Thinking about this more, hash functions make the root of the tree irreversible. Using a polyhash if you know the root of the tree and the R value for each level you can calculate all the leaves of the tree (theoretically). e.g. A tree with root `T` and leaves `L[0..3]` ``` T H0 H1 L0 L1 L2 L3 ``` In $\mathbb{F}_{999,999,000,001}$ We have a _tree_ with $d = depth$ = 2 $a = arity$ = 2 This tree is composed of sets $R$ and $L$. A set of _randoms_ $R = \{ r_0, r_1 \}=\{ 147000143251, 444472719334 \}$ $|R| = d$ A set of _leaves_. $L = \{ l_0, l_1, l_2, l_3 \}=\{ 162635460746, 476273552859, 350556862134, 242288957360 \}$ $|L| = a^d$ From this we can recursively calculate a single value $τ$ that can uniquely represent $\{ L, R \}$ $h_0 = l_0r_0 + l_1r_0^2$ $h_1 = l_2r_0 + l_3r_0^2$ $h_2 = τ = h_0r_1 + h_1r_1^2$ $H$ is the set of values needed to calculate the _root_, $τ$ Given $τ = 547704698159$ we can define $L$ as a combination of $τ$ and $R$. $τ = (l_0r_0 + l_1r_0^2) \times r_1 + (l_2r_0 + l_3r_0^2) \times r_1^2$ $τ = l_0r_0r_1 + l_1r_0^2r_1 + l_2r_0r_1^2 + l_3r_0^2r_1^2$ This is a single degree multivariate polynomial $547704698159 = l_0 \times 812929696084 + l_1 \times 121670827806 + l_2 \times 890295454086 + l_3 \times 915378583427$ If we can solve this equation we can calculate the _leaves_ using only the _root_ and _randoms_. e.g. if we can solve a multivariate polynomial with 1024 variables we could decompress 64 MB from 384 bytes (this problem is NP-complete `:(`) #### Code used to calculate examples above ```js const BN = require('bn.js') const F = new BN(999999000001) const _2 = new BN(2) const r = [147000143251, 444472719334].map(v => new BN(v)) const l = [162635460746,476273552859,350556862134,242288957360].map(v => new BN(v)) const h0 = l[0].mul(r[0]).mod(F).add(l[0].mul(r[0].pow(_2)).mod(F)) const h1 = l[2].mul(r[0]).mod(F).add(l[3].mul(r[0].pow(_2)).mod(F)) const t = h0.mul(r[1]).mod(F).add(h1.mul(r[1].pow(_2)).mod(F)) console.log('-----') console.log(`R`) r.map((_) => console.log(_.toString())) console.log('-----') console.log(`L`) l.map((_) => console.log(_.toString())) console.log('-----') console.log(`H`) console.log(h0.toString()) console.log(h1.toString()) console.log(t.toString()) console.log('-----') console.log(`root is ${t.toString()}`) //~~ calculate R[0], R[0]^2, R[0]^3 console.log(r[0]) console.log(r[0].pow(_2).mod(F).toString()) console.log(r[0].pow(new BN(3)).mod(F).toString()) ```