jfs.shThe rambling and tinkering of a climbing cryptographer.2022-04-18T00:00:00+00:00https://jfs.sh/blog/feed.xmlMosaics and Geometric Patterns2022-04-18T00:00:00+00:002022-04-18T00:00:00+00:00https://jfs.sh/blog/mosaics-and-geometric-patterns/<p>A <a rel="nofollow noreferrer" href="https://remalue.github.io/">friend</a>'s late obsession on ornaments, mosaics, & patterns led me to toying around with them in <a rel="nofollow noreferrer" href="https://ipe.otfried.org/">ipe</a> on a lazy day.
Here's some nice looking pictures.
Thanks to <a rel="nofollow noreferrer" href="https://ambigraph.com/">ambigraph</a> for the inspiration!</p>
<h1 id="mosaics">Mosaics</h1>
<p><img src="/blog/2022-04-18_four_star.svg" alt="" /></p>
<p><img src="/blog/2022-04-18_five_star.svg" alt="" /></p>
<p><img src="/blog/2022-04-18_six_star_5.svg" alt="" /></p>
<h1 id="ipe-files">Ipe Files</h1>
<ul>
<li><a href="/blog/2022-04-18_four_star.ipe">Mosaic with four points</a></li>
<li><a href="/blog/2022-04-18_five_star.ipe">Mosaic with five points</a></li>
<li><a href="/blog/2022-04-18_six_star.ipe">Mosaic with six points</a></li>
</ul>
Gröbner Basis-Attacking a Tiny Sponge2021-06-28T00:00:00+00:002021-06-28T00:00:00+00:00https://jfs.sh/blog/gb-attacking-tiny-sponge/<table><thead><tr><th align="left">🛈</th></tr></thead><tbody>
<tr><td align="left">I originally wrote this post when working at <a rel="nofollow noreferrer" href="https://asdm.gmbh">AS Discrete Mathematics</a> as part of a project sponsored by the <a rel="nofollow noreferrer" href="https://ethereum.foundation/">Ethereum Foundation</a>. It is reproduced here with friendly permission.</td></tr>
</tbody></table>
<p>When estimating the security of a cipher or hash function, there are many different attack scenarios to consider.
For Arithmetization Oriented Ciphers (AOCs), Gröbner basis attacks are a lot more threatening than they are to “traditional” ciphers, like the AES.
The most common way to argue resistance against Gröbner basis attacks is to look at the expected complexity of Gröbner basis algorithms.</p>
<p>However, the complexity estimates only apply asymptotically, and the Big O notation might hide factors that are significant for parameter sizes a cipher designer is interested in.
Thus, to validate whether the theoretical complexity estimates carry significance, we need “real” data to compare it to.
This means running experiments – and that's exactly what this post is about.
Concretely, we have performed several Gröbner basis attacks, and will be discussing and interpreting the resulting data here.</p>
<h2 id="disclaimer">Disclaimer</h2>
<p>Take below results with a grain of salt – the data might be wrong.
As far as I know, no one has reproduced it yet.
<label for="mn-efn_note" class="margin-toggle">🛈</label><input type="checkbox" id="mn-efn_note" class="margin-toggle"/>
<span class="marginnote">
If you have run your own, comparable experiments, please <a href="mailto:gb_attack@jfs.sh">let me know</a>!
</span>
Please draw any conclusions carefully.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>We assume a certain familiarity with the ciphers Rescue-Prime <a href="https://jfs.sh/blog/gb-attacking-tiny-sponge/#references">[4]</a> and Poseidon <a href="https://jfs.sh/blog/gb-attacking-tiny-sponge/#references">[3]</a>, as well as the <a rel="nofollow noreferrer" href="https://en.wikipedia.org/wiki/Sponge_function">Sponge construction</a>.
As a quick reminder for these three things, there are graphical depictions at the end of this post and in the next section, respectively.</p>
<p>Since this post is all about Gröbner basis attacks, a certain familiarity on this topic does not hurt, albeit it shouldn't be strictly necessary.
In case you want to brush up on a detail or two, have a look <a rel="nofollow noreferrer" href="https://ia.cr/2021/870">here</a>.</p>
<h1 id="description-of-experiments">Description of Experiments</h1>
<p>AOCs like Rescue-Prime and Poseidon are designed to have a “small” algebraic description.
That is, when polynomially modeling their structure, we don't need too many polynomials, and those are not of very high degree.</p>
<p>A use case where an AOC's simple algebraic description causes major speedups involves hashes in zero-knowledge proof systems.
The most popular way to transform a permutation, like Rescue-Prime or Poseidon, into a hash function is the Sponge construction.
On a high level, a Sponge looks like this:</p>
<figure>
<img src="/blog/2021-06-28_sponge.png" >
<figcaption>Stylized depiction of the Sponge construction.</figcaption>
</figure>
<p>Any cryptographic hash function needs to be secure against inversion, i.e., computing a pre-image for a given hash digest must be so difficult as to be infeasible.
For the Sponge construction, this largely depends on the plugged-in permutation.
For our experiments, we perform a second pre-image Gröbner basis attack on a Sponge construction with exactly one application of the permutation.
Furthermore, we set rate = capacity = 1, which is the lowest meaningful value for either parameter.
This way, we get the smallest Sponge one can build.
Consequently, if <em>this</em> attack is infeasible, then Gröbner basis attacking a realistically sized Sponge definitely is.</p>
<figure>
<img src="/blog/2021-06-28_last_squeeze.png" >
<figcaption>A super-tiny Sponge. Barely deserves the name.</figcaption>
</figure>
<p>As the permutation, we use the two primitives Rescue-Prime and Poseidon with varying numbers of rounds.
The prime field has size p = 65519, which is the largest 16-bit prime for which gcd(p-1, 3) = 1, meaning we can use exponent 3 in the S-Boxes.
<label for="mn-largest_prime" class="margin-toggle">🛈</label><input type="checkbox" id="mn-largest_prime" class="margin-toggle"/>
<span class="marginnote">
For the largest 16-bit prime, i.e., 65521, we'd have to use exponent 11.
</span>
The limitation to 16-bit primes comes from the used Gröbner basis computation implementation, namely <a rel="nofollow noreferrer" href="https://www-polsys.lip6.fr/%7Ejcf/FGb/">FGb</a> <a href="https://jfs.sh/blog/gb-attacking-tiny-sponge/#references">[2]</a>.</p>
<h2 id="technical-specifications">Technical Specifications</h2>
<p>All the experiments were performed using <a rel="nofollow noreferrer" href="https://cocalc.com/">cocalc</a> on an “n2-highmem-32 Cascade Lake Google Compute Engine” and 264141536 KiB (~252 GiB) of total RAM as reported by <code>free</code>.
The operating system in use was (Ubuntu) Linux 5.4.0-1042-gcp x86_64 as reported by <code>uname -srm</code></p>
<h2 id="reproducibility">Reproducibility</h2>
<p>The code for the experiments can be found on <a rel="nofollow noreferrer" href="https://github.com/ASDiscreteMathematics/gb_benchmarks">github</a>.
Its dependencies are <a rel="nofollow noreferrer" href="https://www.sagemath.org/">sagemath</a>, <a rel="nofollow noreferrer" href="https://github.com/mwageringel/fgb_sage">fgb_sage</a>, and <a rel="nofollow noreferrer" href="https://www-polsys.lip6.fr/%7Ejcf/FGb/">FGb</a> <a href="https://jfs.sh/blog/gb-attacking-tiny-sponge/#references">[2]</a>.
If you have the abilities and capacity to re-run the code to strengthen or refute the claims made here, I encourage you to do so.</p>
<h1 id="summary-of-results">Summary of Results</h1>
<p>Before looking at the data in a little more detail, here's a quick summary of some of my findings.</p>
<ul>
<li>We managed to compute a Gröbner basis for 6 rounds of Rescue-Prime, but failed at 7 rounds.</li>
<li>Poseidon has a two types of rounds, which makes arguing about round limits a little more cumbersome.
With the exception of one outlier, we could not break any partition totaling 11 rounds – see the matrix below.</li>
<li>Memory, not time, seems to be the most limiting factor.</li>
<li>The polynomial system for Poseidon appears to be <em>ir</em>regular, in contrast to the authors' implicit assumption.
This directly affects the number of recommended rounds.
For example, while Poseidon's authors recommend (8,9) rounds for p = 65519 and 2 elements in the state, extrapolating the data here suggests that (8,24) rounds might be necessary.</li>
<li>The interpolation for the degree of regularity for Rescue-Prime is different from the interpolation published with Rescue, but similar in principle. This difference might be explained by the use of Rescue-<em>Prime</em> as the permutation. Sadly, it neither validates nor refutes the authors' claims.</li>
</ul>
<h1 id="results-in-detail">Results in Detail</h1>
<p>Experiments like the ones described above generate quite a bunch of data.
We're not gonna look at <em>everything</em> here, I just want to highlight some parts.
If you want to start digging deeper, you can find the raw data at <a href="https://jfs.sh/blog/gb-attacking-tiny-sponge/#appendix-data">the end of this post</a>.</p>
<p>The metric commonly used to estimate the complexity of a Gröbner basis computation is largely depending on the <a href="https://jfs.sh/blog/hilbert-reg/">degree of regularity</a>.
<label for="mn-dreg" class="margin-toggle">🛈</label><input type="checkbox" id="mn-dreg" class="margin-toggle"/>
<span class="marginnote">
In this post, I will be using ”degree of regularity“ and “maximum degree reached by F<sub>4</sub> during its execution” interchangeably.
Indeed, it is an open question whether this is always true.
</span>
This is <a href="https://jfs.sh/blog/dreg-insufficient-for-security/">not based on a totally rigorous argument</a>, but it seems to be “good enough” in practice.
Consequently, quite a bit of the following will be about the degree of regularity and the Macaulay bound.
<label for="mn-sok_gb" class="margin-toggle">🛈</label><input type="checkbox" id="mn-sok_gb" class="margin-toggle"/>
<span class="marginnote">
If you want to jog your memory on either of these concepts, I suggest taking a glance at <a rel="nofollow noreferrer" href="https://ia.cr/2021/870">this document</a>.
</span>
The Macaulay bound is an upper bound for the degree of regularity, and their values coincide if a polynomial system is a <a rel="nofollow noreferrer" href="https://en.wikipedia.org/wiki/Regular_sequence">regular sequence</a>.</p>
<p>In general, the successful attacks that took the longest time for the two primitives were 6-round Rescue-Prime, and (full=2, partial=9)-round Poseidon.
They took around 34 and 73 hours, requiring roughly 75 and 228 GiB of memory, respectively.</p>
<h2 id="rescue-prime">Rescue-Prime</h2>
<p>We successfully computed a Gröbner basis for 6-round Rescue-Prime, but ran out of memory during the computation for 7-round Rescue-Prime.</p>
<h3 id="degree-of-regularity">Degree of Regularity</h3>
<p>The most important metric to consider is the growth of the degree of regularity as a function in the number of rounds.
As we can see, the degree of regularity is pretty consistently 2 less than the Macaulay bound of the polynomials system for Rescue-Prime.
The only exception happens at r = 2 rounds, an anomaly I don't believe deserves a lot of attention.</p>
<figure>
<img src="/blog/2021-06-28_rescue_prime_dreg_develop.png" >
<figcaption>Various metrics of the polynomial system for Rescue-Prime as a function in the number of rounds.</figcaption>
</figure>
<p>Interestingly, the degree of the highest degree polynomial in the resulting reduced Gröbner basis – abbreviated as the degree of the Gröbner basis – is even lower than that.
More importantly though, its growth seems to be only piecewise linear:
between 1 and 4 rounds, the degree of the Gröbner basis grows by 3 with each iteration, where from round 4 on, the difference is 4.</p>
<p>The limited number of data points makes drawing conclusions difficult.
However, it's not unreasonable to argue that extrapolating the degree of the Gröbner basis linearly might lead to inaccuracies.
Similarly, it is still an open question whether extrapolating the degree of regularity is a good method to estimate the complexity of computing the Gröbner basis for the full-round primitive.</p>
<p>The observed growth of the degree of regularity in Rescue-Prime is different from what is reported in the publication of “plain” Rescue.
Concretely, I observe
<script type="math/tex">d_\text{reg} \approx 4r-1</script>
for Rescue-Prime, whereas Rescue's authors report
<script type="math/tex">d_\text{reg} = 2r+2</script>
for Rescue <a href="https://jfs.sh/blog/gb-attacking-tiny-sponge/#references">[1, Section 6.1]</a>.
Here is their figure for comparison:</p>
<figure>
<img src="/blog/2021-06-28_rescue_dreg_develop_original_paper.png" >
<figcaption>Some of the same metrics as above for the polynomial system for Rescue as a function in the number of rounds, as given by the authors. [1]</figcaption>
</figure>
<p>Extending this interpolation of the degree of regularity to an extrapolation can be used to estimate the required number of rounds to achieve a given security level.
For this, we use the known complexity bound for the most performant Gröbner basis algorithm, which is
<script type="math/tex">\binom{n + d_\text{reg}}{n}^\omega</script>
.
Here, <em>n</em> is the number of variables in the polynomial ring,
<script type="math/tex">d_\text{reg}</script>
is the degree of regularity, and <em>ω</em> is the linear algebra constant.
A conservative choice for <em>ω</em> is 2.
<label for="mn-lin-alg-constant" class="margin-toggle">🛈</label><input type="checkbox" id="mn-lin-alg-constant" class="margin-toggle"/>
<span class="marginnote">
I know of no Gröbner basis algorithm making use of sparse linear algebra techniques, which would imply <em>ω</em> = 2.
However, it is plausible that they do or can exist.
</span>
For the used parameters of Rescue-Prime, the number of variables, which is equal to the number of equations, is 2r.
The degree of regularity is estimated to be 4r - 1.
Putting it all together, we have
<script type="math/tex">\binom{6r - 1}{2r}^2 > 2^{128}</script>
for r ≥ 13.
For the same parameters, the authors of Rescue-Prime recommend r = 27 <a href="https://jfs.sh/blog/gb-attacking-tiny-sponge/#references">[4, Algorithm 7]</a>.
This recommendation also includes a security margin, and considers more attack vectors than just a Gröbner basis attack.</p>
<h3 id="f4-s-working-degree">F<sub>4</sub>'s Working Degree</h3>
<p>For Rescue-Prime, the working degree of F<sub>4</sub> increases strictly monotonously:
every iteration of F<sub>4</sub>'s main loop means working with polynomials of degree exactly 1 higher than in the preceding iteration.
That makes for a pretty dull figure:</p>
<figure>
<img src="/blog/2021-06-28_rescue_prime_f4_degs.png" >
<figcaption>For Rescue-Prime, F<sub>4</sub>'s working degree increases by 1 per iteration, independent of the number of rounds.</figcaption>
</figure>
<h2 id="poseidon">Poseidon</h2>
<p>Since Poseidon has two types of rounds, namely full rounds and partial rounds, we have conducted a lot more experiments for Poseidon than for Rescue.
The following matrix summarizes which ones we ran, and whether the Gröbner basis could be computed successfully.
The value of a cell indicates how many polynomials the polynomial system had.
This is equal to the number of variables in the polynomial ring for this problem instance.
The number of full rounds differ across columns, the number of partial rounds across rows.</p>
<table cellspacing="0" border="0">
<colgroup span="7" width="1"></colgroup>
<tr>
<td></td>
<td align="right">2</td>
<td align="right">4</td>
<td align="right">6</td>
<td align="right">8</td>
<td align="right">10</td>
<td align="right">12</td>
</tr>
<tr>
<td align="right">0</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">3</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">7</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">11</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">15</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">19</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">23</td>
</tr>
<tr>
<td align="right">1</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">4</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">8</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">12</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">16</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">20</td>
<td></td>
</tr>
<tr>
<td align="right">2</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">5</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">9</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">13</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">17</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">21</td>
<td></td>
</tr>
<tr>
<td align="right">3</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">6</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">10</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">14</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">18</td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">4</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">7</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">11</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">15</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">19</td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">5</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">8</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">12</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">16</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">6</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">9</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">13</td>
<td align="right" bgcolor="#E6E905" style="color: #444;">17</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">7</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">10</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">14</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">8</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">11</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">15</td>
<td></td>
<td colspan=3 align="center" bgcolor="#5EB91E" style="color: #444">GB computed</td>
</tr>
<tr>
<td align="right">9</td>
<td align="right" bgcolor="#5EB91E" style="color: #444;">12</td>
<td align="right" bgcolor="#E6E905" style="color: #444;">16</td>
<td></td>
<td colspan=3 align="center" bgcolor="#F10D0C" style="color: #444">out of memory</td>
</tr>
<tr>
<td width="24" align="right">10</td>
<td align="right" bgcolor="#F10D0C" style="color: #444;">13</td>
<td></td>
<td></td>
<td colspan=3 align="center" bgcolor="#E6E905" style="color: #444">manually aborted</td>
</tr>
</table>
<p>A total of 11 rounds seems to the barrier we couldn't break with the available machine, the (2,9)-instance being a notable exception.
Note that the number of equations seems to not be the cutoff point – for (2,10)-Poseidon, we have 13 equations and variables but cannot compute the Gröbner basis, whereas for (10,0)-Poseidon with its 19 equations, we can compute the Gröbner basis.
For some of the figures below, we look at the series for
<script type="math/tex">r_\text{full} = 4</script>
full rounds in more detail to simplify presentation.</p>
<h3 id="degree-of-regularity-1">Degree of Regularity</h3>
<p>As before, the degree of regularity is the metric we're interested in the most.
For example, for Poseidon (4,٭), i.e., 4 full rounds and a varying number of partial rounds, we get the following figure when plotting both the Macaulay bound and the system's degree of regularity.</p>
<figure>
<img src="/blog/2021-06-28_poseidon_f4_dreg_develop.png" >
<figcaption>Degree of regularity and Macaulay bound of the polynomial system for (4,٭)-round Poseidon as a function in the number of partial rounds.</figcaption>
</figure>
<p>It appears the degree of regularity is growing slower than the Macaulay bound.
For a more complete picture, the degrees of regularity for all successfully computed Gröbner bases are listed in the following table.
A grayed-out value means that the Gröbner basis computation did not terminate, but reached the indicated degree at its maximum before running out of memory or being aborted manually.</p>
<table cellspacing="0" border="0">
<colgroup span="7" width="85"></colgroup>
<tr>
<td></td>
<td align="right">2</td>
<td align="right">4</td>
<td align="right">6</td>
<td align="right">8</td>
<td align="right">10</td>
<td align="right">12</td>
</tr>
<tr>
<td align="right">0</td>
<td align="right" style="color: #444" bgcolor="#FFB66C">4</td>
<td align="right" style="color: #444" bgcolor="#FFAA95">5</td>
<td align="right" style="color: #444" bgcolor="#EC9BA4">6</td>
<td align="right" style="color: #444" bgcolor="#BF819E">7</td>
<td align="right" style="color: #444" bgcolor="#B7B3CA">8</td>
<td align="right" style="color: #999">8</td>
</tr>
<tr>
<td align="right">1</td>
<td align="right" style="color: #444" bgcolor="#FFAA95">5</td>
<td align="right" style="color: #444" bgcolor="#EC9BA4">6</td>
<td align="right" style="color: #444" bgcolor="#EC9BA4">6</td>
<td align="right" style="color: #444" bgcolor="#BF819E">7</td>
<td align="right" style="color: #999">8</td>
<td></td>
</tr>
<tr>
<td align="right">2</td>
<td align="right" style="color: #444" bgcolor="#FFAA95">5</td>
<td align="right" style="color: #444" bgcolor="#EC9BA4">6</td>
<td align="right" style="color: #444" bgcolor="#BF819E">7</td>
<td align="right" style="color: #444" bgcolor="#B7B3CA">8</td>
<td align="right" style="color: #999">8</td>
<td></td>
</tr>
<tr>
<td align="right">3</td>
<td align="right" style="color: #444" bgcolor="#EC9BA4">6</td>
<td align="right" style="color: #444" bgcolor="#BF819E">7</td>
<td align="right" style="color: #444" bgcolor="#B7B3CA">8</td>
<td align="right" style="color: #999">9</td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">4</td>
<td align="right" style="color: #444" bgcolor="#BF819E">7</td>
<td align="right" style="color: #444" bgcolor="#B7B3CA">8</td>
<td align="right" style="color: #444" bgcolor="#B4C7DC">9</td>
<td align="right" style="color: #999">9</td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">5</td>
<td align="right" style="color: #444" bgcolor="#B7B3CA">8</td>
<td align="right" style="color: #444" bgcolor="#B4C7DC">9</td>
<td align="right" style="color: #999">9</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">6</td>
<td align="right" style="color: #444" bgcolor="#B4C7DC">9</td>
<td align="right" style="color: #444" bgcolor="#B3CAC7">10</td>
<td align="right" style="color: #999">10</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">7</td>
<td align="right" style="color: #444" bgcolor="#B3CAC7">10</td>
<td align="right" style="color: #999">11</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">8</td>
<td align="right" style="color: #444" bgcolor="#AFD095">11</td>
<td align="right" style="color: #999">12</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">9</td>
<td align="right" style="color: #444" bgcolor="#E8F2A1">12</td>
<td align="right" style="color: #999">13</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td align="right">10</td>
<td align="right" style="color: #999">13</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<p>We can compute the Macaulay bound for the polynomial system arising from
<script type="math/tex">(r_\text{full}, r_\text{partial})</script>
-Poseidon
as
<script type="math/tex">4r_\text{full} + 2r_\text{part} - 1</script>
.
A closely fitting linear approximation for the degree of regularity based on above data is
<script type="math/tex">d_\text{reg} \approx \frac{r_\text{full}}{2} + r_\text{part} + 2</script>
.
The (limited) data suggests that the degree of regularity depends on a full round a lot less than the Macaulay bound makes it seem.
Overall, the degree of regularity does not stay very close to the Macaulay bound.</p>
<p>Based on the <a rel="nofollow noreferrer" href="https://extgit.iaik.tugraz.at/krypto/hadesmimc/-/blob/master/code/calc_round_numbers.py">script</a> supplied by the authors of Poseidon, the recommended number of rounds for 128 bits of security when using a state size of 2 is (8, 9).
Using the number of full rounds as a given, and plugging the interpolated degree of regularity, i.e., r + 6, and the required number of variables, i.e., r + 15, into the complexity bound for the most performant Gröbner basis algorithm leads us to the conclusion that r ≥ 24 partial rounds are necessary to achieve 128 bits of security against Gröbner basis attacks, i.e.,
<script type="math/tex">\binom{2r+21}{r+15}^2 > 2^{128}</script>
for r ≥ 24.
This discrepancy is the direct consequence of the observed degree of regularity not equaling the Macaulay bound – plugging the Macaulay bound into the same formula results in r ≥ 10.</p>
<h3 id="f4-s-working-degree-1">F<sub>4</sub>'s Working Degree</h3>
<p>The working degree of F<sub>4</sub> is quite “bouncy” for the polynomial systems derived from Poseidon.
For example, for
<script type="math/tex">r_\text{full} = 4</script>
with varying number of partial rounds, we can plot the working degree of F<sub>4</sub> against the iteration that degree occurred in.
While the overall tendency is “up,” there are many iterations for which the working degree does not change, or even drops.
I am unsure what exactly this means in terms of security, or if it means anything at all.</p>
<figure>
<img src="/blog/2021-06-28_poseidon_4_f4_degs.png" >
<figcaption>For Poseidon, F<sub>4</sub>'s working degree develops… interestingly.</figcaption>
</figure>
<h1 id="comparison">Comparison: Rescue-Prime vs Poseidon</h1>
<p>One of the most notable differences between the polynomial systems for Rescue-Prime and Poseidon is the growth rate of their respective degrees of regularity.
For example, consider the following plot, where I have repeated the data for Rescue-Prime from above and added the Macaulay bound and degree of regularity for (٭,0)-Poseidon, i.e., varying the number of full rounds.</p>
<figure>
<img src="/blog/2021-06-28_mac-bound_f4-deg_comparison.png" >
<figcaption>
For Rescue-Prime, the degree of regularity closely matches the Macaulay bound.
For Poseidon, the Macaulay bound vastly overestimates the actual degree of regularity.
</figcaption>
</figure>
<p>While the Macaulay bounds are almost identical, the observed degrees of regularity differ greatly.</p>
<p>It's also nice to see the development of the used memory for a few instances, even though that comparison is not very important.
Below figure shows the required memory over time for 5, 6, and 7-round Rescue-Prime and (4,5), (4,6), (4,7)-round Poseidon.
Recall that 7-round Rescue-Prime and (4,7)-round Poseidon both ran out of memory, i.e., terminated abnormally.</p>
<figure>
<img src="/blog/2021-06-28_memory_vs_time.png" >
<figcaption>Not significant but interesting: memory consumption over time for various polynomial systems.</figcaption>
</figure>
<p>By the jumps in memory consumption you can pretty clearly see where a new, bigger matrix was constructed.
This corresponds to the iterations of F<sub>4</sub>.
Exponential – or binomial – growth being what it is, it does not make sense to plot instances with less rounds.
Already, 5-round Rescue-Prime and (4,5)-round Poseidon are barely visible in the lower-left corner of the figure.
The dotted line corresponds to the total available memory.</p>
<h1 id="conclusion">Conclusion</h1>
<p>The data suggests that the implicit assumption about the regularity of the polynomial system arising from Poseidon is wrong:
the difference between the Macaulay bound and the observed degree of regularity implies that the system is irregular.
This has direct consequences for the minimum number of rounds required to achieve a target security level.
For example, for p = 65519 and state size 2, we recommend (8,24) rounds as opposed to (8,9) rounds.</p>
<p>An interesting open question is how to interpret the “bounciness” of F<sub>4</sub>'s working degree when computing a Gröbner basis for a Poseidon-derived system.
The significance of this behavior is completely unclear.</p>
<p>Another open question regards the discrepancy in the observed growth of the degree of regularity for Rescue and Rescue-Prime.
Regardless, the data supports the security argument of Rescue-Prime:
adding one half round at either end, i.e., transforming “plain” Rescue into Rescue-Prime, does not seem to decrease security.</p>
<p>All things told, no successful Gröbner basis attack could be performed for anything approaching realistic round numbers – even for this tiny Sponge construction.</p>
<h1 id="references">References</h1>
<ol>
<li>Aly, A., Ashur, T., Ben-Sasson, E., Dhooghe, S., Szepieniec, A.:
<em>Design of Symmetric Primitives for Advanced Cryptographic Protocols</em>.
IACR ToSC 2020(3), 1–45 (2020)</li>
<li>J.-C. Faugère:
<em>FGb: A Library for Computing Gröbner Bases</em>.
In Komei Fukuda, Joris Hoeven, Michael Joswig, and Nobuki Takayama, editors, Mathematical Software ICMS 2010, volume 6327 of Lecture Notes in Computer Science, pages 84-87, Berlin, Heidelberg, September 2010.
Springer Berlin / Heidelberg.</li>
<li>Grassi, L., Khovratovich, D., Rechberger, C., Roy, A., Schofnegger, M.:
<em>Poseidon: A New Hash Function for Zero-Knowledge Proof Systems</em>.
In: USENIX Security. USENIX Association (2020)</li>
<li>Szepieniec, A., Ashur, T., Dhooghe, S.:
<em>Rescue-Prime: a Standard Specification (SoK)</em>.
Cryptology ePrint Archive, Report 2020/1143 (2020)</li>
</ol>
<h1 id="appendix-summary">Appendix – Summary of the Hash Functions</h1>
<p>Below, I have put some figures summarizing the AOCs Rescue-Prime and Poseidon, respectively.
The input, output, and constants are all vectors of the same length.
They are contracted here to simplify presentation.</p>
<figure>
<img src="/blog/2021-06-28_rescue_prime.png" >
<figcaption>2-round Rescue-Prime. Note that a single round, made up of two half rounds, first uses exponent 3 and then ⅓.</figcaption>
</figure>
<figure>
<img src="/blog/2021-06-28_poseidon.png" >
<figcaption>(2,1)-round Poseidon, i.e., the instance has 2 full rounds – 1 at the beginning, 1 at the end – and 1 partial round.</figcaption>
</figure>
<h1 id="appendix-data">Appendix – Raw Data</h1>
<p><a href="2021-06-28_last_squeeze_attack_data.zip">Here's the data</a> this post is based on!
Each experiment, say, (4,3)-Poseidon, comes with 4 files:
<label for="mn-spaces" class="margin-toggle">🛈</label><input type="checkbox" id="mn-spaces" class="margin-toggle"/>
<span class="marginnote">
Yes, there are spaces in the filename. 🤦 Sorry.
</span>
</p>
<dl>
<dt><strong><code>poseidon_65519_(4, 3)_fgb_debug.txt</code></strong></dt>
<dd>debug information of FGb, described on page 12 in <a href="https://www-polsys.lip6.fr/~jcf/FGb/C/Cdoc.pdf">this document</a>.</dd>
<br>
<dt><strong><code>poseidon_65519_(4, 3)_mem.txt</code></strong></dt>
<dd>memory requirements over time, in KiB, one row per second.</dd>
<br>
<dt><strong><code>poseidon_65519_(4, 3)_summary.txt</code></strong></dt>
<dd>includes time & memory measurements, degrees, data from FGb.</dd>
<br>
<dt><strong><code>poseidon_65519_(4, 3)_sys.txt</code></strong></dt>
<dd>the polynomial system for which the Gröbner basis was computed.</dd>
</dl>
Understanding and Computing the Hilbert Regularity2021-06-08T00:00:00+00:002021-06-08T00:00:00+00:00https://jfs.sh/blog/hilbert-reg/<table><thead><tr><th align="left">🛈</th></tr></thead><tbody>
<tr><td align="left">I originally wrote this post when working at <a rel="nofollow noreferrer" href="https://asdm.gmbh">AS Discrete Mathematics</a> as part of a project sponsored by the <a rel="nofollow noreferrer" href="https://ethereum.foundation/">Ethereum Foundation</a>. It is reproduced here with friendly permission.</td></tr>
</tbody></table>
<p>When attacking <a rel="nofollow noreferrer" href="https://asdm.gmbh/arithmetization-oriented-ciphers/aoc-project/">AOCs</a> using Gröbner bases, the most relevant question is:
how complex is the Gröbner basis computation?
One commonly used estimation is based on the <em>degree of regularity</em>.
Intuitively, the degree of regularity is the degree of the highest-degree polynomials to appear during the Gröbner basis computation.
(<a href="https://jfs.sh/blog/dreg-insufficient-for-security/">Whether this metric is good for estimating the AOC's security is a different matter</a>.)</p>
<p>Unfortunately, different authors define the term “degree of regularity” differently.
In this post, I use the understanding of Bardet et al. [1,2], which coincides with the well-defined <em>Hilbert regularity</em>.</p>
<p>I first introduce the required concepts, and then make them more tangible with some examples.
Lastly, there is some <a rel="nofollow noreferrer" href="https://www.sagemath.org/">sagemath</a> code with which the Hilbert regularity can be computed.</p>
<h1 id="definition-of-the-hilbert-regularity">Definition of the Hilbert Regularity</h1>
<p>Let <script type="math/tex">\mathbb{F}</script>
be some field,
<script type="math/tex">R = \mathbb{F}[x_0, \dots, x_{n-1}]</script>
a polynomial ring in <script type="math/tex">n</script>
variables over
<script type="math/tex">\mathbb{F}</script>
,
and
<script type="math/tex">I \subseteq R</script>
a polynomial ideal of <script type="math/tex">R</script>
.</p>
<p>The affine Hilbert function of quotient ring <script type="math/tex">R/I</script>
is defined as
<script type="math/tex;mode=display">{}^a\textsf{HF}_{R/I}(s) = \dim_\mathbb{F}\!\left(R_{\leqslant s} \middle/ I_{\leqslant s}\right).</script>
For some large enough value <script type="math/tex">s_0</script>
, the Hilbert function of all <script type="math/tex">s \geqslant s_0</script>
can be expressed as a polynomial in <script type="math/tex">s</script>
.
<label for="mn-background" class="margin-toggle">🛈</label><input type="checkbox" id="mn-background" class="margin-toggle"/>
<span class="marginnote">
For a general treatment of the <em>how?</em> and <em>why?</em>, have a look at the excellent book “Ideals, Varieties, and Algorithms,” [3] in particular Chapter 9, §2, Theorem 6, and Chapter 9, §3.
The examples in this post hopefully shed some light, too.
</span>
This polynomial, denoted <script type="math/tex">{}^a\textsf{HP}_{R/I}(s)</script>
, is called <em>Hilbert polynomial</em>.
By definition, the values of the Hilbert function and the Hilbert polynomial coincide for values greater than <script type="math/tex">s_0</script>
.</p>
<p>The <strong>Hilbert regularity</strong> is the smallest <script type="math/tex">s_0</script>
such that for all <script type="math/tex">s \geqslant s_0</script>
, the evaluation of the Hilbert function in <script type="math/tex">s</script>
equals the evaluation of the Hilbert polynomial in <script type="math/tex">s.</script>
</p>
<p>By the <a rel="nofollow noreferrer" href="https://en.wikipedia.org/wiki/Rank%E2%80%93nullity_theorem">rank-nullity theorem</a>, we can equivalently write the Hilbert function as
<script type="math/tex;mode=display">{}^a\textsf{HF}_{R/I}(s) = \dim_\mathbb{F}\! \left( R_{\leqslant s} \right) - \dim_\mathbb{F}\! \left( I_{\leqslant s}\right).</script>
This is a little bit easier to handle, because we can look at <script type="math/tex">R</script>
and <script type="math/tex">I</script>
separately and can ignore the quotient ring <script type="math/tex">R/I</script>
for the moment.
By augmenting <script type="math/tex">R</script>
with a graded monomial order, like <a rel="nofollow noreferrer" href="https://en.wikipedia.org/wiki/Monomial_order#Graded_reverse_lexicographic_order">degrevlex</a>, we can go one step further and look at leading monomials <script type="math/tex">\textsf{lm}</script>
only:
the set
<script type="math/tex">\{ \textsf{lm}(f) \mid f \in I, \deg(f) \leqslant s \}</script>
is a basis for
<script type="math/tex">I_{\leqslant s}</script>
as an <script type="math/tex">\mathbb{F}</script>
-vector space.
<label for="mn-f_v_space" class="margin-toggle">🛈</label><input type="checkbox" id="mn-f_v_space" class="margin-toggle"/>
<span class="marginnote">
See [3, Chapter 9, §3, Proposition 4] for a full proof.
</span>
Meaning we don't even need to look at <script type="math/tex">I</script>
, but can restrict ourselves to the ideal of leading monomials <script type="math/tex">\langle \textsf{lm}(I) \rangle</script>
.
<script type="math/tex;mode=display">{}^a\textsf{HF}_{R/I}(s) = \dim_\mathbb{F}\!\left(R_{\leqslant s}\right) - \dim_\mathbb{F}\!\left( \langle \textsf{lm}(I) \rangle_{\leqslant s}\right).</script>
</p>
<p>One way to get a good grip on <script type="math/tex">\langle I \rangle</script>
is through reduced Gröbner bases.
A Gröbner basis <script type="math/tex">G</script>
for ideal <script type="math/tex">I</script>
is a finite set of polynomials with the property
<script type="math/tex">\langle G \rangle = \langle I \rangle</script>
and, more relevant right now,
<script type="math/tex">\langle \textsf{lm}(G) \rangle = \langle \textsf{lm}(I) \rangle.</script>
This means it's sufficient to look at (the right combinations) of elements of <script type="math/tex">\textsf{lm}(G).</script>
This, in turn, is more manageable because <script type="math/tex">G</script>
always has finitely many elements, but <script type="math/tex">I</script>
might not.</p>
<h2 id="example-0-dimensional-ideal">Example: 0-Dimensional Ideal</h2>
<p>Let's start with a super simple polynomial system:
<script type="math/tex;mode=display">G = \{x^6, x^2y^2, y^5\} \subseteq \mathbb{F}[x,y], \quad I = \langle G \rangle</script>
for some finite field
<script type="math/tex">\mathbb{F}.</script>
This is a zero-dimensional, monomial (thus homogeneous) ideal.
That's about as special as a special case can get.
Note that here, we have
<script type="math/tex">I = \langle \textsf{lm}(I) \rangle</script>
, but this doesn't generally hold.
Dealing with a super-special case also means that the Hilbert polynomial is relatively boring, but that's fine for starting out.
<script type="math/tex">G</script>
is the reduced Gröbner basis for <script type="math/tex">I</script>
, and we'll use its elements to help computing the Hilbert function.</p>
<p>A benefit of ideals in two variables is:
we can draw pictures.</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal-1.png" >
<figcaption>The monomials of 𝔽[<em>x</em>,<em>y</em>] seen as 𝔽-vector space.</figcaption>
</figure>
<p>This is what the monomials of <script type="math/tex">\mathbb{F}[x,y]</script>
as an <script type="math/tex">\mathbb{F}</script>
-vector space look like.
Well, at least the part <script type="math/tex">\{x^ay^b \mid a \leqslant 8, b \leqslant 7 \}.</script>
After all, <script type="math/tex">\mathbb{F}[x,y]</script>
as an <script type="math/tex">\mathbb{F}</script>
-vector space has infinite dimension.
I have (arbitrarily) highlighted <script type="math/tex">x^3y^2,</script>
i.e., coordinate (3,2), to give a better understanding of what the picture means.</p>
<p>Since <script type="math/tex">I</script>
is a monomial ideal, we can highlight every element in <script type="math/tex">I</script>
.
The circles of the elements of the Gröbner basis <script type="math/tex">G</script>
are red.
The zig-zig pattern of the boundary between <script type="math/tex">x^ay^b \in I</script>
and <script type="math/tex">x^ay^b \notin I</script>
is inherent, and generalizes to higher dimensions, i.e., more variables.
Because of the zig-zagging, the set of monomials not in <script type="math/tex">\langle \textsf{lm}(I) \rangle</script>
is referred to as <em>staircase</em> of <script type="math/tex">I.</script>
</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal-2.png" >
<figcaption>The <em>staircase</em> of ⟨G⟩.</figcaption>
</figure>
<p>Let's start computing the Hilbert function for <script type="math/tex">R/I.</script>
The <script type="math/tex">\mathbb{F}</script>
-vector space dimensions of <script type="math/tex">R_{\leqslant s}</script>
and <script type="math/tex">I_{\leqslant s}</script>
are simply the number of monomials in <script type="math/tex">R</script>
respectively <script type="math/tex">I</script>
with degree <script type="math/tex">\leqslant s.</script>
Getting those numbers is easy – it amounts to counting dots in the picture!
For example, for <script type="math/tex">s=2,</script>
, we have <script type="math/tex">{}^a\textsf{HF}_{R/I}(2)=5-0=5:</script>
</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal-3.png" >
<figcaption>The Hilbert Function of <em>I</em> at <em>s = 2</em>.</figcaption>
</figure>
<p>No monomial of total degree less than or equal to 2 is in <script type="math/tex">I</script>
, so computing the Hilbert function is a little bit boring here.</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal-5.png" >
<figcaption>The Hilbert Function of <em>I</em> at <em>s = 5</em>.</figcaption>
</figure>
<p>The value of the Hilbert function
<script type="math/tex">{}^a\textsf{HF}_{R/I}(5)</script>
is more interesting:
some monomials of degree <script type="math/tex">\leqslant 5</script>
are indeed elements of <script type="math/tex">I</script>
, and thus <script type="math/tex">\dim I_{\leqslant 5}</script>
is not 0 but 4.
In particular, we have <script type="math/tex">{}^a\textsf{HF}_{R/I}(5)=21 - 4=17.</script>
For <script type="math/tex">s=6,</script>
we have <script type="math/tex">{}^a\textsf{HF}_{R/I}(6)=28-10=18:</script>
</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal-6.png" >
<figcaption>The Hilbert Function of <em>I</em> at <em>s = 6</em>.</figcaption>
</figure>
<p>From this point forward, increasing <script type="math/tex">s</script>
will not change the value of the Hilbert function –
the dimension of <script type="math/tex">I_{\leqslant s}</script>
as an <script type="math/tex">\mathbb{F}</script>
-vector space grows with the same rate as the dimension of <script type="math/tex">R_{\leqslant s}</script>
, since all monomials <em>not</em> in <script type="math/tex">I</script>
are of lesser total degree.
Expressed differently, all monomials above the line are elements of both <script type="math/tex">I</script>
and <script type="math/tex">R</script>
–
the values of the Hilbert function doesn't change by increasing <script type="math/tex">s.</script>
</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal-7.png" >
<figcaption>The Hilbert Function of <em>I</em> at <em>s = 7</em>.</figcaption>
</figure>
<p>From this, two things follow:</p>
<ol>
<li>The Hilbert polynomial of <script type="math/tex">R/I</script>
is the constant 18.
(That's why I said it's relatively boring.
A more interesting case follows.)</li>
<li>The Hilbert regularity of <script type="math/tex">R/I</script>
is 6, since <script type="math/tex">{}^a\textsf{HF}_{R/I}(s) = {}^a\textsf{HP}_{R/I}(s)</script>
for all <script type="math/tex">s \geqslant 6.</script>
</li>
</ol>
<h2 id="example-ideal-of-positive-dimension">Example: Ideal of Positive Dimension</h2>
<p>As hinted at above, whether or not <script type="math/tex">I</script>
is a monomial ideal does not matter for computing the Hilbert function or the Hilbert polynomial, because <script type="math/tex">\textsf{lm}(I)</script>
behaves exactly the same.
What does matter, though, is the dimension of <script type="math/tex">I.</script>
In the previous example, <script type="math/tex">I</script>
was of dimension 0, and the Hilbert polynomial of <script type="math/tex">R/I</script>
was a constant.
That's not a coincidence.</p>
<p>Even though the ideal spanned by the polynomial system modelling an AOC will usually be zero-dimensional, it's interesting to see what happens if it isn't.
Let's take <script type="math/tex">G = \{x^4y^3, x^2y^5\} \subseteq \mathbb{F}[x,y]</script>
and <script type="math/tex">I = \langle G \rangle.</script>
</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_poly-0.png" >
<figcaption>The “staircase” of ⟨G⟩. Some of the stairs' steps are pretty large.</figcaption>
</figure>
<p>As you can see, there are parts of the staircase that extend to infinity.
That's a direct consequence of <script type="math/tex">I</script>
having positive dimension, or, equivalently, variety <script type="math/tex">V(I)</script>
not having finitely many solutions.
In the picture below, I've indicated the staircase's five subspaces of dimension <script type="math/tex">1</script>
by dashed, gray lines.</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_poly-1.png" >
<figcaption>The five subspaces of <em>I</em> with dimension 1.</figcaption>
</figure>
<p>For the Hilbert function, only monomials in <script type="math/tex">I</script>
of degree <script type="math/tex">\leqslant s</script>
are relevant.
For each of the five subspaces, we can express the matching number of elements as a polynomial in <script type="math/tex">s.</script>
</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_poly-2.png" >
<figcaption>The number of monomials in each of the 1-dimensional subspaces as a function of s.</figcaption>
</figure>
<p>The sum of these five polynomials is <script type="math/tex">5s+1,</script>
which corresponds to the total number of monomials in the staircase of <script type="math/tex">I</script>
of degree <script type="math/tex">\leqslant s</script>
that lie in the staircase's 1-dimensional subspaces –
except that some elements are counted more than once.
Since the intersection of two orthogonal 1-dimensional subspaces is of dimension <script type="math/tex">0</script>
, we can simply add a constant correction term.
<label for="mn-higher_dim_correction" class="margin-toggle">🛈</label><input type="checkbox" id="mn-higher_dim_correction" class="margin-toggle"/>
<span class="marginnote">
For ideals with more than two variables, we generally need to add correction terms of higher dimension, corresponding to polynomial summands of degree higher than 0.
</span>
</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_poly-3.png" >
<figcaption>The correction term for monomials counted twice is 6.</figcaption>
</figure>
<p>Adding the correction term of <script type="math/tex">-6</script>
gives <script type="math/tex">5s-5</script>
as a (preliminary) Hilbert polynomial for <script type="math/tex">I.</script>
We're not completely done yet:
for <script type="math/tex">s > 4</script>
, there are monomials not in <script type="math/tex">I</script>
that are also not in any of the 1-dimensional subspaces –
for example <script type="math/tex">x^3y^3.</script>
Of those, we only have finitely many.
In the example, it's 4.</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_poly-4.png" >
<figcaption>The correction term for monomials not counted at all is 4.</figcaption>
</figure>
<p>After adding the second correction term, we have <script type="math/tex">{}^a\textsf{HP}_{I/R}(s)=5s-1</script>
.</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_poly-5.png" >
<figcaption>The staircase of ⟨G⟩ with 1-dimensional subspaces and both correction terms.</figcaption>
</figure>
<p>By finding the Hilbert polynomial, we also computed the Hilbert regularity of <script type="math/tex">R/I:</script>
it's <script type="math/tex">7.</script>
In other words, for <script type="math/tex">s\geqslant 7,</script>
we have <script type="math/tex">\dim_\mathbb{F}(R/I) = {}^a\textsf{HF}_{R/I}(s) = {}^a\textsf{HP}_{R/I}(s) = 5s-1.</script>
</p>
<p>This coincides with the distance of the closest diagonal
<label for="mn-hyperplane" class="margin-toggle">🛈</label><input type="checkbox" id="mn-hyperplane" class="margin-toggle"/>
<span class="marginnote">
Generally speaking, the diagonal is a hyperplane.
</span>
such that all “overlapping” as well as all zero-dimensional parts of the staircase are enclosed –
the red and blue dashed circles, respectively, in above picture.</p>
<h1 id="more-variables-more-dimensions">More Variables, More Dimensions</h1>
<p>The intuition of the 2-dimensional examples above translate to higher dimensions:
find the most distant corner of the blue circle –
the parts where positive-dimensional subspaces of the variety overlap –
and the red circle –
the variety's part of dimension zero –
and take the distance of the farther of these two corners as the Hilbert regularity.
However, finding the corners becomes less trivial.
Let me demonstrate with a staircase consisting of three “tunnels” that we'll successively modify.</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_3D-0.png" >
<figcaption>Ideal ⟨G⟩ as 3-dimensional 𝔽-vector space.</figcaption>
</figure>
<p>Above staircase is defined by <script type="math/tex">G=\{x^2y, x^2z^3, yz^2\}.</script>
No monomials exist in the red bubble –
every point is part of a subspace of dimension 1.
The blue corner is the monomial defining the enclosing space of the parts where positive-dimensional subspaces overlap.
It coincides with the least common multiple (lcm) of the three elements of <script type="math/tex">G,</script>
namely <script type="math/tex">m=x^2yz^3.</script>
The Hilbert regularity can be read off from <script type="math/tex">m\!</script>
:
the hyperplane's required distance is <script type="math/tex">\deg(x^{(2-1)}y^{(1-1)}z^{(3-1)})=3.</script>
</p>
<p>That was easy enough.
Let's take a look at <script type="math/tex">G' = \{x^2y, yz^2, z^3\}.</script>
The staircase looks similar, with the exception for the “<script type="math/tex">z</script>
-tunnel.”</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_3D-1.png" >
<figcaption>Closing off the “tunnel” along the z-axis changes the Hilbert regularity.</figcaption>
</figure>
<p>Even though <script type="math/tex">m</script>
from above is still on the “border” of <script type="math/tex">\langle G' \rangle,</script>
just as it was for <script type="math/tex">\langle G \rangle,</script>
it no longer defines the enclosing space we're looking for.
Note that the lcm of the elements in <script type="math/tex">G'</script>
is still <script type="math/tex">m,</script>
but the Hilbert regularity is now defined by the lcm of only two elements, <script type="math/tex">x^2y</script>
and <script type="math/tex">yz^2,</script>
giving <script type="math/tex">m' = x^2yz^2.</script>
The Hilbert regularity has changed to <script type="math/tex">2.</script>
</p>
<p>Let's modify the staircase a little bit more, and look at <script type="math/tex">G^\dagger = \{x^2, yz^2, z^3\}.</script>
</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_3D-2.png" >
<figcaption>Additionally closing off the “tunnel” along the x-axis changes the Hilbert regularity again.</figcaption>
</figure>
<p>he Hilbert regularity can once again be found by looking at <script type="math/tex">m = x^2yz^3,</script>
but the reason has changed.
This time around, <script type="math/tex">m</script>
is the most distant corner of the volume enclosing all monomials not appearing in positive-dimensional subspaces of the variety –
that's the red bubble from before.
And since only one “tunnel” remains, there's no more overlap in positive-dimensional subspaces –
the blue bubble, and with it the blue dot, have disappeared.
Note that <script type="math/tex">m</script>
is once again the lcm of the three elements of <script type="math/tex">G^\dagger.</script>
The Hilbert regularity is now again 3.</p>
<p>For completeness sake, let's close off the last of the tunnels by adding <script type="math/tex">y^4</script>
to <script type="math/tex">G^\dagger.</script>
Monomial <script type="math/tex">m^\dagger = x^2y^4z^2,</script>
being the lcm of <script type="math/tex">x^2,</script>
<script type="math/tex">yz^2,</script>
and <script type="math/tex">y^4,</script>
is the Hilbert regularity-defining corner.
The Hilbert regularity for <script type="math/tex">G^\dagger</script>
is 5.</p>
<figure>
<img src="/blog/2021-06-08_monomial_ideal_3D-3.png" >
<figcaption>Additionally closing off the “tunnel” along the y-axis again changes the Hilbert regularity.</figcaption>
</figure>
<h1 id="computing-the-regularity-in-sagemath">Computing the Regularity in sagemath</h1>
<p>After having understood the Hilbert regularity, it's time to throw some <a rel="nofollow noreferrer" href="https://www.sagemath.org/">sagemath</a> at the problem.
Below, you can find two approaches.
The first uses the staircase, like in the examples above.
The second is based on the <em>Hilbert series</em>, which is explained <a href="https://jfs.sh/blog/hilbert-reg/#math-approach">further below</a>.</p>
<h2 id="the-nice-to-visualize-geometric-approach">The nice-to-visualize geometric approach</h2>
<p>Using the geometric intuitions from above, we can compute the Hilbert regularity by finding all of the staircase's corners.
The code below only works for ideals of dimension 0
<label for="mn-negative_dim" class="margin-toggle">🛈</label><input type="checkbox" id="mn-negative_dim" class="margin-toggle"/>
<span class="marginnote">
Technically, the code works for any dimension ≤ 0, i.e., if there are no common solutions to the polynomials in the ideal, it also works.
</span>
since the polynomial models I do research on are always of that kind.</p>
<figure>
<img src="/blog/2021-06-08_finding_corners.png" >
<figcaption>A general method to identify whether the lcm of some elements of G are a corner of the staircase.</figcaption>
</figure>
<p>The code computes all lcm's of subsets of size <script type="math/tex">n</script>
of the Gröbner basis' leading monomials, which we have determined as the points of interest above.
Any such lcm corresponding to a monomial that's flush to one of the 0-planes is ignored as being degenerate –
for example, the turquoise cross in below picture.
Next, we check if the lcm-monomial is actually a corner of the staircase, by moving one step towards the origin along all axes.
If the resulting monomial is in the ideal, it is not in the staircase, and thus not a corner –
for example, the red cross in above picture.
If, from the moved-to monomial, moving one step along any axis crosses the border of the staircase, we found a corner –
for example, both of the blue crosses in above picture, but not the orange cross in the picture below.
The distance of the furthest such corner corresponds to the Hilbert regularity.</p>
<figure>
<img src="/blog/2021-06-08_finding_corners_3D.png" >
<figcaption>Some edge cases when determining whether a monomial is a corner are most clearly seen in the 3-dimensional case.</figcaption>
</figure>
<p>With those pictures in mind, following the code should be fairly doable:</p>
<pre data-lang="py" style="background-color:#2e3440;color:#d8dee9;" class="language-py "><code class="language-py" data-lang="py"><span style="color:#81a1c1;">import </span><span>combinations
</span><span style="color:#81a1c1;">def </span><span style="color:#88c0d0;">hilbert_regularity_staircase</span><span>(I):
</span><span> </span><span style="color:#616e88;">'''
</span><span style="color:#616e88;"> Compute the Hilbert regularity of R/I where R = I.ring() and I.dimension() <= 0.
</span><span style="color:#616e88;"> This is done by iterating through all n-tuples of the Gröbner basis' leading monomials,
</span><span style="color:#616e88;"> computing their lcm, then determining if that lcm is actually a corner of the staircase.
</span><span style="color:#616e88;"> The corner that is the furthest from the origin determines the Hilbert regularity.
</span><span style="color:#616e88;"> '''
</span><span> </span><span style="color:#81a1c1;">if </span><span>I</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">dimension</span><span>() </span><span style="color:#81a1c1;">> </span><span style="color:#b48ead;">0</span><span>:
</span><span> </span><span style="color:#81a1c1;">raise </span><span style="color:#8fbcbb;">NotImplementedError</span><span>(</span><span style="color:#81a1c1;">f</span><span style="color:#a3be8c;">"Ideal must be of dimension 0 or less, but has dim </span><span>{I</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">dimension</span><span>()}</span><span style="color:#a3be8c;">."</span><span>)
</span><span> gens </span><span style="color:#81a1c1;">= </span><span>I</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">ring</span><span>()</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">gens</span><span>() </span><span style="color:#616e88;"># all variables
</span><span> n </span><span style="color:#81a1c1;">= </span><span style="font-style:italic;color:#88c0d0;">len</span><span>(gens)
</span><span> xyz </span><span style="color:#81a1c1;">= </span><span style="font-style:italic;color:#88c0d0;">reduce</span><span>(operator</span><span style="color:#81a1c1;">.</span><span>mul</span><span style="color:#eceff4;">, </span><span>gens</span><span style="color:#eceff4;">, </span><span style="color:#b48ead;">1</span><span>)
</span><span> gb_lm </span><span style="color:#81a1c1;">= </span><span>[f</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">lm</span><span>() </span><span style="color:#81a1c1;">for </span><span>f </span><span style="color:#81a1c1;">in </span><span>I</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">groebner_basis</span><span>()]
</span><span> I_lm </span><span style="color:#81a1c1;">= </span><span style="color:#88c0d0;">Ideal</span><span>(gb_lm)
</span><span> hil_reg </span><span style="color:#81a1c1;">= </span><span style="color:#b48ead;">0
</span><span> </span><span style="color:#81a1c1;">for </span><span>lms </span><span style="color:#81a1c1;">in </span><span style="color:#88c0d0;">combinations</span><span>(gb_lm</span><span style="color:#eceff4;">, </span><span>n):
</span><span> m </span><span style="color:#81a1c1;">= </span><span style="color:#88c0d0;">lcm</span><span>(lms)
</span><span> </span><span style="color:#616e88;"># are we considering a meaningful combination of lm's?
</span><span> </span><span style="color:#616e88;"># i.e., does every variable make an appearance in m?
</span><span> </span><span style="color:#81a1c1;">if </span><span style="font-style:italic;color:#88c0d0;">len</span><span>(m</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">degrees</span><span>()) </span><span style="color:#81a1c1;">!= </span><span>n </span><span style="color:#81a1c1;">or not </span><span style="font-style:italic;color:#88c0d0;">all</span><span>(m</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">degrees</span><span>()):
</span><span> </span><span style="color:#81a1c1;">continue
</span><span> m </span><span style="color:#81a1c1;">= </span><span>m </span><span style="color:#81a1c1;">/ </span><span>xyz </span><span style="color:#616e88;"># 1 step towards origin along all axes
</span><span> </span><span style="color:#81a1c1;">assert </span><span>I</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">ring</span><span>()(m) </span><span style="color:#81a1c1;">== </span><span>m</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">numerator</span><span>() </span><span style="color:#616e88;"># no negative exponents, please
</span><span> m </span><span style="color:#81a1c1;">= </span><span>I</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">ring</span><span>()(m)
</span><span> </span><span style="color:#616e88;"># are we in a corner of the staircase?
</span><span> </span><span style="color:#616e88;"># i.e., not in the ideal, but moving 1 step along any axis, we end up in the ideal?
</span><span> </span><span style="color:#81a1c1;">if not </span><span>m </span><span style="color:#81a1c1;">in </span><span>I_lm </span><span style="color:#81a1c1;">and </span><span style="font-style:italic;color:#88c0d0;">all</span><span>([v</span><span style="color:#81a1c1;">*</span><span>m </span><span style="color:#81a1c1;">in </span><span>I_lm </span><span style="color:#81a1c1;">for </span><span>v </span><span style="color:#81a1c1;">in </span><span>gens]):
</span><span> hil_reg </span><span style="color:#81a1c1;">= </span><span style="font-style:italic;color:#88c0d0;">max</span><span>(hil_reg</span><span style="color:#eceff4;">, </span><span>m</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">degree</span><span>())
</span><span> </span><span style="color:#81a1c1;">return </span><span>hil_reg
</span></code></pre>
<h2 id="math-approach">The rigorous mathematical approach</h2>
<p>The Hilbert regularity can also be computed using the <a rel="nofollow noreferrer" href="https://en.wikipedia.org/wiki/Hilbert_series_and_Hilbert_polynomial"><em>Hilbert series</em></a>.
The Hilbert series is the formal power series of the (projective) Hilbert function:
<label for="mn-projective" class="margin-toggle">🛈</label><input type="checkbox" id="mn-projective" class="margin-toggle"/>
<span class="marginnote">
We can either look at the projective Hilbert function, or equivalently subtract two consecutive values of the affine Hilbert function, as I am doing here.
</span>
<script type="math/tex;mode=display">\textsf{HS}_{R/I}(t) = \sum_{s=1}^{\infty}({}^a\textsf{HF}_{R/I}(s) - {}^a\textsf{HF}_{R/I}(s-1))t^s</script>
The Hilbert series' coefficient of monomial <script type="math/tex">t^d</script>
is the number of monomials of degree <script type="math/tex">d</script>
<label for="mn-equality" class="margin-toggle">🛈</label><input type="checkbox" id="mn-equality" class="margin-toggle"/>
<span class="marginnote">
Unlike before, we only consider equality now!
</span>
that are in <script type="math/tex">R</script>
but not in <script type="math/tex">I.</script>
The Hilbert regularity coincides with the degree of the highest-degree consecutive term having positive coefficient.</p>
<p>For example, take <script type="math/tex">I</script>
from the very first example again, where we had <script type="math/tex">G = \{x^6, x^2y^2, y^5\}.</script>
Evaluating the Hilbert function of <script type="math/tex">R/I</script>
gives <script type="math/tex">(1, 3, 6, 10, 14, 17, 18, 18, \dots).</script>
The Hilbert series of <script type="math/tex">R/I</script>
is
<script type="math/tex;mode=display">\textsf{HS}_{R/I}(t) = 1 + 2t + 3t^2 + 4t^3 + 4t^4 + 3t^5 + t^6.</script>
And indeed, the sought-for term has degree <script type="math/tex">6,</script>
which we have seen to be the Hilbert regularity of <script type="math/tex">R/I.</script>
</p>
<p>Conveniently, sagemath has a method for computing the Hilbert series of an ideal, albeit only for homogeneous ideals.
As we have established above, the Hilbert regularity does not change when looking only at the leading monomials of the ideal's Gröbner basis, which is a homogeneous ideal.
Thus, finally, we have a catch-all piece of code for computing the Hilbert regularity.</p>
<pre data-lang="py" style="background-color:#2e3440;color:#d8dee9;" class="language-py "><code class="language-py" data-lang="py"><span style="color:#81a1c1;">def </span><span style="color:#88c0d0;">hilbert_regularity</span><span>(I):
</span><span> </span><span style="color:#616e88;">'''
</span><span style="color:#616e88;"> Compute the Hilbert regularity of R/I using the Hilbert series of R/I.
</span><span style="color:#616e88;"> '''
</span><span> gb_lm </span><span style="color:#81a1c1;">= </span><span>[f</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">lm</span><span>() </span><span style="color:#81a1c1;">for </span><span>f </span><span style="color:#81a1c1;">in </span><span>I</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">groebner_basis</span><span>()]
</span><span> I_lm </span><span style="color:#81a1c1;">= </span><span style="color:#88c0d0;">Ideal</span><span>(gb_lm)
</span><span> hil_ser </span><span style="color:#81a1c1;">= </span><span>I_lm</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">hilbert_series</span><span>()
</span><span> hil_reg </span><span style="color:#81a1c1;">= </span><span>hil_ser</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">numerator</span><span>()</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">degree</span><span>() </span><span style="color:#81a1c1;">- </span><span>hil_ser</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">denominator</span><span>()</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">degree</span><span>()
</span><span> </span><span style="color:#81a1c1;">return </span><span>hil_reg
</span></code></pre>
<h1 id="summary">Summary</h1>
<p>In this post, we have looked at the Hilbert function, the Hilbert polynomial, the Hilbert regularity, and the Hilbert series.
For the first two of those, extensive examples have built intuition for what the Hilbert regularity is –
and why it is not trivial to compute using this intuition.
Instead, the Hilbert series gives us a tool to find the Hilbert regularity fairly easily.</p>
<h1 id="references">References</h1>
<ol>
<li>Magali Bardet, Jean-Charles Faugère, Bruno Salvy, and Bo-Yin Yang.
<em>Asymptotic behaviour of the degree of regularity of semi-regular polynomial systems</em>.
In Proceedings of MEGA, volume 5, 2005.</li>
<li>Alessio Caminata and Elisa Gorla.
<em>Solving multivariate polynomial systems and an invariant from commutative algebra</em>.
arXiv preprint arXiv:1706.06319, 2017.</li>
<li>David A. Cox, John Little, and Donal O’Shea.
<em>Ideals, Varieties, and Algorithms: An Introduction to Computational Algebraic Geometry and Commutative Algebra</em>.
Springer Science & Business Media, 2013.</li>
</ol>
Why the Degree of Regularity Alone is Bad for Estimating Security – a Counter Example to Common Arguments2021-05-18T00:00:00+00:002021-05-18T00:00:00+00:00https://jfs.sh/blog/dreg-insufficient-for-security/<table><thead><tr><th align="left">🛈</th></tr></thead><tbody>
<tr><td align="left">I originally wrote this post when working at <a rel="nofollow noreferrer" href="https://asdm.gmbh">AS Discrete Mathematics</a> as part of a project sponsored by the <a rel="nofollow noreferrer" href="https://ethereum.foundation/">Ethereum Foundation</a>. It is reproduced here with friendly permission.</td></tr>
</tbody></table>
<p>Cryptographic primitives designed to be algebraically simple – <a rel="nofollow noreferrer" href="https://asdm.gmbh/arithmetization-oriented-ciphers/">AOCs</a> – might be particularly vulnerable to algebraic attacks.
One of the most threatening attack vectors in this category is the <a href="https://jfs.sh/blog/introduction-to-gb-attacks-on-aoc/">Gröbner basis analysis</a>.
For a cipher or hash function to be considered secure, the Gröbner basis for any polynomial system derivable from the primitive needs to be intractable to compute.</p>
<p>Unfortunately, the complexity of computing a Gröbner basis for a specific polynomial system is generally not known before the computation is completed.
However, some complexity bounds exist.
One of the most prominently used bounds is based on a polynomial system's <a rel="nofollow noreferrer" href="https://asdm.gmbh/2021/03/15/d_reg/">degree of regularity</a>.</p>
<p>Generally, computing the degree of regularity for a polynomial system is as hard as <a rel="nofollow noreferrer" href="https://asdm.gmbh/2021/04/16/dreg-from-gb/">computing the Gröbner basis</a> itself.
Luckily, for an “<a rel="nofollow noreferrer" href="https://staff.math.su.se/shapiro/ProblemSolving/Pardue.pdf">average</a>”<a rel="nofollow noreferrer" href="https://en.wikipedia.org/wiki/Regular_sequence">regular</a> determined system, the degree of regularity equals the <em>Macaulay bound</em>.
That is, for <script type="math/tex">\mathcal{F} = \{f_0, \dots, f_{s-1}\} \subseteq \mathbb{F}[x_0, \dots, x_{n-1}]</script>
we have <script type="math/tex">d_\text{reg} = 1 + \sum_{i=0}^{s-1}\deg(f_i) - 1.</script>
</p>
<h1 id="how-current-aocs-argue-resistance-to-grobner-basis-analysis">How Current AOCs Argue Resistance to Gröbner Basis Analysis</h1>
<p>The <strong>Poseidon</strong> [6] paper mentions the Macaulay bound, and implicitly assumes that the polynomial system arising from Poseidon is a regular sequence.
My own experiments indicate that this assumption is <em>false</em>.
Similarly, <strong>GMiMC</strong> [1] uses the Macaulay bound and assumes the regularity of the system implicitly.
My own experiments indicate that this assumption is also <em>false</em>.
The authors of <strong>Ciminion</strong> [4] explicitly assume the derived system to be regular, but mistakenly describe this to be “the best adversarial scenario” where in fact the opposite is true.
Furthermore, my own experiments indicate that the polynomial sequence is <em>not</em> regular.
For <strong>Rescue</strong> [2], the authors perform Gröbner basis attacks on round-reduced variants, showing that the system arising from Rescue is <em>not</em> regular.
They then extrapolate the observed degrees to estimate the degree of regularity for the full-round primitive.</p>
<p>In summary, two approaches can be observed:</p>
<ol>
<li>assume regularity of the system, then use the Macaulay bound to compute the degree of regularity, or</li>
<li>extrapolate the degree of regularity from round-reduced variants.
Both approaches then use the degree of regularity to estimate the complexity for computing the Gröbner basis.
This is generally done by looking at the complexity bound of the most efficient Gröbner basis algorithm, F<sub>5</sub>.
This bound is
<script type="math/tex;mode=display">O\left(\binom{n + d_\text{reg}}{n}^\omega\right)</script>
where <script type="math/tex">n</script>
is the number of variables in the polynomial ring [3].</li>
</ol>
<p>But:
this is an upper bound.
We need a <em>lower</em> bound.</p>
<h1 id="the-degree-of-regularity-does-not-suffice">The Degree of Regularity does not Suffice</h1>
<p>I'll make a series of increasingly complex and decreasingly pathological examples why the degree of regularity derived from the Macaulay bound does not suffice to accurately estimate the <em>concrete</em> complexity of computing a Gröbner basis.
The ideals of all the systems below are of dimension 0, meaning that the respective sets of common solutions are non-empty and contain finitely many elements.
This accurately reflects the properties of polynomial systems modeling a cryptographic primitive.</p>
<h2 id="example-1-the-system-is-already-a-grobner-basis">Example 1: The system is already a Gröbner basis</h2>
<p>Let's say we want to compute the Gröbner basis for
<script type="math/tex">\mathcal{F}_\text{gb} = \{x^7, y^7, z^7\} \subseteq \mathbb{F}[x,y,z].</script>
We quickly see that <script type="math/tex">\mathcal{F}</script>
is a <a rel="nofollow noreferrer" href="https://en.wikipedia.org/wiki/Regular_sequence">regular sequence</a>, and determine that the degree of regularity is <script type="math/tex">d_\text{reg} = 1 + \sum_{i=0}^2 7 - 1 = 19.</script>
Consequently, or so the roughly sketched argument above goes, a Gröbner basis algorithm like F<sub>4</sub> or F<sub>5</sub> should have to perform computations on polynomials of up to degree 19 before being able to output a Gröbner basis.</p>
<p>However, <script type="math/tex">\mathcal{F}_\text{gb}</script>
is already a Gröbner basis – no computation at all is required!</p>
<h2 id="example-2-the-system-can-be-split-up">Example 2: The system can be split up</h2>
<p>Deriving a polynomial system from a cryptographic primitive rarely gives you a Gröbner basis – although there are exceptions, like GMiMC.
Instead, let's look at the following polynomial system.
<script type="math/tex;mode=display">\mathcal{F}_\text{indep} = \left\{
\begin{aligned}
&u^2 v w + u^2, && x^2 y z + x^2, \\
&u v^2 w + v^2 + 1, && x y^2 z + y^2 + 1, \\
&u v w^2 + w^2, && x y z^2 + z^2 \\
\end{aligned}
\right\}
\subseteq \mathbb{F}[u,v,w,x,y,z].</script>
</p>
<p>The polynomials containing variables <script type="math/tex">u</script>
, <script type="math/tex">v</script>
and <script type="math/tex">w</script>
are completely independent from the polynomials where <script type="math/tex">x</script>
, <script type="math/tex">y,</script>
and <script type="math/tex">z</script>
make an appearance.
For the Macaulay bound, this fact is irrelevant.
Since <script type="math/tex">\mathcal{F}_\text{indep}</script>
is a regular sequence, we might derive <script type="math/tex">d_\text{reg} = 1 + \sum_{i=0}^5 4 - 1 = 19.</script>
</p>
<p>However, the F<sub>4</sub> implementations of <a rel="nofollow noreferrer" href="http://magma.maths.usyd.edu.au/magma/">magma</a> and <a rel="nofollow noreferrer" href="https://www-polsys.lip6.fr/%7Ejcf/FGb/">FGb</a> as well as the <a rel="nofollow noreferrer" href="https://github.com/ASDiscreteMathematics/gb-voodoo/">python implementation of F<sub>5</sub></a> all compute on polynomials of only degree 5 and lower before finding the Gröbner basis –
they are not fooled by this attempt to artificially increase the complexity.</p>
<h2 id="example-3-the-system-is-not-very-involved">Example 3: The system is not very “involved”</h2>
<p>When deriving a polynomial system from a (single) cryptographic primitive, a partition in the set of polynomials like above is unlikely to appear –
intuitively, that would lead to weak <a rel="nofollow noreferrer" href="https://en.wikipedia.org/wiki/Confusion_and_diffusion#Diffusion">diffusion</a>.
Let's change the system a little, then.
<script type="math/tex;mode=display">\mathcal{F}_\text{invlv} = \left\{
\begin{aligned}
&u^2 v w + u^2, && x^2 y z + x^2, \\
&u v^2 w + v^2 + 1, && x y^2 z + y^2 + 1, \\
&u v w^2 + w^2, && u^4 + z^4 \\
\end{aligned}
\right\}
\subseteq \mathbb{F}[u,v,w,x,y,z].</script>
</p>
<p>The sets <script type="math/tex">\mathcal{F}_\text{indep}</script>
and <script type="math/tex">\mathcal{F}_\text{invlv}</script>
differ in one polynomial, and this polynomial <script type="math/tex">(u^4 + z^4) = f_\text{link}</script>
links the two independent subsets of <script type="math/tex">\mathcal{F}_\text{indep}.</script>
I didn't derive the system from any concrete primitive, but a polynomial like <script type="math/tex">f_\text{link}</script>
might express how to move from one round to the next in a cipher.</p>
<p>The Macaulay bound for <script type="math/tex">\mathcal{F}_\text{invlv}</script>
does not change from the bound for <script type="math/tex">\mathcal{F}_\text{indep}</script>
since <script type="math/tex">f_\text{link}</script>
is of the same degree as the polynomial it replaced.
Also, <script type="math/tex">\mathcal{F}_\text{invlv}</script>
is still a regular sequence, so we still have <script type="math/tex">d_\text{reg} = 19.</script>
</p>
<p>You might have guessed it by now:
the highest polynomials appearing during a Gröbner basis computation for <script type="math/tex">\mathcal{F}_\text{invlv}</script>
is not 19.
Magma's F<sub>4</sub> reports a maximum degree of <script type="math/tex">6,</script>
FGb only reaches degree 5, and so does python-F<sub>5</sub>.</p>
<p>While I don't fully understand why this happens, <a rel="nofollow noreferrer" href="https://github.com/ASDiscreteMathematics/gb-voodoo/">vectors of origin</a> give some hints.
Briefly, <script type="math/tex">v_i</script>
is a vector of origin for Gröbner basis element <script type="math/tex">g_i</script>
if <script type="math/tex">\mathcal{F}_\text{invlv} \cdot v_i = g_i.</script>
Below are the vectors of origin for <script type="math/tex">\mathcal{F}_\text{invlv},</script>
where any big polynomial is replaced by <script type="math/tex">\bullet</script>
to ease reading.
<script type="math/tex;mode=display">\begin{align*}
v_1 &= (\bullet, \bullet, {\small 0}, {\small 0}, {\small 0}, {\small 0}), \\
v_2 &= (\bullet, \bullet, {\small 0}, {\small 0}, {\small 0}, {\small 0}), \\
v_3 &= ({\small 0}, {\small 0}, \bullet, 3, {\small 0}, {\small 0}), \\
v_4 &= ({\small 0}, {\small 0}, \bullet, \bullet, {\small 0}, {\small 0}), \\
v_5 &= ({\small 0}, {\small 0}, \bullet, \bullet, 1, {\small 0}), \\
v_6 &= ({\small 0}, {\small 0}, \bullet, \bullet, \bullet, 1) \\
\end{align*}</script>
</p>
<p>A zero in position <script type="math/tex">i</script>
in a vector of origin means that <script type="math/tex">f_i</script>
was unnecessary for computing the Gröbner basis element.
Above vectors of origin have a lot of zeros –
in fact, even though all polynomials are linked to one another in some (potentially indirect) way, there seems to be a partition.</p>
<p>I describe polynomial systems for which the Gröbner bases' elements can be computed from a few input polynomials at a time as having low “involvement.”
As of yet, there is no mathematically rigourous way to define this notion, but above example should give a rough intuition.
My observations indicate that low involvement means low complexity for computing a Gröbner basis.</p>
<p><strong>Note.</strong>
Above counter-examples do not disprove the equality of the degree of regularity and the Macaulay bound for <em>generic</em> polynomial systems –
they only show that regularity of the sequence is not a sufficient requirement.</p>
<h1 id="existing-lower-bounds">Existing Lower Bounds</h1>
<p>The main message of this post is that we need (tight-ish) <em>lower</em>, not upper, bounds for estimating the complexity of a Gröbner basis computation in order to accurately asses the security of cryptographic primitives against this vector of attack.
Unfortunately, the scientific literature currently has little to offer in this regard.</p>
<p>Hyun [5] exclusively deals with field <script type="math/tex">\mathbb{Q},</script>
while we are interested in finite fields.
Möller & Mora [7] look at ideals of positive dimension, while we are only interested in zero-dimensional ideals.
Furthermore, all given bounds are <em>existential</em> while we need a <em>constructive</em> bound.</p>
<p>In summary, current strategies for arguing that some Arithmetization Oriented Primitive is resistant against Gröbner basis attacks make too many unbacked assumptions, often implicitly.
The tools to make these arguments rigorously don't currently exist.
Or in other words: “<a rel="nofollow noreferrer" href="https://www.youtube.com/watch?v=AgMLPFCFE90">look at me still talking when there's science to do.</a>”</p>
<h1 id="references">References</h1>
<ol>
<li>Albrecht, M.R., Grassi, L., Perrin, L., Ramacher, S., Rechberger, C., Rotaru, D.,Roy, A., Schofnegger, M.:
<em>Feistel Structures for MPC, and More</em>.
In: ESORICS. pp.151–171. Springer (2019)</li>
<li>Aly, A., Ashur, T., Ben-Sasson, E., Dhooghe, S., Szepieniec, A.:
<em>Design of Symmetric Primitives for Advanced Cryptographic Protocols</em>.
IACR ToSC 2020(3), 1–45(2020)</li>
<li>Bardet, M., Faugère, J.C., Salvy, B.:
<em>On the complexity of the F5 Gröbner basis algorithm</em>.
Journal of Symbolic Computation 70, 49–70 (2015)</li>
<li>Dobraunig, C.E., Grassi, L., Guinet, A., Kuijsters, D.:
<em>Ciminion: Symmetric Encryption Based on Toffoli-Gates over Large Finite Fields</em>.
In: Eurocrypt 2021 (2021)</li>
<li>Huynh, Dung T.:
<em>A superexponential lower bound for Gröbner bases and Church-Rosser commutative Thue systems</em>.
Information and Control, 68(1- 3):196–206 (1986)</li>
<li>Grassi, L., Khovratovich, D., Rechberger, C., Roy, A., Schofnegger, M.:
<em>Poseidon: A New Hash Function for Zero-Knowledge Proof Systems</em>.
In: USENIX Security. USENIXAssociation (2020)</li>
<li>Möller, H. M., and Mora, F.:
<em>Upper and lower bounds for the degree of Gröbner bases</em>.
In: International Symposium on Symbolic and Algebraic Manipulation, pages 172–183. Springer (1984)</li>
</ol>
Converting Gröbner bases with FGLM2020-10-22T00:00:00+00:002020-10-22T00:00:00+00:00https://jfs.sh/blog/fglm-presentation/<table><thead><tr><th align="left">🛈</th></tr></thead><tbody>
<tr><td align="left">I originally wrote this post when working at <a rel="nofollow noreferrer" href="https://asdm.gmbh">AS Discrete Mathematics</a> as part of a project sponsored by the <a rel="nofollow noreferrer" href="https://ethereum.foundation/">Ethereum Foundation</a>. It is reproduced here with friendly permission.</td></tr>
</tbody></table>
<p>Have you ever computed a Gröbner basis in some monomial order
<script type="math/tex">\prec_0</script>
only to then realize that you <em>actually</em> wanted it in another order
<script type="math/tex">\prec_1</script>
?
I know, happens <em>all</em> the time…
But fret not, FGLM can convert between the two orders, and you don't have to start your computation from scratch.</p>
<p><img src="/blog/2020-10-22_fglm_summary.png" alt="A visual summary of the execution of FGLM on an example input." title="Left, a " /></p>
<p><a rel="nofollow noreferrer" href="https://www.bitchute.com/video/5TeyXMq4m7Gc/">Here's a recording</a> where I'm explaining how FGLM works.
If you'd like to look through the slides at your own pace, <a href="/blog/2020-10-22_fglm_example_animated.pdf">here they are</a>.
You can also find the two Gröbner bases used in the example as well as pseudocode for FGLM in the slides, in case you want to retrace the steps yourself.</p>
<p align="center">
<iframe scrolling="no" style="border: none;display:block;" src="https://www.bitchute.com/embed/5TeyXMq4m7Gc/" width="640" height="360" frameborder="0"></iframe>
</p>
<p>If you are interested in not only <em>how</em> but also <em>why</em> FGLM works, have a look at the <a rel="nofollow noreferrer" href="https://doi.org/10.1006/jsco.1993.1051">original publication</a>.
Section 5 and 6 give a comprehensive overview of FGLM's complexity, which can be summarized as
<script type="math/tex">O(n\cdot D^3)</script>
where <script type="math/tex">D</script>
is the dimension of quotient ring
<script type="math/tex">k[x_0, \dots, x_{n-1}] / \langle G \rangle</script>
as a <script type="math/tex">k</script>
-vector-space.
More intuitively, <script type="math/tex">D</script>
is the number of monomials in the staircase of a Gröbner basis, which are those dots in the non-blue region in this post's first picture.</p>
<pre data-lang="python" style="background-color:#2e3440;color:#d8dee9;" class="language-python "><code class="language-python" data-lang="python"><span style="color:#81a1c1;">def </span><span style="color:#88c0d0;">FGLM</span><span>(order_new</span><span style="color:#eceff4;">, </span><span>gb_old</span><span style="color:#eceff4;">, </span><span>order_old):
</span><span> d </span><span style="color:#81a1c1;">= </span><span>{}
</span><span> gb_new </span><span style="color:#81a1c1;">= </span><span>[]
</span><span> next_monoms </span><span style="color:#81a1c1;">= </span><span>[</span><span style="color:#b48ead;">1</span><span>]
</span><span> </span><span style="color:#81a1c1;">while </span><span>next_monoms:
</span><span> monom </span><span style="color:#81a1c1;">= </span><span style="font-style:italic;color:#88c0d0;">min</span><span>(next_monoms) </span><span style="color:#616e88;"># according to order_new
</span><span> next_monoms </span><span style="color:#81a1c1;">-= </span><span>monom
</span><span> </span><span style="color:#81a1c1;">if </span><span>no g </span><span style="color:#81a1c1;">in </span><span>gb_new such that </span><span style="color:#88c0d0;">LM</span><span>(g) </span><span style="color:#81a1c1;">| </span><span>monom:
</span><span> </span><span style="color:#616e88;"># monom is still within staircase
</span><span> reduced_monom </span><span style="color:#81a1c1;">= </span><span>monom</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">reduce</span><span>(gb_old</span><span style="color:#eceff4;">, </span><span>order_old)
</span><span> </span><span style="color:#81a1c1;">if </span><span>reduced_monom </span><span style="color:#81a1c1;">+ </span><span style="font-style:italic;color:#88c0d0;">sum</span><span>([w[u] </span><span style="color:#81a1c1;">* </span><span>v </span><span style="color:#81a1c1;">for </span><span>u</span><span style="color:#eceff4;">, </span><span>v </span><span style="color:#81a1c1;">in </span><span>d</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">items</span><span>()]) </span><span style="color:#81a1c1;">== </span><span style="color:#b48ead;">0 </span><span style="background-color:#bf616a;color:#d8dee9;">for</span><span> some w</span><span style="color:#eceff4;">:
</span><span> </span><span style="color:#616e88;"># w[i] are field elements, i.e., coefficients.
</span><span> </span><span style="color:#616e88;"># they can be found by Gaussian reduction of d.values()
</span><span> gb_new </span><span style="color:#81a1c1;">+= </span><span>monom </span><span style="color:#81a1c1;">+ </span><span style="font-style:italic;color:#88c0d0;">sum</span><span>([w[u] </span><span style="color:#81a1c1;">* </span><span>u </span><span style="color:#81a1c1;">for </span><span>u</span><span style="color:#eceff4;">, </span><span>v </span><span style="color:#81a1c1;">in </span><span>d</span><span style="color:#81a1c1;">.</span><span style="color:#88c0d0;">items</span><span>()])
</span><span> </span><span style="color:#81a1c1;">else</span><span>:
</span><span> d </span><span style="color:#81a1c1;">+= </span><span>{monom </span><span style="color:#eceff4;">: </span><span>reduced_monom}
</span><span> next_monoms </span><span style="color:#81a1c1;">+= </span><span>[x_i </span><span style="color:#81a1c1;">* </span><span>monom </span><span style="color:#81a1c1;">for </span><span>i </span><span style="color:#81a1c1;">in </span><span style="font-style:italic;color:#88c0d0;">range</span><span>(n)]
</span><span> </span><span style="color:#81a1c1;">return </span><span>gb_new
</span></code></pre>
Introduction to GB Attacks on AOC2020-08-12T00:00:00+00:002020-08-12T00:00:00+00:00https://jfs.sh/blog/introduction-to-gb-attacks-on-aoc/<table><thead><tr><th align="left">🛈</th></tr></thead><tbody>
<tr><td align="left">I originally wrote this post when working at <a rel="nofollow noreferrer" href="https://asdm.gmbh">AS Discrete Mathematics</a> as part of a project sponsored by the <a rel="nofollow noreferrer" href="https://ethereum.foundation/">Ethereum Foundation</a>. It is reproduced here with friendly permission.</td></tr>
</tbody></table>
<p>Today, I gave an introductory presentation on Gröbner basis attacks in the context of attacking arithmetization-oriented ciphers.</p>
<figure>
<img src="/blog/2020-08-12_summary.png" >
<figcaption>Summary slide of the introductory presentation to Gröbner bases.</figcaption>
</figure>
<p>Couldn't make it?
Not to worry!
Take a peek at <a href="/blog/2020-08-12_ac_using_gbs.pdf">the slides</a>, and complement them by watching <a rel="nofollow noreferrer" href="https://www.bitchute.com/video/aYp4d6gVnFjT/">the recording</a>.</p>
<p align="center">
<iframe scrolling="no" style="border: none;display:block;" src="https://www.bitchute.com/embed/aYp4d6gVnFjT/" width="640" height="360" frameborder="0"></iframe>
</p>
<p>Another important piece of the puzzle is FGLM, which is skipped in today's presentation.
<a href="https://jfs.sh/blog/fglm-presentation/">Here</a>'s a dedicated presentation about FGLM.</p>