<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Math &amp; Engineering</title>
    <subtitle>Random collections of my notes and articles over the years, mostly about maths and&#x2F;or engineering.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://2π.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://2π.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-05-04T00:00:00+00:00</updated>
    <id>https://2π.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Multi-Party Computation</title>
        <published>2026-05-04T00:00:00+00:00</published>
        <updated>2026-05-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/26/mpc/"/>
        <id>https://2π.com/26/mpc/</id>
        
        <content type="html" xml:base="https://2π.com/26/mpc/">&lt;p&gt;&lt;strong&gt;Work in progress.&lt;&#x2F;strong&gt; This note is a work in progress with many loose
ends and unfinished sentences.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;multi-party-computation&quot;&gt;Multi-Party Computation&lt;&#x2F;h1&gt;
&lt;p&gt;I am only considering linear MPC in the semi-honest setting. My goal
here is to present it its most general algebraic form.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;secret-sharing&quot;&gt;Secret Sharing&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;linear-secret-sharing&quot;&gt;Linear Secret Sharing&lt;&#x2F;h3&gt;
&lt;p&gt;A linear secret sharing scheme is a method to store a secret value from
a space &lt;span class=&quot;math math-inline&quot;&gt;Z&lt;&#x2F;span&gt; over a number of parties by handing each a &lt;em&gt;secret share&lt;&#x2F;em&gt;
from a space &lt;span class=&quot;math math-inline&quot;&gt;U&lt;&#x2F;span&gt;. We adapt the definitions from (Cascudo et al. 2018),
(Abspoel et al. 2020):&lt;&#x2F;p&gt;
&lt;p&gt;Informaly, a secret sharing scheme assigns shares to participants such
that the shares encode a secret. To ensure privacy, which we will define
later, there is an element of randomness in this assignment. In the
linear version the secrets and shares come from linear spaces, or more
generally modules over some ring and decoding is a linear operation.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 1.&lt;&#x2F;strong&gt; (&lt;em&gt;Linear Secret Sharing&lt;&#x2F;em&gt;) Let &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; be a ring, let &lt;span class=&quot;math math-inline&quot;&gt;U&lt;&#x2F;span&gt; and
&lt;span class=&quot;math math-inline&quot;&gt;Z&lt;&#x2F;span&gt; be &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-modules, and let &lt;span class=&quot;math math-inline&quot;&gt;n \geq 1&lt;&#x2F;span&gt;. An &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-party &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-&lt;em&gt;linear
secret-sharing scheme&lt;&#x2F;em&gt; with share alphabet &lt;span class=&quot;math math-inline&quot;&gt;U&lt;&#x2F;span&gt; and secret module &lt;span class=&quot;math math-inline&quot;&gt;Z&lt;&#x2F;span&gt;
consists of an &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-submodule &lt;span class=&quot;math math-inline&quot;&gt;C \subseteq U^{n}&lt;&#x2F;span&gt; together with a
surjective &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-module homomorphism &lt;span class=&quot;math math-inline&quot;&gt;\psi:C \rightarrow Z&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The elements of &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; are the valid share vectors, and &lt;span class=&quot;math math-inline&quot;&gt;\psi(c)&lt;&#x2F;span&gt; is the
secret encoded by &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt;. A sharing &lt;span class=&quot;math math-inline&quot;&gt;\lbrack z\rbrack&lt;&#x2F;span&gt; of a secret
&lt;span class=&quot;math math-inline&quot;&gt;z \in Z&lt;&#x2F;span&gt; is sampled from the fiber &lt;span class=&quot;math math-inline&quot;&gt;\psi^{- 1}(z)&lt;&#x2F;span&gt;. When the fibers are
finite, the default distribution is uniform.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The language of rings and modules may seem a unfamiliar to
cryptographers more acustomed to fields and vector spaces, but this
generalization is practically useful as we can work over computer native
data types.&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; (&lt;em&gt;3-party sharing of bytes&lt;&#x2F;em&gt;) Take
&lt;span class=&quot;math math-inline&quot;&gt;R = U = Z = {\mathbb{Z}}&#x2F;2^{8}{\mathbb{Z}}&lt;&#x2F;span&gt;, the ring of unsigned
bytes, and &lt;span class=&quot;math math-inline&quot;&gt;C = R^{3}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\psi(c) = c_{0} + c_{1} + c_{2}&lt;&#x2F;span&gt;. To share
a secret &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt; we draw &lt;span class=&quot;math math-inline&quot;&gt;r_{0},r_{1}\overset{\ \$}{\leftarrow}R&lt;&#x2F;span&gt; and take
&lt;span class=&quot;math math-inline&quot;&gt;\lbrack z\rbrack = \left( r_{0},r_{1},z - r_{0} - r_{1} \right)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Informally, a subset of parties &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A} \subseteq \lbrack n\rbrack&lt;&#x2F;span&gt;
is a reconstructing set if the assigned subset of shares
&lt;span class=&quot;math math-inline&quot;&gt;c_{\mathcal{A}}&lt;&#x2F;span&gt; corresponds to a unique secret &lt;span class=&quot;math math-inline&quot;&gt;z \in Z&lt;&#x2F;span&gt; for any
sharing &lt;span class=&quot;math math-inline&quot;&gt;c \in C&lt;&#x2F;span&gt;. We can formalize this by observing that share the
selection map &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\mathcal{A}}&lt;&#x2F;span&gt; is a linear map which ‘forgets” the
subspace &lt;span class=&quot;math math-inline&quot;&gt;\ker\pi_{\mathcal{A}}|_{C}&lt;&#x2F;span&gt;. If this is contained in the
subspace &lt;span class=&quot;math math-inline&quot;&gt;\ker\psi&lt;&#x2F;span&gt; ignored by reconstruction, then the secret is
unique.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 2.&lt;&#x2F;strong&gt; (&lt;em&gt;Reconstruction&lt;&#x2F;em&gt;) A set
&lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A} \subseteq \lbrack n\rbrack&lt;&#x2F;span&gt; is a &lt;em&gt;reconstructing set&lt;&#x2F;em&gt; if
&lt;span class=&quot;math math-inline&quot;&gt;\ker\pi_{\mathcal{A}}|_{C} \subseteq \ker\psi&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We say that &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{S}&lt;&#x2F;span&gt; has &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt;-reconstruction&lt;&#x2F;em&gt; if for all
&lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A} \subseteq \lbrack n\rbrack&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;|\mathcal{A}| \geq r&lt;&#x2F;span&gt;,
&lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A}&lt;&#x2F;span&gt; is a reconstructing set.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Similarly, a subset of parties &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A} \subseteq \lbrack n\rbrack&lt;&#x2F;span&gt;
is a privacy set if for any sharing &lt;span class=&quot;math math-inline&quot;&gt;c \in C&lt;&#x2F;span&gt;, the shares
&lt;span class=&quot;math math-inline&quot;&gt;c_{\mathcal{A}}&lt;&#x2F;span&gt; reveal no information about the secret. This is taken
in the information-theoretic sense: given knowledge of a prior
distribution of the secret, learning &lt;span class=&quot;math math-inline&quot;&gt;c_{\mathcal{A}}&lt;&#x2F;span&gt; does not change
the posterior distribution. As &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\mathcal{A}}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\psi&lt;&#x2F;span&gt; are both
linear, it is sufficient to require that &lt;span class=&quot;math math-inline&quot;&gt;c_{\mathcal{A}}&lt;&#x2F;span&gt; is compatible
with every value of &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 3.&lt;&#x2F;strong&gt; (&lt;em&gt;Privacy&lt;&#x2F;em&gt;) A set
&lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A} \subseteq \lbrack n\rbrack&lt;&#x2F;span&gt; is a &lt;em&gt;privacy set&lt;&#x2F;em&gt; if the
product morphism
&lt;span class=&quot;math math-inline&quot;&gt;\left( \pi_{\mathcal{A}},\psi \right):C \rightarrow \pi_{\mathcal{A}(C)} \times Z&lt;&#x2F;span&gt;
is surjective.&lt;&#x2F;p&gt;
&lt;p&gt;We say that &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{S}&lt;&#x2F;span&gt; has &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt;-privacy&lt;&#x2F;em&gt; if for all
&lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A} \subseteq \lbrack n\rbrack&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;|\mathcal{A}| \leq t&lt;&#x2F;span&gt;,
&lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A}&lt;&#x2F;span&gt; is a privacy set.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;We also introduce a notion of efficiency, the rate&lt;&#x2F;p&gt;
&lt;div id=&quot;Rate&quot;&gt;
&lt;div class=&quot;definition numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 4.&lt;&#x2F;strong&gt; (&lt;em&gt;Rate&lt;&#x2F;em&gt;) Given a LSSS with secret space &lt;span class=&quot;math math-inline&quot;&gt;Z&lt;&#x2F;span&gt; and share
space &lt;span class=&quot;math math-inline&quot;&gt;U&lt;&#x2F;span&gt;, its &lt;em&gt;rate&lt;&#x2F;em&gt; is &lt;span class=&quot;math math-display&quot;&gt;\rho = \frac{\log|Z|}{n \cdot \log|U|}.&lt;&#x2F;span&gt; The
inverse &lt;span class=&quot;math math-inline&quot;&gt;\rho^{- 1}&lt;&#x2F;span&gt; is known as the &lt;em&gt;information ratio&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Intuitively, the information ratio is the total storage size of the
secret shares as a multiple of the size of the secrets. It is bounded by
requirements on reconstruction and privacy. Notably there are schemes
with &lt;span class=&quot;math math-inline&quot;&gt;|Z| &amp;gt; |U|&lt;&#x2F;span&gt;, e.g. &lt;em&gt;vector secret sharing&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; (&lt;em&gt;Additive Sharing&lt;&#x2F;em&gt;) For any ring &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; (in fact, any group)
and &lt;span class=&quot;math math-inline&quot;&gt;n &amp;gt; 0&lt;&#x2F;span&gt;, there exist an &lt;em&gt;additive sharing&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-LSSS with
&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-reconstruction and &lt;span class=&quot;math math-inline&quot;&gt;(n - 1)&lt;&#x2F;span&gt;-privacy given by &lt;span class=&quot;math math-inline&quot;&gt;Z = U = R&lt;&#x2F;span&gt; and
&lt;span class=&quot;math math-inline&quot;&gt;\psi(\mathbf{u}) = \sum_{i}u_{i}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; (&lt;em&gt;Shamir Sharing&lt;&#x2F;em&gt;) Consider&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div id=&quot;embedding&quot;&gt;
&lt;div class=&quot;lemma numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 5.&lt;&#x2F;strong&gt; (&lt;em&gt;Embedding&lt;&#x2F;em&gt;) Given an &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-LSSS with secret space &lt;span class=&quot;math math-inline&quot;&gt;Z&lt;&#x2F;span&gt; and an
injective linear map &lt;span class=&quot;math math-inline&quot;&gt;p:Y \rightarrow Z&lt;&#x2F;span&gt;, there exists an &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-LSSS with
secret space &lt;span class=&quot;math math-inline&quot;&gt;Y&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;strong&gt;Proof.&lt;&#x2F;strong&gt; Since &lt;span class=&quot;math math-inline&quot;&gt;p^{- 1}&lt;&#x2F;span&gt; is surjective the composition
&lt;span class=&quot;math math-inline&quot;&gt;p^{- 1} \circ \psi&lt;&#x2F;span&gt; is a surjective homomorphism which forms the
reconstruction map for an &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-LSSS with secret space &lt;span class=&quot;math math-inline&quot;&gt;Y&lt;&#x2F;span&gt;, share space
&lt;span class=&quot;math math-inline&quot;&gt;U&lt;&#x2F;span&gt; and code space &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div id=&quot;concat&quot;&gt;
&lt;div class=&quot;lemma numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 6.&lt;&#x2F;strong&gt; (&lt;em&gt;Concatenation&lt;&#x2F;em&gt;) Given &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-LSSSs with secret spaces &lt;span class=&quot;math math-inline&quot;&gt;Y,Z&lt;&#x2F;span&gt;, we
can construct an &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-LSSS with secret space &lt;span class=&quot;math math-inline&quot;&gt;Y \times Z&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;strong&gt;Proof.&lt;&#x2F;strong&gt; Follows from taking the direct product of &lt;span class=&quot;math math-inline&quot;&gt;Z&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;U&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; and
&lt;span class=&quot;math math-inline&quot;&gt;\psi&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;From this lemma follows that given an &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-LSSSs for &lt;span class=&quot;math math-inline&quot;&gt;Z&lt;&#x2F;span&gt;, we can
construct an LSSS with secret space &lt;span class=&quot;math math-inline&quot;&gt;Z^{n}&lt;&#x2F;span&gt; for any &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;secret-computation&quot;&gt;Secret Computation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;local-realizability&quot;&gt;Local Realizability&lt;&#x2F;h3&gt;
&lt;p&gt;In MPC we not want to share secrets, we also want to do computations on
them and obtain a secret sharing of the result. Sometimes this can be
done locally, by doing operations on the shares directly without
communicating with the other parties.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 7.&lt;&#x2F;strong&gt; (&lt;em&gt;Local Realizability&lt;&#x2F;em&gt;) Given sharing schemes
&lt;span class=&quot;math math-inline&quot;&gt;\left( Z_{i},C_{i},\psi_{i} \right)&lt;&#x2F;span&gt; and a map
&lt;span class=&quot;math math-inline&quot;&gt;f:Z_{1} \times \cdots \times Z_{k} \rightarrow Z&lt;&#x2F;span&gt; we say that &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is
&lt;em&gt;locally realizable&lt;&#x2F;em&gt; if there exists a target scheme &lt;span class=&quot;math math-inline&quot;&gt;(Z,C,\psi)&lt;&#x2F;span&gt; and a
map &lt;span class=&quot;math math-inline&quot;&gt;g:U_{1} \times \cdots \times U_{k} \rightarrow U&lt;&#x2F;span&gt; such that, for
all &lt;span class=&quot;math math-inline&quot;&gt;c_{i} \in C_{i}&lt;&#x2F;span&gt; we have
&lt;span class=&quot;math math-inline&quot;&gt;\psi\left( \hat{g}(c_{1},\ldots,c_{k}) \right) = f\left( \psi_{1}\left( c_{1} \right),\ldots,\psi_{k\left( c_{k} \right)} \right)&lt;&#x2F;span&gt;,
where &lt;span class=&quot;math math-inline&quot;&gt;\hat{g}&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; applied coordinatewise.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;lemma numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 8.&lt;&#x2F;strong&gt; A realizable map necessarily degrades the code proportional to
the polynomial degree of the map.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;lemma numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 9.&lt;&#x2F;strong&gt; (&lt;em&gt;Affine is free&lt;&#x2F;em&gt;) Any affine map &lt;span class=&quot;math math-inline&quot;&gt;f:&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; (&lt;em&gt;Replicated Sharing&lt;&#x2F;em&gt;) Given a ring &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;, there exists a
3-party &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-LSSS with &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;-reconstruction and &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;-privacy given by
&lt;span class=&quot;math math-inline&quot;&gt;Z = R&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;U = R^{2}&lt;&#x2F;span&gt;, and&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;\begin{aligned}
C &amp;amp; = \operatorname{span}\left\{ \begin{pmatrix}
(1,0) \\
(0,0) \\
(0,1)
\end{pmatrix},\begin{pmatrix}
(0,1) \\
(1,0) \\
(0,0)
\end{pmatrix},\begin{pmatrix}
(0,0) \\
(0,1) \\
(1,0)
\end{pmatrix} \right\} \\
\psi(a,b,c) &amp;amp; = a_{0} + b_{0} + c_{0.}
\end{aligned}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Put differently, to share a secret &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt;, create additive shares
&lt;span class=&quot;math math-inline&quot;&gt;z_{0},z_{1},z_{2}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;z = z_{0} + z_{1} + z_{2}&lt;&#x2F;span&gt;, and then give
each party two shares: party one receives &lt;span class=&quot;math math-inline&quot;&gt;\left( z_{0},z_{1} \right)&lt;&#x2F;span&gt;,
party two receives &lt;span class=&quot;math math-inline&quot;&gt;\left( z_{1},z_{2} \right)&lt;&#x2F;span&gt; and party three
&lt;span class=&quot;math math-inline&quot;&gt;\left( z_{2},z_{0} \right)&lt;&#x2F;span&gt;. Given such a sharing of two secrets &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;,
&lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; each party&lt;&#x2F;p&gt;
&lt;p&gt;Given sharings of two secrets&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;x = x_{0} + x_{1} + x_{2}\quad\text{ and }\quad y = y_{0} + y_{1} + y_{2},&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;each party can locally compute one additive share of the product:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;\begin{aligned}
p_{0} &amp;amp; = x_{0}y_{0} + x_{0}y_{1} + x_{1}y_{0}, \\
p_{1} &amp;amp; = x_{1}y_{1} + x_{1}y_{2} + x_{2}y_{1}, \\
p_{2} &amp;amp; = x_{2}y_{2} + x_{2}y_{0} + x_{0}y_{2.}
\end{aligned}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These satisfy&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;p_{0} + p_{1} + p_{2} = \left( x_{0} + x_{1} + x_{2} \right)\left( y_{0} + y_{1} + y_{2} \right) = x \cdot y.&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Thus &lt;span class=&quot;math math-inline&quot;&gt;p_{0},p_{1},p_{2}&lt;&#x2F;span&gt; are additive shares of &lt;span class=&quot;math math-inline&quot;&gt;x \cdot y&lt;&#x2F;span&gt;, but&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; (&lt;em&gt;Reed–Solomon&lt;&#x2F;em&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;beaver-tuples&quot;&gt;Beaver Tuples&lt;&#x2F;h3&gt;
&lt;div class=&quot;definition numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 10.&lt;&#x2F;strong&gt; (&lt;em&gt;Beaver Tuples&lt;&#x2F;em&gt;) Let &lt;span class=&quot;math math-inline&quot;&gt;Z_{1},\ldots,Z_{k},Z&lt;&#x2F;span&gt;be
&lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-algebras. Given a polynomial map
&lt;span class=&quot;math math-inline&quot;&gt;f:Z_{1} \times \cdots \times Z_{k} \rightarrow Z&lt;&#x2F;span&gt;, construct a
polynomial expansion of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; around an arbitrary point &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;f(r + \delta) = \sum_{\alpha}g_{\alpha}(r) \cdot \delta^{\alpha}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\delta&lt;&#x2F;span&gt; are vectors, &lt;span class=&quot;math math-inline&quot;&gt;\alpha \in {\mathbb{N}}^{k}&lt;&#x2F;span&gt; sums
over all the monomial degrees and &lt;span class=&quot;math math-inline&quot;&gt;\delta^{\alpha}&lt;&#x2F;span&gt; is the monomial
&lt;span class=&quot;math math-inline&quot;&gt;\prod_{i}\delta_{i}^{\alpha_{i}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Given a schemes &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{B}&lt;&#x2F;span&gt;, and a random
&lt;span class=&quot;math math-inline&quot;&gt;r\overset{\ \$}{\leftarrow}Z_{1} \times \cdots \times Z_{k}&lt;&#x2F;span&gt;, then
&lt;span class=&quot;math math-inline&quot;&gt;\left( \lbrack r\rbrack_{\mathcal{A}},\left( \left\lbrack g_{\alpha}(r) \right\rbrack_{\mathcal{B}} \right)_{\alpha} \right)&lt;&#x2F;span&gt;
is a &lt;em&gt;Beaver tuple&lt;&#x2F;em&gt; for &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Beaver Tuples can be used to evaluate arbitrary maps.&lt;&#x2F;p&gt;
&lt;div class=&quot;protocol numbered&quot; &gt;&lt;p&gt;&lt;strong&gt;Protocol 11.&lt;&#x2F;strong&gt; (&lt;em&gt;Beaver Evaluation&lt;&#x2F;em&gt;) Given
&lt;span class=&quot;math math-inline&quot;&gt;\lbrack z\rbrack_{\mathcal{A}}&lt;&#x2F;span&gt; and a map &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; the parties want to
compute &lt;span class=&quot;math math-inline&quot;&gt;\left\lbrack f(z) \right\rbrack_{\mathcal{B}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;A dealer provides a Beaver tuple
&lt;span class=&quot;math math-inline&quot;&gt;\left( \lbrack r\rbrack_{\mathcal{A}},\left( \left\lbrack g_{\alpha}(r) \right\rbrack_{\mathcal{B}} \right)_{\alpha} \right)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The parties compute the affine
&lt;span class=&quot;math math-inline&quot;&gt;\lbrack\delta\rbrack_{\mathcal{A}} = \lbrack z\rbrack_{\mathcal{A}} - \lbrack r\rbrack_{\mathcal{A}}&lt;&#x2F;span&gt;
locally.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The parties exchange shares and reveal &lt;span class=&quot;math math-inline&quot;&gt;\delta&lt;&#x2F;span&gt; to eachother.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The parties compute the affine
&lt;span class=&quot;math math-inline&quot;&gt;\left\lbrack f(r + \delta) \right\rbrack_{\mathcal{B}} = \sum_{\alpha}\left\lbrack g_{\alpha}(r) \right\rbrack_{\mathcal{B}} \cdot \delta^{\alpha}&lt;&#x2F;span&gt;
locally.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We now have
&lt;span class=&quot;math math-inline&quot;&gt;\left\lbrack f(r + \delta) \right\rbrack_{\mathcal{B}} = \left\lbrack f(x) \right\rbrack_{\mathcal{B}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Note that step one does not depend on &lt;span class=&quot;math math-inline&quot;&gt;\lbrack z\rbrack_{\mathcal{A}}&lt;&#x2F;span&gt;
and can be done as a preprocessing step if &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is fixed. The protocol
preserves privacy because &lt;span class=&quot;math math-inline&quot;&gt;\delta&lt;&#x2F;span&gt; by itself does not reveal anything
about &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt;. This follows from the that fact &lt;span class=&quot;math math-inline&quot;&gt;(\delta,r)&lt;&#x2F;span&gt; is a valid
additive secret sharing of &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; is never revealed.&lt;&#x2F;p&gt;
&lt;p&gt;A special case of this is a simple folklore protocol to switch schemes
and convert &lt;span class=&quot;math math-inline&quot;&gt;\lbrack z\rbrack_{\mathcal{A}}&lt;&#x2F;span&gt; to
&lt;span class=&quot;math math-inline&quot;&gt;\lbrack z\rbrack_{\mathcal{B}}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; (&lt;em&gt;Scheme switching&lt;&#x2F;em&gt;) Consider &lt;span class=&quot;math math-inline&quot;&gt;f(x) = x&lt;&#x2F;span&gt;, then
&lt;span class=&quot;math math-inline&quot;&gt;f(r + \delta) = r \cdot \delta^{0} + 1 \cdot \delta^{1}&lt;&#x2F;span&gt; so
&lt;span class=&quot;math math-inline&quot;&gt;g_{0}(r) = r&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;g_{1}(x) = 1&lt;&#x2F;span&gt;. Given &lt;span class=&quot;math math-inline&quot;&gt;r\overset{\ \$}{\leftarrow}R&lt;&#x2F;span&gt;
the Beaver tuple, leaving out constants, is
&lt;span class=&quot;math math-inline&quot;&gt;\left( \lbrack r\rbrack_{\mathcal{A}},\lbrack r\rbrack_{\mathcal{B}} \right)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Given shares &lt;span class=&quot;math math-inline&quot;&gt;\lbrack z\rbrack_{\mathcal{A}}&lt;&#x2F;span&gt; and a tuple, the parties
compute
&lt;span class=&quot;math math-inline&quot;&gt;\lbrack\delta\rbrack_{\mathcal{A}} = \lbrack z\rbrack_{\mathcal{A}} - \lbrack r\rbrack_{\mathcal{A}}&lt;&#x2F;span&gt;
and reveal &lt;span class=&quot;math math-inline&quot;&gt;\delta&lt;&#x2F;span&gt;. Each party then computes
&lt;span class=&quot;math math-inline&quot;&gt;\lbrack z\rbrack_{\mathcal{B}} = \lbrack r\rbrack_{\mathcal{B}} + \delta \cdot \lbrack 1\rbrack_{\mathcal{B}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Another special case is for multiplication, this is how it was
originally presented by Beaver:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; (&lt;em&gt;Beaver Multiplication&lt;&#x2F;em&gt;) Consider
&lt;span class=&quot;math math-inline&quot;&gt;f\left( x_{0},x_{1} \right) = x_{0} \cdot x_{1}&lt;&#x2F;span&gt; and construct&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;\begin{aligned}
f\left( r_{0} + \delta_{0},r_{1} + \delta_{1} \right) &amp;amp; = \left( r_{0} + \delta_{0} \right) \cdot \left( r_{1} + \delta_{1} \right) \\
 &amp;amp; = \left( r_{0} \cdot r_{1} \right) \cdot \delta_{0}^{0}\delta_{1}^{0} + r_{0} \cdot \delta_{0}^{0}\delta_{1}^{1} + r_{1} \cdot \delta_{0}^{1}\delta_{1}^{0} + 1 \cdot \delta_{0}^{1}\delta_{1}^{1}.
\end{aligned}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this we find the coefficient polynomials&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;\begin{aligned}
g_{00}(r) &amp;amp; = r_{0} \cdot x_{1} &amp;amp; g_{01}(r) &amp;amp; = r_{0} \\
g_{10}(r) &amp;amp; = r_{1} &amp;amp; g_{11}(r) &amp;amp; = 1.
\end{aligned}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{A} = \mathcal{B}&lt;&#x2F;span&gt; for simplicity. After removing
duplicate and constant values, the resulting Beaver tuple is
&lt;span class=&quot;math math-inline&quot;&gt;\left( \left\lbrack r_{0} \right\rbrack,\left\lbrack r_{1} \right\rbrack,\left\lbrack r_{0} \cdot r_{1} \right\rbrack \right)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Given shares of
&lt;span class=&quot;math math-inline&quot;&gt;\left\lbrack z_{0} \right\rbrack,\left\lbrack z_{1} \right\rbrack&lt;&#x2F;span&gt;,
using the protocol above the parties reveal &lt;span class=&quot;math math-inline&quot;&gt;\delta_{i} = z_{i} - r_{i}&lt;&#x2F;span&gt;
and compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;\left\lbrack z_{0} \cdot z_{1} \right\rbrack = \left\lbrack r_{0} \cdot r_{1} \right\rbrack + \left\lbrack r_{0} \right\rbrack \cdot \delta_{1} + \left\lbrack r_{1} \right\rbrack \cdot \delta_{0} + \delta_{0} \cdot \delta_{1.}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div id=&quot;refs&quot; class=&quot;references csl-bib-body hanging-indent&quot;
entry-spacing=&quot;0&quot;&gt;
&lt;div id=&quot;ref-ACD20&quot; class=&quot;csl-entry&quot;&gt;
&lt;p&gt;Abspoel, Mark, Ronald Cramer, Ivan Damgård, Daniel Escudero, Matthieu
Rambaud, Chaoping Xing, and Chen Yuan. 2020. “Asymptotically Good
Multiplicative LSSS over Galois Rings and Applications to MPC over
&lt;span class=&quot;math math-inline&quot;&gt;\mathbb{Z}&#x2F;p^k\mathbb{Z}&lt;&#x2F;span&gt;.” &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1256&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1256&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div id=&quot;ref-CCXY18&quot; class=&quot;csl-entry&quot;&gt;
&lt;p&gt;Cascudo, Ignacio, Ronald Cramer, Chaoping Xing, and Chen Yuan. 2018.
“Amortized Complexity of Information-Theoretically Secure MPC
Revisited.” Cryptology ePrint Archive, Paper 2018&#x2F;429.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;429&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;429&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Uniqueness</title>
        <published>2026-05-04T00:00:00+00:00</published>
        <updated>2026-05-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/26/uniqueness/"/>
        <id>https://2π.com/26/uniqueness/</id>
        
        <content type="html" xml:base="https://2π.com/26/uniqueness/">&lt;h1 id=&quot;probabilistic-uniqueness&quot;&gt;Probabilistic Uniqueness&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;ground-truth&quot;&gt;Ground Truth&lt;&#x2F;h2&gt;
&lt;p&gt;Consider a set of observations &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{O}&lt;&#x2F;span&gt; and a binary relation
&lt;span class=&quot;math math-inline&quot;&gt;\mathord{\sim} \subseteq \mathcal{O} \times \mathcal{O}&lt;&#x2F;span&gt;
such that &lt;span class=&quot;math math-inline&quot;&gt;a \sim b&lt;&#x2F;span&gt; means that the observations are of the same entity.
Then &lt;span class=&quot;math math-inline&quot;&gt;\sim&lt;&#x2F;span&gt; is an equivalence relation and the &lt;em&gt;unique entities&lt;&#x2F;em&gt; are
given by the quotient set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{O}&#x2F;\mathord{\sim}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;noisy-equivalence&quot;&gt;Noisy Equivalence&lt;&#x2F;h2&gt;
&lt;p&gt;Now consider we can not observe &lt;span class=&quot;math math-inline&quot;&gt;a \sim b&lt;&#x2F;span&gt; directly, but only through a
noisy channel &lt;span class=&quot;math math-inline&quot;&gt;\hat{\sim}&lt;&#x2F;span&gt;. This is modelled through the two
probabilities of &lt;em&gt;false-match-rate&lt;&#x2F;em&gt; (FMR) and &lt;em&gt;false-non-match-rate&lt;&#x2F;em&gt;
(FNMR).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;\Pr(a\mathrel{\hat{\sim}}b~|~a \nsim b)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;\Pr(a\mathrel{\hat{\nsim}}b~|~a \sim b)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;noisy-distances&quot;&gt;Noisy Distances&lt;&#x2F;h2&gt;
&lt;p&gt;Assume a distance function
&lt;span class=&quot;math math-inline&quot;&gt;d:\mathcal{O} \times \mathcal{O} \rightarrow {\mathbb{R}}_{\geq 0}&lt;&#x2F;span&gt; and
probability mass functions&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;\begin{aligned}
p_{\text{same}}(d) &amp;amp; = \Pr(d(a,b) = d~|~a \sim b) \\
p_{\text{diff}}(d) &amp;amp; = \Pr(d(a,b) = d~|~a \nsim b)
\end{aligned}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;approximate-uniqueness&quot;&gt;Approximate Uniqueness&lt;&#x2F;h2&gt;
&lt;p&gt;We can imaging candidate relations &lt;span class=&quot;math math-inline&quot;&gt;\hat{\sim}&lt;&#x2F;span&gt; and a probability
distribution over them. There are &lt;span class=&quot;math math-inline&quot;&gt;2^{n^{2}}&lt;&#x2F;span&gt; possible relations, but
not all of them are equivalence relations. The number of equivalence
relations is given by the Bell numbers &lt;span class=&quot;math math-inline&quot;&gt;B_{n}&lt;&#x2F;span&gt;. While also
super-exponential, it grows much slower. This suggest the equivalence
relation is a useful constraint.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Physics</title>
        <published>2026-05-01T00:00:00+00:00</published>
        <updated>2026-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/26/physics/"/>
        <id>https://2π.com/26/physics/</id>
        
        <content type="html" xml:base="https://2π.com/26/physics/">&lt;h1 id=&quot;physics&quot;&gt;Physics&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;qm-from-decoherence&quot;&gt;QM from Decoherence&lt;&#x2F;h2&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>List Decoding</title>
        <published>2025-10-27T00:00:00+00:00</published>
        <updated>2025-10-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/list-decoding/"/>
        <id>https://2π.com/25/list-decoding/</id>
        
        <content type="html" xml:base="https://2π.com/25/list-decoding/">&lt;h1 id=&quot;list-decoding-mds-codes&quot;&gt;List Decoding MDS Codes&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\set#1{\left\{{#1}\right\}}
\gdef\ceil#1{\left\lceil{#1}\right\rceil}
\gdef\norm#1{\left|{#1}\right|}
\gdef\setn#1{\mathcal{#1}}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\F{\mathbb{F}}
\gdef\om{\mathrm{\omega}}
\gdef\wt{\operatorname{wt}}
\gdef\d{\operatorname{d}}
\gdef\A{\operatorname{A}}
\gdef\Aut{\operatorname{Aut}}
\gdef\Iso{\operatorname{Iso}}
\gdef\L{\operatorname{L}}
\gdef\span{\operatorname{span}}
\gdef\rank{\operatorname{rank}}
\gdef\supp{\operatorname{supp}}
\gdef\n{\operatorname{n}}
\gdef\H{\operatorname{H}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ground rules:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Avoid polynomials.&lt;&#x2F;em&gt; This is a combinatorics and linear algebra game. For good measure we also avoid generator polynomials.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Avoid ratios.&lt;&#x2F;em&gt; No rate, relative distance, etc. This is a discrete problem.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Avoid Hamming balls.&lt;&#x2F;em&gt; &lt;a href=&quot;&#x2F;21&#x2F;n-sphere&quot;&gt;High dimensional spheres&lt;&#x2F;a&gt; are counter-intuitive. Hamming balls are counter-intuitive. High dimensional Hamming balls are doubly counter-intuitive.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Numerically test&lt;&#x2F;em&gt; all theorems and conjectures. We are doing exploration and conjecture testing.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Exhaustively explore&lt;&#x2F;em&gt; all instances up to practical limits. Edge cases can be very informative.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The theory is of linear codes is essentially linear algebra with extra vocabulary and an odd almost-norm: the Hamming weight. Given a finite field &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; and a linear space &lt;span class=&quot;math math-inline&quot;&gt;\F_q^n&lt;&#x2F;span&gt; (called the &lt;em&gt;ambient space&lt;&#x2F;em&gt;). Then a &lt;em&gt;linear code&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is a subspace &lt;span class=&quot;math math-inline&quot;&gt;\setn C \subseteq \F_q^n&lt;&#x2F;span&gt;. The &lt;em&gt;dimension&lt;&#x2F;em&gt; of the code is &lt;span class=&quot;math math-inline&quot;&gt;k = \dim \setn C&lt;&#x2F;span&gt;. A linear code with these &lt;span class=&quot;math math-inline&quot;&gt;q, n, k&lt;&#x2F;span&gt; parameters are is denoted a &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;preliminaries-on-mds-codes&quot;&gt;Preliminaries on MDS Codes&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;hamming-weight-and-distance&quot;&gt;Hamming Weight and Distance&lt;&#x2F;h3&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 1.&lt;&#x2F;strong&gt; (&lt;em&gt;Hamming weight&lt;&#x2F;em&gt;) Given a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v \in \F_q^n&lt;&#x2F;span&gt;, its &lt;em&gt;support&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\supp(\vec v) \subseteq [0,n)&lt;&#x2F;span&gt; is the set of indices of its non-zero coordinates,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\supp(\vec v) = \set{i \in [0,n) \mid v_i \neq 0} \text{,}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and its &lt;em&gt;weight&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\wt(\vec v) \in [0,n]&lt;&#x2F;span&gt; is the number  of non-zero coordinates, denoted as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\wt(\vec v) = \norm{\supp(\vec v)} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a subset &lt;span class=&quot;math math-inline&quot;&gt;\setn{S} \subseteq \F_q^n&lt;&#x2F;span&gt;, its &lt;em&gt;weight&lt;&#x2F;em&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\wt(\setn S) = \min_{\vec v \in \setn S \setminus \{\vec 0\}} \wt(\vec v)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and its &lt;em&gt;weight distribution&lt;&#x2F;em&gt; is the sequence for &lt;span class=&quot;math math-inline&quot;&gt;i \in [0,n]&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i(\setn S) = \norm{\set{\vec v \in \setn S \mid \wt(\vec v) = i}} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The Hamming weight is almost a norm on &lt;span class=&quot;math math-inline&quot;&gt;\F_q^n&lt;&#x2F;span&gt;, except that it does not satisfy homogeneity: instead &lt;span class=&quot;math math-inline&quot;&gt;\wt(\alpha \cdot \vec v) = \wt(\vec v)&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;\alpha \in \F_q^\times&lt;&#x2F;span&gt;. It does however satisfy the triangle inequality &lt;span class=&quot;math math-inline&quot;&gt;\wt(\vec u + \vec v) \leq \wt(\vec u) + \wt(\vec v)&lt;&#x2F;span&gt;, non-negativity &lt;span class=&quot;math math-inline&quot;&gt;\wt(\vec v) \geq 0&lt;&#x2F;span&gt; and positive definiteness &lt;span class=&quot;math math-inline&quot;&gt;\wt(\vec v) = 0&lt;&#x2F;span&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;\vec v = \vec 0&lt;&#x2F;span&gt;. Furthermore, the distance derived from it, &lt;span class=&quot;math math-inline&quot;&gt;\d(\vec u, \vec v) = \wt(\vec u - \vec v)&lt;&#x2F;span&gt; is a proper metric on &lt;span class=&quot;math math-inline&quot;&gt;\F_q^n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The Hamming weight and the ambient space are invariant under permutations of the coordinates or scalings of individual coordinates. Together these are represented by &lt;em&gt;monomial matrices&lt;&#x2F;em&gt;, essentially permutation matrices where the non-zero entries can be any non-zero field element. It can be shown that together with field automorphisms of &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; these are all automorphisms of &lt;span class=&quot;math math-inline&quot;&gt;\F_q^n&lt;&#x2F;span&gt; and the Hamming weight.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 2.&lt;&#x2F;strong&gt; (&lt;em&gt;Linear code&lt;&#x2F;em&gt;) A &lt;span class=&quot;math math-inline&quot;&gt;[n,k,d]_q&lt;&#x2F;span&gt;-&lt;em&gt;code&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is a subspace &lt;span class=&quot;math math-inline&quot;&gt;\setn C \subseteq \F_q^n&lt;&#x2F;span&gt; of &lt;em&gt;length&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, &lt;em&gt;dimension&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;, and &lt;em&gt;minimum distance&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;d = \wt(\setn C)&lt;&#x2F;span&gt;. When &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; is not specified, we simply write &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-code. The members of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; are called &lt;em&gt;codewords&lt;&#x2F;em&gt;. A &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; can be represented as the row space of a &lt;em&gt;generator matrix&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\mat G \in \F_q^{k \times n}&lt;&#x2F;span&gt; of rank &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\setn C = \set{\vec m \cdot \mat G \mid \vec m \in \F_q^k} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A generator matrix in the form &lt;span class=&quot;math math-inline&quot;&gt;\mat G = [\mat I_k \mid \mat P]&lt;&#x2F;span&gt; is said to be in &lt;em&gt;systematic form&lt;&#x2F;em&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\mat P&lt;&#x2F;span&gt; is the &lt;em&gt;parity matrix&lt;&#x2F;em&gt; and the first &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; coordinates an &lt;em&gt;information-set&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;. The &lt;em&gt;dual&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is the &lt;span class=&quot;math math-inline&quot;&gt;[n,n-k]_q&lt;&#x2F;span&gt; code &lt;span class=&quot;math math-inline&quot;&gt;\setn C^\perp&lt;&#x2F;span&gt;, a generator of the dual code is called a &lt;em&gt;parity-check matrix&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Two codes &lt;span class=&quot;math math-inline&quot;&gt;\setn C_1, \setn C_2 \subseteq \F_q^n&lt;&#x2F;span&gt; are &lt;em&gt;monomially equivalent&lt;&#x2F;em&gt; if there exists a monomial matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat M \in \F_q^{n \times n}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\setn C_2 = \setn C_1 \cdot \mat M = \set{\vec c \cdot \mat M \mid \vec c \in \setn C_1}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In coding theory, one refers only to the set of codewords without specifying &lt;em&gt;how&lt;&#x2F;em&gt; messages are encoded into codewords. In other words, the encoding map &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{enc} : \setn M \to \setn C&lt;&#x2F;span&gt; is not specified and there are many valid encodings for the same code. Typically encoding is done through multiplication by a generator matrix.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m being loose here with the choice of coordinates and the definition of information set. For the codes we will consider, this doesn&#x27;t matter.&lt;&#x2F;p&gt;
&lt;p&gt;Given any invertible matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat M \in \F_q^{k \times k}&lt;&#x2F;span&gt;, the generator matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat G&amp;#39; = \mat M \cdot \mat G&lt;&#x2F;span&gt; generates the same code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;. Similarly, given a matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat M \in \F_q^{n \times n}&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;\mat G&amp;#39; = \mat G \cdot \mat M&lt;&#x2F;span&gt; generates the code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&amp;#39; = \setn C \cdot \mat M&lt;&#x2F;span&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt; is a monomial matrix, then &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\setn C&amp;#39;&lt;&#x2F;span&gt; are monomially equivalent codes. Monomial equivalence preserves all the aspects of a code we care about here: dimension, minimum distance, weight distribution, list decoding size, etc.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 2.&lt;&#x2F;strong&gt; (&lt;em&gt;MacWilliam equations&lt;&#x2F;em&gt;) Given &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; we have have the following relations between its weight distribution and that of its dual code &lt;span class=&quot;math math-inline&quot;&gt;\setn C^\perp&lt;&#x2F;span&gt;, for &lt;span class=&quot;math math-inline&quot;&gt;i \in [0,n]&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{j \in [0,n-i]} \binom{n - j}{i} \A_j(\setn C) = q^{k-i} \sum_{j \in [0, i]} \binom{n - j}{n-i} \A_j(\setn C^\perp) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;We know that by definition &lt;span class=&quot;math math-inline&quot;&gt;0 \leq \A_i \leq \binom{n}{i} (q-1)^{i}&lt;&#x2F;span&gt;. We also have &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i \in [0,n]} \A_i(\setn C) = q^k&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i \in [0,n]} \A_i(\setn C^\perp) = q^{n-k}&lt;&#x2F;span&gt;. Together with the MacWilliams equations this forms an integer linear program to bound the weight distribution of any &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; code.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mds-codes&quot;&gt;MDS Codes&lt;&#x2F;h3&gt;
&lt;p&gt;A well known theorem in coding theory is the Singleton bound, which limits the minimum distance &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; of a code for given &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 2.&lt;&#x2F;strong&gt; (&lt;em&gt;Singleton bound&lt;&#x2F;em&gt;) Given &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
d = \wt(\setn C) \leq n - k + 1 \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Codes that achieve this bound with equality are called &lt;em&gt;maximum distance separable (MDS) codes&lt;&#x2F;em&gt;. There are various equivalent definitions of MDS codes, we list some of them here:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 4.&lt;&#x2F;strong&gt; Given a &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; the following are equivalent:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is MDS.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\setn C^\perp&lt;&#x2F;span&gt; is MDS.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\wt(\setn C) = d = n - k + 1&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Any set of &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; coordinates is an information set.&lt;&#x2F;li&gt;
&lt;li&gt;Any &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; columns of a generator matrix of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; are linearly independent.&lt;&#x2F;li&gt;
&lt;li&gt;Every parity matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat P&lt;&#x2F;span&gt; is &lt;em&gt;superregular&lt;&#x2F;em&gt;, i.e., all square submatrices of &lt;span class=&quot;math math-inline&quot;&gt;\mat A&lt;&#x2F;span&gt; are invertible.&lt;&#x2F;li&gt;
&lt;li&gt;For every &lt;span class=&quot;math math-inline&quot;&gt;\setn S \subseteq [0,n)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn S} = d&lt;&#x2F;span&gt; there is a codeword &lt;span class=&quot;math math-inline&quot;&gt;\vec c \in \setn C&lt;&#x2F;span&gt; with support &lt;span class=&quot;math math-inline&quot;&gt;\supp(\vec c) = \setn S&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;For every &lt;span class=&quot;math math-inline&quot;&gt;\setn S \subseteq [0,n)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn S} = k&lt;&#x2F;span&gt; the projection map &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\setn S} : \setn C \to \F_q^k&lt;&#x2F;span&gt; defined as &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\setn S}(\vec c) = (c_i)_{i \in \setn S}&lt;&#x2F;span&gt; is surjective.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; A matrix that is superregular is also called an &lt;em&gt;MDS matrix&lt;&#x2F;em&gt;, especially in the cryptographic literature where they are used as diffusion layers in block ciphers and hash functions (e.g. AES, Poseidon). An MDS code can be constructed from a superregular matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat P&lt;&#x2F;span&gt; as the image of &lt;span class=&quot;math math-inline&quot;&gt;[\,\mat I \mid \mat P\,]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2403.10372
https:&#x2F;&#x2F;greggkelly.com&#x2F;VANDERMONDE.html
https:&#x2F;&#x2F;math.stackexchange.com&#x2F;questions&#x2F;1781867&#x2F;rank-of-square-matrix-a-with-a-ij-lambda-jp-i-where-p-i-is-an-incre&lt;&#x2F;p&gt;
&lt;p&gt;, which is true only for non-zero evaluation points over the reals, but not over finite fields. See e.g.:&lt;&#x2F;p&gt;
&lt;p&gt;Superregular matrices: https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2507.08809&lt;&#x2F;p&gt;
&lt;p&gt;K. C. Gupta, S. K. Pandey, I. G. Ray, S. Samanta, Cryptographically significant mds matrices over finite fields: A brief survey and some generalized results, Advances in Mathematics of Communications 13 (4) (2019) 779–843.
doi:10.3934&#x2F;amc.2019045.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; MDS codes not only all have the same maximum distance, they have their complete weight distribution in common (see e.g. Huffman-Pless lemma 7.4.1 p. 262):&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 5.&lt;&#x2F;strong&gt; (&lt;em&gt;MDS weight distribution&lt;&#x2F;em&gt;) The weight distribution of an &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; MDS code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i(\setn C) =  \begin{cases}
1 &amp;amp; \text{if } i = 0 \\
\binom{n}{i} (q-1)\sum_{j\in[0, i - n + k]} (-1)^j \binom{i-1}{j} q^{i - n + k - j} &amp;amp; \text{otherwise.} \\
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;It follows from the MDS property, and also from the summation range, that &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn C) = 0&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;0 &amp;lt; i &amp;lt; n - k&lt;&#x2F;span&gt;. The first nonzero value is &lt;span class=&quot;math math-inline&quot;&gt;\A_{n-k}(\setn C) = \binom{n}{k+1} (q-1)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;MDS conjecture&lt;&#x2F;em&gt;, which bounds the size of an MDS code for a given &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Conjecture 5.&lt;&#x2F;strong&gt; (&lt;em&gt;MDS conjecture&lt;&#x2F;em&gt;) Given an &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; MDS code then either&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;k \in \{0, 1, n - 1, n\}&lt;&#x2F;span&gt;, or&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;n \leq q + 1&lt;&#x2F;span&gt;, or&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; is even, &lt;span class=&quot;math math-inline&quot;&gt;n = q + 2&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;k \in \{3, q - 1\}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Evidence.&lt;&#x2F;em&gt; The conjecture has been proven for many cases, in particular for all prime fields, and for &lt;span class=&quot;math math-inline&quot;&gt;q = p^h&lt;&#x2F;span&gt; with prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;k &amp;lt; p&lt;&#x2F;span&gt;. For an overview see, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.4171&#x2F;emss&#x2F;33&quot;&gt;BL19&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;The MDS Conjecture can equally be restated as a conjecture on the existence of superregular matrices of dimension &lt;span class=&quot;math math-inline&quot;&gt;k \times (n - k)&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The first case &lt;span class=&quot;math math-inline&quot;&gt;k \in \{0, 1, n - 1, n\}&lt;&#x2F;span&gt; are trivial codes: the empty code, the full space, the repetition code and its dual the single-parity check code.&lt;&#x2F;p&gt;
&lt;p&gt;We will now look at a class of codes that achieves both the Singleton bound and the entire range allowed by &lt;span class=&quot;math math-inline&quot;&gt;n \leq q + 1&lt;&#x2F;span&gt;: Reed-Solomon codes. In fact, Reed-Solomon codes are the only codes that do so.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reed-solomon-codes&quot;&gt;Reed-Solomon Codes&lt;&#x2F;h3&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 6.&lt;&#x2F;strong&gt; (&lt;em&gt;Reed-Solomon Code&lt;&#x2F;em&gt;) A &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-&lt;em&gt;Reed-Solomon (RS) code&lt;&#x2F;em&gt; is defined by a sequence of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; distinct &lt;em&gt;evaluation points&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\vec x \in \F_q^n&lt;&#x2F;span&gt;, the code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is generated by the &lt;em&gt;Vandermonde matrix&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; \cdots &amp;amp; 1 \\
x_0 &amp;amp; x_1 &amp;amp; x_2 &amp;amp; \cdots &amp;amp; x_{n-1} \\
x_0^2 &amp;amp; x_1^2 &amp;amp; x_2^2 &amp;amp; \cdots &amp;amp; x_{n-1}^2 \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \\
x_0^{k-1} &amp;amp; x_1^{k-1} &amp;amp; x_2^{k-1} &amp;amp; \cdots &amp;amp; x_{n-1}^{k-1} \\
\end{bmatrix} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; It is sometimes claimed that a Vandermonde matrix is superregular (or rather &quot;is MDS&quot;). While a Vandermonde matrix generates MDS codes, it is only superregular under specific conditions (e.g. over the reals when the evaluation points are positive). In particular Vandermonde matrices are not superregular when the evaluation points are a multiplicative subgroup of a finite field, as is common in practice.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-Reed-Solomon code is essentially the evaluation of all polynomials of degree less than &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; at the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; distinct points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;. Any subset of &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; such evaluation points produces a unique polynomial, so any &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; columns of the generator matrix are linearly independent. By lemma 4 this means that Reed-Solomon codes are MDS.&lt;&#x2F;p&gt;
&lt;p&gt;The above definition of Reed-Solomon codes can be extended by adding &lt;em&gt;the point at infinity&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\infty&lt;&#x2F;span&gt; to the evaluation points, which corresponds to reading off the &lt;span class=&quot;math math-inline&quot;&gt;x^{k-1}&lt;&#x2F;span&gt; coefficient in much the same way that evaluation at &lt;span class=&quot;math math-inline&quot;&gt;x=0&lt;&#x2F;span&gt; is reading off the &lt;span class=&quot;math math-inline&quot;&gt;x^0&lt;&#x2F;span&gt; coefficient. In other words, its column looks like &lt;span class=&quot;math math-inline&quot;&gt;[0, 0, \dots, 0, 1]^\top&lt;&#x2F;span&gt;. This allows RS codes with &lt;span class=&quot;math math-inline&quot;&gt;n = q + 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Extended RS codes are not closed under monomial equivalence: Scaling a column by &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; produces &lt;span class=&quot;math math-inline&quot;&gt;[\alpha, \alpha \cdot x, \alpha \cdot x^2, \dots]^\top&lt;&#x2F;span&gt;. We can fix this by assigning scaling values &lt;span class=&quot;math math-inline&quot;&gt;\vec a \in (\F_q^{\times})^n&lt;&#x2F;span&gt; to each evaluation point, producing a &lt;em&gt;generalized Reed-Solomon code&lt;&#x2F;em&gt;(GRS) generated by a &lt;em&gt;generalized Vandermonde matrix&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\mat G_{ij} = \alpha_j \cdot x_j^{i}&lt;&#x2F;span&gt;, with the column for the point at infinity similarly scaled.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Theorem 7.&lt;&#x2F;strong&gt; An &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; MDS code is a GRS code if and only if the parity matrix is a &lt;em&gt;generalized Cauchy matrix&lt;&#x2F;em&gt; with entries&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat P_{ij} = \frac{u_i \, v_j}{x_i - y_j} \text{,}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with &lt;span class=&quot;math math-inline&quot;&gt;x_i, y_j \in \F_q \cup \{\infty\}&lt;&#x2F;span&gt; all distinct and &lt;span class=&quot;math math-inline&quot;&gt;u_i, v_j \in \F_q^{\times}&lt;&#x2F;span&gt;. At most one of the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;y_j&lt;&#x2F;span&gt; can be &lt;span class=&quot;math math-inline&quot;&gt;\infty&lt;&#x2F;span&gt;, for which the row&#x2F;column will be &lt;span class=&quot;math math-inline&quot;&gt;\mat P_{ij} = u_i \, v_j&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;It is known that square Cauchy matrices are invertible, and it is easy to see that all its submatrices are also Cauchy matrices, so all Cauchy matrices are superregular. This is another way to see that Reed-Solomon codes are MDS.&lt;&#x2F;p&gt;
&lt;p&gt;An important result is that GRS codes are essentially the &lt;em&gt;only&lt;&#x2F;em&gt; MDS codes at the boundary of the MDS conjecture, with a few exceptions:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Conjecture 8.&lt;&#x2F;strong&gt; (&lt;em&gt;GRS Conjecture.&lt;&#x2F;em&gt;) A &lt;span class=&quot;math math-inline&quot;&gt;[n, k]_q&lt;&#x2F;span&gt; MDS code with &lt;span class=&quot;math math-inline&quot;&gt;n = q + 1&lt;&#x2F;span&gt; is a GRS code, except for the following cases:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;[10, 5]_9&lt;&#x2F;span&gt;, the Casse-Glynn code,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;q=2^h&lt;&#x2F;span&gt; and
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;k \in \{3, q-1\}&lt;&#x2F;span&gt;, the hyperoval codes and their duals,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;k \in \{4, q-3\}&lt;&#x2F;span&gt; and  &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt; odd, the Glynn codes and their duals.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Evidence.&lt;&#x2F;em&gt; The conjecture has been proven in many cases, see [BL19]. In particular, it holds for&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;The GRS conjecture can equally be stated (with equivalent exceptions) as a conjecture that all supperregular matrices of dimension &lt;span class=&quot;math math-inline&quot;&gt;k \times (q - k + 1 )&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; are Cauchy, or that all &lt;span class=&quot;math math-inline&quot;&gt;q+1&lt;&#x2F;span&gt; point arcs in the projective space &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{PG}(k-1, q)&lt;&#x2F;span&gt; are normal rational curves. A similar theorem, that extends below the MDS boundary is due to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1109&#x2F;18.45291&quot;&gt;RL89&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Theorem 9.&lt;&#x2F;strong&gt; (&lt;em&gt;Roth-Lempel&lt;&#x2F;em&gt;) A &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; MDS code is GRS if &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; is odd, &lt;span class=&quot;math math-inline&quot;&gt;3 \leq k \leq q-1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;n \geq  k + q - \ceil{\frac{\sqrt{q} + 1}{4}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The Hyperoval codes for &lt;span class=&quot;math math-inline&quot;&gt;q = 2^h&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;k=3&lt;&#x2F;span&gt; come from the addition of an extra &lt;span class=&quot;math math-inline&quot;&gt;[0, 1, 0]^\top&lt;&#x2F;span&gt; column to the RS code that only works in this specific case. This can be seen as a coefficient-selection evaluation much like &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\infty&lt;&#x2F;span&gt;, selecting the &lt;span class=&quot;math math-inline&quot;&gt;x^1&lt;&#x2F;span&gt; coefficient. So in that sense the exception is not too far from being a Reed-Solomon code, but unlike the point at infinity, there is no clean interpretation in projective geometry. The other exception, &lt;span class=&quot;math math-inline&quot;&gt;k=q-1&lt;&#x2F;span&gt; are their duals. This extra point allows them to grow to &lt;span class=&quot;math math-inline&quot;&gt;n = q +2&lt;&#x2F;span&gt;, which explains the exception to the MDS Conjecture.&lt;&#x2F;p&gt;
&lt;p&gt;The other exception is a single code the Casse-Glynn code:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 8.&lt;&#x2F;strong&gt; (&lt;em&gt;Casse-Glynn&lt;&#x2F;em&gt;) The following is a &lt;span class=&quot;math math-inline&quot;&gt;[10,5]_9&lt;&#x2F;span&gt; MDS code that is not a GRS code, given by the generator matrix&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; \delta^7 &amp;amp; \delta^5 &amp;amp; 1 &amp;amp; 1 &amp;amp; \delta^5 \\
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; \delta^5 &amp;amp; \delta^7 &amp;amp; \delta^5 &amp;amp; 1 &amp;amp; 1 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 &amp;amp; \delta^5 &amp;amp; \delta^7 &amp;amp; \delta^5 &amp;amp; 1 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 1 &amp;amp; 1 &amp;amp; \delta^5 &amp;amp; \delta^7 &amp;amp; \delta^5 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 &amp;amp; \delta^5 &amp;amp; 1 &amp;amp; 1 &amp;amp; \delta^5 &amp;amp; \delta^7 \\
\end{bmatrix}\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\delta&lt;&#x2F;span&gt; is a root of  &lt;span class=&quot;math math-inline&quot;&gt;\delta^2 + 2 \, \delta + 2&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The binary field exception we already discussed. The main proof is through Roth–Lempel (1989), who showed that any &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; MDS code with &lt;span class=&quot;math math-inline&quot;&gt;n = q + 1&lt;&#x2F;span&gt; is equivalent to an RS code. It is constructive: bring the generator matrix to the form &lt;span class=&quot;math math-inline&quot;&gt;[\mat I_k \mid \mat A]&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;\mat A&lt;&#x2F;span&gt; will be a &lt;em&gt;generalized Cauchy matrix&lt;&#x2F;em&gt; with entries &lt;span class=&quot;math math-inline&quot;&gt;A_{i,j} = \frac{u_i\,v_i}{x_i - y_j}&lt;&#x2F;span&gt; for distinct &lt;span class=&quot;math math-inline&quot;&gt;x_i, y_j \in \F_q&lt;&#x2F;span&gt; and nonzero &lt;span class=&quot;math math-inline&quot;&gt;u_i, v_i \in \F_q^{\times}&lt;&#x2F;span&gt;. Roth-Seroussi (1985) showed these generators correspond to generalized Reed-Solomon codes, which in turn are monomially equivalent to Reed-Solomon codes.&lt;&#x2F;p&gt;
&lt;p&gt;But the result holds only &lt;em&gt;at&lt;&#x2F;em&gt; the boundary of the MDS bound. For &lt;span class=&quot;math math-inline&quot;&gt;n &amp;lt; q + 1&lt;&#x2F;span&gt; there are codes known not to be equivalent to Reed-Solomon codes. A concrete example is the &lt;span class=&quot;math math-inline&quot;&gt;[6,3]_7&lt;&#x2F;span&gt; MDS code generated by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 4 &amp;amp; 2 &amp;amp; 3 \\
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 2 &amp;amp; 2 &amp;amp; 1 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 4 &amp;amp; 6 &amp;amp; 5 \\
\end{bmatrix}\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Do non-RS MDS codes behave materially different?&lt;&#x2F;p&gt;
&lt;p&gt;Higher order MDS codes:&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2111.03210v2&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2310.12888&lt;&#x2F;p&gt;
&lt;h3 id=&quot;superregular-matrices&quot;&gt;Superregular matrices&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.aimsciences.org&#x2F;article&#x2F;doi&#x2F;10.3934&#x2F;amc.2019045&lt;&#x2F;p&gt;
&lt;h3 id=&quot;list-decoding&quot;&gt;List Decoding&lt;&#x2F;h3&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 2.&lt;&#x2F;strong&gt; Given an &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; and a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_q^n&lt;&#x2F;span&gt;, the &lt;em&gt;coset&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; with &lt;em&gt;offset&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; is the affine subspace&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec r + \setn C = \set{\vec r + \vec c \mid \vec c \in \setn C} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;list decoding size&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; is, for &lt;span class=&quot;math math-inline&quot;&gt;i \in [0,n]&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\L_i(\setn C, \vec r) = \sum_{j \in [0,i]} \A_j(\vec r + \setn C) \text{,}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and the &lt;em&gt;list decoding bound&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is, for &lt;span class=&quot;math math-inline&quot;&gt;i \in [0,n]&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\L_i(\setn C) = \max_{\vec r \in \F_q^n} \L_i(\setn C, \vec r) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Let&#x27;s quickly check that this definition matches the usual distance-to-code one:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\L_i(\setn C, \vec r)
&amp;amp;= |\set{\vec c \in \setn C \mid \d(\vec r, \vec c) \leq i}| \\
&amp;amp;= \sum_{j \in [0,i]}  |\set{\vec c \in \setn C \mid \wt(\vec r - \vec c) = i}| \\
&amp;amp;= \sum_{j \in [0,i]} |\set{\vec v \in (\vec r + \setn C) \mid \wt(\vec v) = i}| 
\text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We are interested in computing or bounding &lt;span class=&quot;math math-inline&quot;&gt;\L_i(\setn C)&lt;&#x2F;span&gt; for a given code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;. To do this we need to understand the weight distribution of all cosets &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\vec r + \setn C)&lt;&#x2F;span&gt;. We have already seen the weight distribution of the trivial coset &lt;span class=&quot;math math-inline&quot;&gt;\vec 0 + \setn C = \setn C&lt;&#x2F;span&gt;. The trivial coset can be computed from &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; alone, but generally the weight distributions of the cosets depends on the code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; itself, we will see an example of this in the numerical experiments.&lt;&#x2F;p&gt;
&lt;p&gt;But before we get to computation, there is more that can be done on the theory front. Consider this explicitly solvable coset:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 5.&lt;&#x2F;strong&gt; Given a &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; MDS code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; and a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_q^n&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\setn D = \span(\vec r + \setn C)&lt;&#x2F;span&gt; is an &lt;span class=&quot;math math-inline&quot;&gt;[n,k+1]_q&lt;&#x2F;span&gt; MDS code, we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i(\vec r + \setn C) = \begin{cases}
0 &amp;amp; \text{if } i &amp;lt; n - k \\
\A_i(\setn C) + (-1)^{n - k + i} \binom{n}{i} \binom{i-1}{n - k  - 1} &amp;amp; \text{if } i \geq n - k  \text{.}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; By Huffman-Pless lemma 7.5.1.ii we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i(\vec r + \setn C) = \frac{\A_i(\setn D) - \A_i(\setn C)}{q - 1} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;span class=&quot;math math-inline&quot;&gt;i = 0&lt;&#x2F;span&gt; both &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn D)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn C)&lt;&#x2F;span&gt; are one and cancel out. For &lt;span class=&quot;math math-inline&quot;&gt;i &amp;lt; n - k&lt;&#x2F;span&gt; both &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn D)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn C)&lt;&#x2F;span&gt; are zero. For &lt;span class=&quot;math math-inline&quot;&gt;i = n - k&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn D) = \binom{n}{k} (q-1)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn C) = 0&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;i &amp;gt; n - k&lt;&#x2F;span&gt; we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\binom{n}{i} (q-1)\sum_{j\in[0, i - n + k]} (-1)^j \binom{i-1}{j} q^{i - n + k - j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\footnotesize
\begin{align*}
&amp;amp;\frac{\A_i(\setn D) - \A_i(\setn C)}{q-1} \\
&amp;amp;= \binom{n}{i} \p {\sum_{j\in [0,i - n + k]} (-1)^j \binom{i-1}{j} q^{i - n+k - j} - 
\!\!\!\sum_{j\in[0, i - n +k -1]}\!\!\!\! (-1)^j \binom{i-1}{j} q^{i - n+k -1 - j}} \\
&amp;amp;= \binom{n}{i} \p{\p{q - 1}\sum_{j=0}^{i - d} (-1)^j \binom{i-1}{j} q^{i - d - j} + (-1)^{i - n + k} \binom{i-1}{i - d + 1}} \\
&amp;amp;= \A_i(\setn C) + (-1)^{n - k + i} \binom{n}{i} \binom{i-1}{n - k - 1} \text{.} \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;In particular for an non-extended RS code with &lt;span class=&quot;math math-inline&quot;&gt;k &amp;lt; n&lt;&#x2F;span&gt; such a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; must exist. &lt;strong&gt;Question:&lt;&#x2F;strong&gt; How many such vectors exist?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; What are the conditions for this span-extension to exist? It doesn&#x27;t seem to hold in general for MDS.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;computing-coset-weight-distributions&quot;&gt;Computing coset weight distributions&lt;&#x2F;h2&gt;
&lt;p&gt;Given a subspace &lt;span class=&quot;math math-inline&quot;&gt;\setn C \subseteq \F_q^n&lt;&#x2F;span&gt; of dimension &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; we want to efficiently compute the weight distribution of all cosets &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\vec r + \setn C)&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_q^n&lt;&#x2F;span&gt;. To reduce the search space we first note that for any &lt;span class=&quot;math math-inline&quot;&gt;\vec d \in \setn C&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;\vec r + \setn C = (\vec r + \vec d) + \setn C&lt;&#x2F;span&gt;. For any &lt;span class=&quot;math math-inline&quot;&gt;\alpha \in \F_q^\times&lt;&#x2F;span&gt; we also have &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\alpha \cdot \vec r + \setn C) = \A_i(\vec r + \setn C)&lt;&#x2F;span&gt;. This follows from &lt;span class=&quot;math math-inline&quot;&gt;\wt(\alpha \cdot \vec x) = \wt(\vec x)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\alpha(\vec r + \setn C) = \alpha \cdot \vec r + \setn C&lt;&#x2F;span&gt; (see also Huffman-Pless lemma 7.5.1.i).&lt;&#x2F;p&gt;
&lt;p&gt;Under these symmetries, each coset class can be assigned a unique representative offset &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \setn C^\perp&lt;&#x2F;span&gt; with first non-zero coordinate equal to &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To iterate through the reduced search space we first construct a basis for &lt;span class=&quot;math math-inline&quot;&gt;\setn C^\perp&lt;&#x2F;span&gt; of the form &lt;span class=&quot;math math-inline&quot;&gt;[\mat I_r \mid \mat H&amp;#39;]&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;r = \dim \setn C^\perp = n - k&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mat H&amp;#39; \in \F_q^{r \times k}&lt;&#x2F;span&gt;. Then we iterate through all vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec s \in \F_q^r&lt;&#x2F;span&gt; with first non-zero coordinate equal to &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;, and construct the corresponding coset offset as &lt;span class=&quot;math math-inline&quot;&gt;\vec r = [\vec s \mid \mat H&amp;#39; \cdot \vec s]&lt;&#x2F;span&gt;. In total, we need to consider &lt;span class=&quot;math math-inline&quot;&gt;1 + (q^r - 1)&#x2F;(q - 1)&lt;&#x2F;span&gt; cosets, where the &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; accounts for the zero coset &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; itself.&lt;&#x2F;p&gt;
&lt;p&gt;Once we have a specific offset &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt;, we need to compute the weight distribution &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\vec r + \setn C)&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;\dim C = 1&lt;&#x2F;span&gt; we can do this efficiently by observing that &lt;span class=&quot;math math-inline&quot;&gt;\vec r + \setn C = \{\vec r + \alpha \cdot \vec c \mid \alpha \in \F_q\}&lt;&#x2F;span&gt;. Let &lt;span class=&quot;math math-inline&quot;&gt;\vec v = \vec r + \alpha \cdot \vec c&lt;&#x2F;span&gt;, then for each coordinate &lt;span class=&quot;math math-inline&quot;&gt;v_j = r_j + \alpha \cdot c_j&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;v_j = r_j&lt;&#x2F;span&gt; if &lt;span class=&quot;math math-inline&quot;&gt;c_j= 0&lt;&#x2F;span&gt; and otherwise &lt;span class=&quot;math math-inline&quot;&gt;v_j = 0&lt;&#x2F;span&gt; when &lt;span class=&quot;math math-inline&quot;&gt;\alpha = \alpha_j = -r_j &#x2F; c_j&lt;&#x2F;span&gt;. So we first count the weight of &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; on the coordinates where &lt;span class=&quot;math math-inline&quot;&gt;c_j = 0&lt;&#x2F;span&gt;, call this &lt;span class=&quot;math math-inline&quot;&gt;w_0&lt;&#x2F;span&gt;. Then we compute &lt;span class=&quot;math math-inline&quot;&gt;\alpha_j&lt;&#x2F;span&gt; for the remaining coordinates and count repetitions. This takes &lt;span class=&quot;math math-inline&quot;&gt;O(n + q)&lt;&#x2F;span&gt; time + &lt;span class=&quot;math math-inline&quot;&gt;O(q)&lt;&#x2F;span&gt; space (or &lt;span class=&quot;math math-inline&quot;&gt;O(n \log n)&lt;&#x2F;span&gt; time and &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; space).&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\dim \setn C = k &amp;gt; 1&lt;&#x2F;span&gt; we can use the above method as the base case in a recursive algorithm. We pick a basis vector &lt;span class=&quot;math math-inline&quot;&gt;\vec c \in \setn C&lt;&#x2F;span&gt; and construct the &lt;span class=&quot;math math-inline&quot;&gt;k-1&lt;&#x2F;span&gt; dimensional subspace &lt;span class=&quot;math math-inline&quot;&gt;\setn C&amp;#39;&lt;&#x2F;span&gt; of the remaining basis vectors. Then we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A_i(\vec r + \setn C) = \sum_{\alpha \in \F_q} A_i((\vec r + \alpha \cdot \vec c) + \setn C&amp;#39;) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then there are small practical optimizations: We can pick a basis of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; of the form &lt;span class=&quot;math math-inline&quot;&gt;[\mat I_k \mid \mat C]&lt;&#x2F;span&gt; so the first &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; coordinates are trivial. Then instead of iterating through &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; and computing &lt;span class=&quot;math math-inline&quot;&gt;\vec r + \alpha \cdot \vec c&lt;&#x2F;span&gt; we can initialize an accumulator with &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; and repeatedly add &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt; to it &lt;span class=&quot;math math-inline&quot;&gt;q - 1&lt;&#x2F;span&gt; times. Finally we can precompute &lt;span class=&quot;math math-inline&quot;&gt;c_j^{-1}&lt;&#x2F;span&gt; for the last dimension.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;numerical-experiments&quot;&gt;Numerical experiments&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Define RS codes.&lt;&#x2F;p&gt;
&lt;p&gt;For every prime &lt;span class=&quot;math math-inline&quot;&gt;q \in \{2,3,5,7,\dots\}&lt;&#x2F;span&gt; we construct all &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt; Reed-Solomon codes with &lt;span class=&quot;math math-inline&quot;&gt;n \in[1,q)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;k \in [1,n-1]&lt;&#x2F;span&gt; up to permutation of the coordinates. For each code we compute the weight distribution of all cosets using the method above. As it turns out, there are only a few distinct coset weight distributions per code, and often many cosets share the same weight distribution. We record the distinct coset weight distributions and their frequencies.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO.&lt;&#x2F;strong&gt; Also do for &lt;span class=&quot;math math-inline&quot;&gt;n = q&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The first question we ask is whether all Reed-Solomon codes with the same parameters &lt;span class=&quot;math math-inline&quot;&gt;q,n,k&lt;&#x2F;span&gt; have identical coset weight distributions. Despite &lt;span class=&quot;math math-inline&quot;&gt;\binom{q}{n}&lt;&#x2F;span&gt; unique evaluation point sets up to permuation, most produce identical spectra. But this breaks down earliest at &lt;span class=&quot;math math-inline&quot;&gt;[6,2]_13&lt;&#x2F;span&gt; where four distinct spectra exists.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; The weight distributions and the maximum list size of a &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-Reed-Solomon code depends on the choice of evaluation points.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; We meet the first example at &lt;span class=&quot;math math-inline&quot;&gt;[6,2]_{13}&lt;&#x2F;span&gt;, where the frequencies of coset weight distributions differ, but we need to look further to &lt;span class=&quot;math math-inline&quot;&gt;[7,2]_{13}&lt;&#x2F;span&gt; to see differences in the maximum list size. Take evaluation point sets&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\vec x_1 &amp;amp;= [0, 1, 2, 3, 4, 5, 6] \\
\vec x_2 &amp;amp;= [0, 1, 2, 3, 4, 5, 9] \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The resulting codes &lt;span class=&quot;math math-inline&quot;&gt;[7,2]_13&lt;&#x2F;span&gt;-RS codes &lt;span class=&quot;math math-inline&quot;&gt;\setn C_1, \setn C_2&lt;&#x2F;span&gt; have the following maximum distances&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\L(\setn C_1) &amp;amp;= [1, 1, 1, 2, 6, 21, 85, 169] \\
\L(\setn C_2) &amp;amp;= [1, 1, 1, 2, 5, 21, 85, 169] \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and the following coset weight distributions&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                  C₁     C₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [1, 0, 0, 0, 0,  0, 84, 84]:     1      1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 1, 0, 0, 0,  6, 73, 89]:     7      7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 1, 0, 1,  8, 67, 92]:   105    105&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 1, 0, 0, 11, 64, 93]:   147    147&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 2, 0,  9, 65, 93]:    70     70&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 1, 3,  6, 66, 93]:    72     56&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 1, 2,  9, 63, 94]:  1044   1092&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 1, 1, 12, 60, 95]:  2561   2513&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 1, 0, 15, 57, 96]:  1223   1239&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 0, 6,  3, 67, 93]:     2      0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 0, 5,  6, 64, 94]:    84    105&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 0, 4,  9, 61, 95]:  1596   1533&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 0, 3, 12, 58, 96]:  7259   7357&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 0, 2, 15, 55, 97]: 10862  10766&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 0, 1, 18, 52, 98]:  5193   5250&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  [0, 0, 0, 0, 0, 21, 49, 99]:   716    701&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We observe that the coset with weight &lt;span class=&quot;math math-inline&quot;&gt;6&lt;&#x2F;span&gt; at distance &lt;span class=&quot;math math-inline&quot;&gt;4&lt;&#x2F;span&gt; only occurs for &lt;span class=&quot;math math-inline&quot;&gt;\setn C_1&lt;&#x2F;span&gt;, leading to the difference in &lt;span class=&quot;math math-inline&quot;&gt;\L_4&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;Despite this, there appear only very few distinct weight distribution classes for a given &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;, for &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-RS codes up to &lt;span class=&quot;math math-inline&quot;&gt;q \leq 13&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;n \leq 8&lt;&#x2F;span&gt;, only the following have more than one class, with the given frequencies per class (no particular order):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
[6,2]_{13} &amp;amp;: [52, 104, 312,1248] \\
[6,3]_{13} &amp;amp;: [52, 104, 312, 1248] \\[1em]
[7,2]_{13} &amp;amp;: [78, 182, 364, 546, 546] \\
[7,3]_{13} &amp;amp;: [78, 182, 364, 546, 546] \\
[7,4]_{13} &amp;amp;: [78, 182, 546, 910] \\[1em]
[8,2]_{13} &amp;amp;: [39, 78, 234, 468, 468] \\
[8,3]_{13} &amp;amp;: [39, 78, 234, 468, 468] \\
[8,4]_{13} &amp;amp;: [39, 78, 234, 468, 468] \\
[8,5]_{13} &amp;amp;: [39, 78, 234, 468, 468] \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Observe that the class frequencies are identical for each &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, except for &lt;span class=&quot;math math-inline&quot;&gt;[7,4]_q&lt;&#x2F;span&gt; where it appears two classes have collapsed into one.&lt;&#x2F;p&gt;
&lt;p&gt;Generally we find that there is a lot more symmetry left to exploit. There are much few coset classes then what we identified, and much fewer code weight distrbutions then what is possible.&lt;&#x2F;p&gt;
&lt;p&gt;It is computationally demanding to explore this further, so instead we will focus on a particular set of evaluation points: the multiplicative cosets of subgroups of &lt;span class=&quot;math math-inline&quot;&gt;\F_q^\times&lt;&#x2F;span&gt;, i.e. &lt;span class=&quot;math math-inline&quot;&gt;x_i = \alpha \cdot \om_n^i&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\alpha \in \F_q^\times&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\om_n \in \F_q&lt;&#x2F;span&gt; is a primitive &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th root of unity. These are the point sets of practical concern as they can be efficiently implemented using number-theoretic transforms (NTTs).&lt;&#x2F;p&gt;
&lt;p&gt;We test if &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; influences the weight distributions, and find that it does not for prime &lt;span class=&quot;math math-inline&quot;&gt;q &amp;lt; 13&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;q = 13, n &amp;lt; 12&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;q = 13, n = 12, k \in [3,10]&lt;&#x2F;span&gt;. We skipped the other $[12,k]_{13]$ cases due to computational complexity, but some of these cases follow from the lemmas below. We will from here on fix &lt;span class=&quot;math math-inline&quot;&gt;\alpha = 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;exact-solutions-for-mds&quot;&gt;Exact solutions for MDS &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 3.&lt;&#x2F;strong&gt; Given a subspace &lt;span class=&quot;math math-inline&quot;&gt;\setn C \subseteq \F_q^n&lt;&#x2F;span&gt; we have the &lt;em&gt;singleton bound&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\wt(\setn C) \leq n - \dim \setn C + 1 \text{,}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and when the bound is tight, i.e., when equality holds, then &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;  is called &lt;em&gt;maximum distance separable (MDS)&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof sketch.&lt;&#x2F;em&gt; We have &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; coordinates, if we use all &lt;span class=&quot;math math-inline&quot;&gt;k = \dim \setn C&lt;&#x2F;span&gt; degrees of freedom to try to zero them out, we end up with the zero vector which is excluded from the weight minimum. So we can at most zero out &lt;span class=&quot;math math-inline&quot;&gt;k - 1&lt;&#x2F;span&gt; coordinates, leaving at most &lt;span class=&quot;math math-inline&quot;&gt;n - (k - 1) = n - k + 1&lt;&#x2F;span&gt; non-zero coordinates.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;When &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is MDS, we can solve the coset weight distribution of two special cases exactly. The
first one is is the trivial coset when &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \setn C&lt;&#x2F;span&gt; and the coset is &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; itself:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 4.&lt;&#x2F;strong&gt; Given &lt;span class=&quot;math math-inline&quot;&gt;\setn C \subseteq \F_q^n&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;k = \dim \setn C&lt;&#x2F;span&gt; the following are equivalent:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is MDS.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\setn C^\perp&lt;&#x2F;span&gt; is MDS.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\wt(\setn C) = n - k + 1&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Any &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; columns of a generator matrix of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; are linearly independent.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\mat G = [\mat I \mid \mat A]&lt;&#x2F;span&gt; is a generator matrix of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;\mat A&lt;&#x2F;span&gt; is hyper-invertible, i.e., all square submatrices of &lt;span class=&quot;math math-inline&quot;&gt;\mat A&lt;&#x2F;span&gt; are invertible.&lt;&#x2F;li&gt;
&lt;li&gt;For every &lt;span class=&quot;math math-inline&quot;&gt;\setn S \subseteq [0,n)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn S} = n-k+1&lt;&#x2F;span&gt; there is a codeword &lt;span class=&quot;math math-inline&quot;&gt;\vec c \in \setn C&lt;&#x2F;span&gt; with support &lt;span class=&quot;math math-inline&quot;&gt;\supp(\vec c) = \set{i \in [0,n) \mid c_i \neq 0} = \setn S&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;For every &lt;span class=&quot;math math-inline&quot;&gt;\setn S \subseteq [0,n)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn S} = k&lt;&#x2F;span&gt; the projection map &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\setn S} : \setn C \to \F_q^k&lt;&#x2F;span&gt; defined as &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\setn S}(\vec c) = (c_i)_{i \in \setn S}&lt;&#x2F;span&gt; is surjective.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 4.&lt;&#x2F;strong&gt; Given an MDS &lt;span class=&quot;math math-inline&quot;&gt;\setn C \subseteq \F_q^n&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;k = \dim \setn C&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;d = n-k+1&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i(\setn C) = f_i(q,n,k) + \begin{cases}
1 &amp;amp; \text{if } i = 0 \\
0 &amp;amp; \text{otherwise,} \\
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_i(q,n,k) = \binom{n}{i} (q-1)\sum_{j=0}^{i - d} (-1)^j \binom{i-1}{j} q^{i - d - j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which has special cases &lt;span class=&quot;math math-inline&quot;&gt;f_i(q,n,k) = 0&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;i &amp;lt; d&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f_{d}(q,n,k) = \binom{n}{k+1} (q-1)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; See Huffman-Pless lemma 7.4.1 p. 262.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;In particular &lt;span class=&quot;math math-inline&quot;&gt;f_{n - k + 1}(q,n,k) = \binom{n}{k+1} (q-1)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We must have &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i\in[0,n]} \A_i(\setn C) = q^k&lt;&#x2F;span&gt;, from this follows that &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i\in[0,n]} f_i(q,n,k) = q^k - 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The second special case is when &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; is such that the span of &lt;span class=&quot;math math-inline&quot;&gt;\vec r + \setn C&lt;&#x2F;span&gt; is also MDS. For an &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-RS code with &lt;span class=&quot;math math-inline&quot;&gt;k &amp;lt; n&lt;&#x2F;span&gt; and evaluation points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; we can construct such an &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; by choosing &lt;span class=&quot;math math-inline&quot;&gt;r_i = x_i^{k}&lt;&#x2F;span&gt;. The resulting span is the &lt;span class=&quot;math math-inline&quot;&gt;[n,k+1]_q&lt;&#x2F;span&gt;-RS code on the same evaluation points, and hence is also MDS.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 5.&lt;&#x2F;strong&gt; Given an MDS &lt;span class=&quot;math math-inline&quot;&gt;\setn C \subseteq \F_q^n&lt;&#x2F;span&gt; and a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec r \notin \setn C&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\setn D = \span(\vec r + \setn C)&lt;&#x2F;span&gt; is also MDS, we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i(\vec r + \setn C) = f_i(q,n,k) + \begin{cases}
0 &amp;amp; \text{if } i &amp;lt; n - k \\
(-1)^{n - k + i} \binom{n}{i} \binom{i-1}{n - k  - 1} &amp;amp; \text{if } i \geq n - k  \text{.}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In particular &lt;span class=&quot;math math-inline&quot;&gt;\A_{n-k}(\vec r + \setn C) =  \binom{n}{k}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; Since &lt;span class=&quot;math math-inline&quot;&gt;\setn D&lt;&#x2F;span&gt; is MDS, its minimum distance is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
d&amp;#39; = n - \dim \setn D + 1 = n - (\dim \setn C + 1) + 1 = d - 1 \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;By Huffman-Pless lemma 7.5.1.ii we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i(\vec r + \setn C) = \frac{\A_i(\setn D) - \A_i(\setn C)}{q - 1} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;span class=&quot;math math-inline&quot;&gt;i =&lt;&#x2F;span&gt; both &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn D)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn C)&lt;&#x2F;span&gt; are one and cancel out. For &lt;span class=&quot;math math-inline&quot;&gt;i &amp;lt; d - 1&lt;&#x2F;span&gt; both &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn D)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn C)&lt;&#x2F;span&gt; are zero. For &lt;span class=&quot;math math-inline&quot;&gt;i = d - 1&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn D) = \binom{n}{d-1} (q-1)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i(\setn C) = 0&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;i \geq d&lt;&#x2F;span&gt; we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\footnotesize
\begin{align*}
&amp;amp;\frac{\A_i(\setn D) - \A_i(\setn C)}{q-1} 
= \frac{f_i(q, n, d - 1) - f_i(q, n, d)}{q - 1} \\
&amp;amp;= \binom{n}{i} \p {\sum_{j=0}^{i - d + 1} (-1)^j \binom{i-1}{j} q^{i - d + 1 - j} - 
\sum_{j=0}^{i - d    } (-1)^j \binom{i-1}{j} q^{i - d     - j}} \\
&amp;amp;= \binom{n}{i} \p{\p{q - 1}\sum_{j=0}^{i - d} (-1)^j \binom{i-1}{j} q^{i - d - j} + (-1)^{i - d + 1} \binom{i-1}{i - d + 1}} \\
&amp;amp;=  f_i(q,n,d) - (-1)^{d + i} \binom{n}{i} \binom{i-1}{d - 2} \text{.} \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;It is interesting that these fluctuations do not depend on &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The above two cosets provide a simple lower bound for the list decoding size of &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-RS codes with &lt;span class=&quot;math math-inline&quot;&gt;k &amp;lt; n&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\L_{d-1} \geq \binom{n}{d-1} &amp;amp;&amp;amp; \L_d \geq 1 + \binom{n}{d} (q - 1) \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;coset-weight-distributions&quot;&gt;Coset Weight Distributions&lt;&#x2F;h2&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;\setn C \subseteq \F_q^n&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\dim \setn C = k&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_q^n&lt;&#x2F;span&gt;. We want to compute &lt;span class=&quot;math math-inline&quot;&gt;\A_i = \A_i(\vec r + \setn C)&lt;&#x2F;span&gt;, the number of vectors in the coset &lt;span class=&quot;math math-inline&quot;&gt;\vec r + \setn C&lt;&#x2F;span&gt; of weight &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We will tackle this by considering all support sets &lt;span class=&quot;math math-inline&quot;&gt;\setn I \subseteq [0,n)&lt;&#x2F;span&gt;. Define the subset of the coset with support contained in &lt;span class=&quot;math math-inline&quot;&gt;\setn I&lt;&#x2F;span&gt; and exactly equal to &lt;span class=&quot;math math-inline&quot;&gt;\setn I&lt;&#x2F;span&gt; respectively as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\setn A_{\setn I}  &amp;amp;= \{\vec c \in \vec r + C \mid \supp(\vec c) \subseteq \setn I\} \\
\setn A_{\setn I}&amp;#39; &amp;amp;= \{\vec c \in \vec r + C \mid \supp(\vec c) = \setn I\} \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then these are related by inclusion-exclusion as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\norm{\setn A_{\setn I}&amp;#39;} = \sum_{\setn J \subseteq \setn I} (-1)^{\norm{\setn I} - \norm{\setn J}} \norm{\setn A_{\setn J}} \text{,}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and to the the coset weight distribution by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i
= \sum_{\substack{\setn I \subseteq [0,n)\\[.3em] \norm{\setn I} = i}} \norm{\setn A_{\setn I}&amp;#39;} 
= \sum_{\substack{\setn I \subseteq [0,n)\\[.3em] \norm{\setn I} = i}}
\sum_{\setn J \subseteq \setn I} (-1)^{\norm{\setn I} - \norm{\setn J}} \norm{\setn A_{\setn J}}
\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So the task is to compute &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn A_{\setn J}}&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;\setn J \subseteq [0,n)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Fix &lt;span class=&quot;math math-inline&quot;&gt;\setn J \subseteq [0,n)&lt;&#x2F;span&gt; and lets its complement be &lt;span class=&quot;math math-inline&quot;&gt;\overline{\setn J} = [0,n) \setminus \setn J&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;\vec x \in \vec r + \setn C&lt;&#x2F;span&gt; to be in &lt;span class=&quot;math math-inline&quot;&gt;\setn A_{\setn J}&lt;&#x2F;span&gt; it must be that &lt;span class=&quot;math math-inline&quot;&gt;x_j = 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;j \in \overline{\setn J}&lt;&#x2F;span&gt;. This gives the coordinate wise equations&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\underset{j \in \overline{\setn J}}{\Large \forall}{}\  c_j = - r_j \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Denote with subscript &lt;span class=&quot;math math-inline&quot;&gt;\overline{\setn J}&lt;&#x2F;span&gt; the restriction to coordinates in &lt;span class=&quot;math math-inline&quot;&gt;\overline{\setn J}&lt;&#x2F;span&gt;, i.e. &lt;span class=&quot;math math-inline&quot;&gt;\vec c_{\overline{\setn J}} = (c_j)_{j \in \overline{\setn J}}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\setn C_{\overline{\setn J}} = \set{\vec c_{\overline{\setn J}} \mid \vec c \in \setn C}&lt;&#x2F;span&gt;, etc. Let &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\overline{\setn J}}: \setn C \to \setn C_{\overline{\setn J}}&lt;&#x2F;span&gt; be the coordinate restriction projection. Then the above equations can be rewritten as &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\overline{\setn J}}(\vec c) = - r_{\overline{\setn J}}&lt;&#x2F;span&gt;. And we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
|\setn A_{\setn J}| = \begin{cases}
0 &amp;amp; \text{if } \vec r_{\overline{\setn J}} \notin C_{\overline{\setn J}} \\
\norm{\ker(\pi_{\overline{\setn J}})} &amp;amp; \text{if } \vec r_{\overline{\setn J}} \in C_{\overline{\setn J}} \text{,}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\norm{\ker(\pi_{\overline{\setn J}})} = q^{\dim \ker(\pi_{\overline{\setn J}})}&lt;&#x2F;span&gt;. Define &lt;span class=&quot;math math-inline&quot;&gt;s_{\!\setn J} = \dim \ker(\pi_{\overline{\setn J}})&lt;&#x2F;span&gt;, then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i = 
\sum_{\substack{\setn I \subseteq [0,n)\\[.3em] \norm{\setn I} = i}}
\sum_{\substack{\setn J \subseteq \setn I \\[.3em] \vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}} }} (-1)^{\norm{\setn I} - \norm{\setn J}}
q^{s_{\!\setn J}} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So the two pieces of information that matter are (for each &lt;span class=&quot;math math-inline&quot;&gt;\setn I \subseteq [0,n)&lt;&#x2F;span&gt;),&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;s_{\setn I} = \dim \ker(\pi_{\overline{\setn I}})&lt;&#x2F;span&gt;, which depends only on &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;, and&lt;&#x2F;li&gt;
&lt;li&gt;whether &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\setn I} \in C_{\setn I}&lt;&#x2F;span&gt;, which also depends on the coset &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A natural next question is when does &lt;span class=&quot;math math-inline&quot;&gt;s_{\setn J}&lt;&#x2F;span&gt; only depend on the size &lt;span class=&quot;math math-inline&quot;&gt;j = \norm{\setn J}&lt;&#x2F;span&gt; but not its contents?  It turns out this is exactly when &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is MDS:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mds-codes-coarse-and-fine-structure&quot;&gt;MDS Codes: Coarse and Fine Structure&lt;&#x2F;h2&gt;
&lt;p&gt;Assume &lt;span class=&quot;math math-inline&quot;&gt;s_{\setn J}&lt;&#x2F;span&gt; only depend on the size &lt;span class=&quot;math math-inline&quot;&gt;j = \norm{\setn J}&lt;&#x2F;span&gt;. It follows that &lt;span class=&quot;math math-inline&quot;&gt;\dim \ker (\pi_{\setn S})&lt;&#x2F;span&gt; depends only on &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn S}&lt;&#x2F;span&gt; and thus &lt;span class=&quot;math math-inline&quot;&gt;\rank(\pi_{\setn S})&lt;&#x2F;span&gt; also depends only on &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn S}&lt;&#x2F;span&gt;. Let &lt;span class=&quot;math math-inline&quot;&gt;f(t) = \rank(\pi_{\setn S})&lt;&#x2F;span&gt; for any &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn S} = t&lt;&#x2F;span&gt;. Then we must have &lt;span class=&quot;math math-inline&quot;&gt;f(t) \leq \min(t, k)&lt;&#x2F;span&gt;, since the image of &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\setn S}&lt;&#x2F;span&gt; is a subspace of &lt;span class=&quot;math math-inline&quot;&gt;\F_q^t&lt;&#x2F;span&gt; and the rank cannot exceed the dimension of &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;. Recall that &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; simply deletes coordinates, so for &lt;span class=&quot;math math-inline&quot;&gt;t+1&lt;&#x2F;span&gt; we are adding a single coordinates, hence &lt;span class=&quot;math math-inline&quot;&gt;f(t+1) - f(t) \in \{0,1\}&lt;&#x2F;span&gt;. From these two conditions it follows that &lt;span class=&quot;math math-inline&quot;&gt;f(t) = \min(t,k)&lt;&#x2F;span&gt;, i.e. &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\setn S}&lt;&#x2F;span&gt; is surjective for when &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn S} \leq k&lt;&#x2F;span&gt;. By lemma 4 this is equivalent to &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; being MDS.&lt;&#x2F;p&gt;
&lt;p&gt;Conversely, when &lt;span class=&quot;math math-inline&quot;&gt;\pi_{\setn I}&lt;&#x2F;span&gt; is surjective when &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn I} \leq k&lt;&#x2F;span&gt;, and hence &lt;span class=&quot;math math-inline&quot;&gt;\setn C_{\setn I} = \F_q^{\norm{\setn I}}&lt;&#x2F;span&gt;. Therefore for &lt;span class=&quot;math math-inline&quot;&gt;\norm{\setn I} \geq k&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\setn I} \in \setn C_{\setn I}&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_q^n&lt;&#x2F;span&gt;. Additionally we have &lt;span class=&quot;math math-inline&quot;&gt;\rank(\pi_{\setn I}) = \dim(\setn C_{\setn I}) = \min(\norm{\setn I}, k)&lt;&#x2F;span&gt;, and thus &lt;span class=&quot;math math-inline&quot;&gt;\dim \ker(\pi_{\setn I}) = k - \min(\norm{\setn I}, k)&lt;&#x2F;span&gt;,&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;j = \norm{\setn J}&lt;&#x2F;span&gt;, so that &lt;span class=&quot;math math-inline&quot;&gt;\norm{\overline{\setn J}} = n - j&lt;&#x2F;span&gt;, then we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
s_{\!\setn J} = k - \min(n-j, k) = \begin{cases}
0 &amp;amp; \text{if } j \leq n - k \\
j - n + k &amp;amp; \text{if } j \geq n - k \text{.}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We split the inner sum for &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt; splits into two parts, one for &lt;span class=&quot;math math-inline&quot;&gt;j &amp;lt; n - k&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;q^{s_{\!\setn J}} = 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}}&lt;&#x2F;span&gt; may or may not hold, and one for &lt;span class=&quot;math math-inline&quot;&gt;j \geq n - k&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;q^{s_{\!\setn J}} = q^{j - n + k}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}}&lt;&#x2F;span&gt; always holds. Hence&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i = 
\overbrace{
\sum_{\substack{\setn I \subseteq [0,n)\\[.3em] \norm{\setn I} = i}}
\sum_{\substack{\setn J \subseteq \setn I \\[.3em] j \geq n - k }} (-1)^{i-j}
q^{j - n + k}
}^{\A_i^\text{coarse}} +
\overbrace{
\sum_{\substack{\setn I \subseteq [0,n)\\[.3em] \norm{\setn I} = i}}
\sum_{\substack{\setn J \subseteq \setn I \\[.3em] j &amp;lt; n - k  \\[.3em] \vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}} }} (-1)^{i-j}
}^{\A_i^\text{fine}}
\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first term is independent of &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; and is responsible for what we call the &lt;em&gt;coarse structure&lt;&#x2F;em&gt; of the coset weight distributions. The second term depends on &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; and is responsible for the &lt;em&gt;fine structure&lt;&#x2F;em&gt;. Note that the second term does not immediately depend on &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; (though it may still do so indirectly through the membership condition &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}}&lt;&#x2F;span&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s get the coarse structure term into a closed form. The double sum only depends on sizes &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt;, so we can rewrite it as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i^{\text{coarse}} = \binom{n}{i} \sum_{j \in [n - k, i]}(-1)^{i-j} \binom{i}{j} q^{j - n + k}
\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In particular this is zero for &lt;span class=&quot;math math-inline&quot;&gt;i &amp;lt; n - k&lt;&#x2F;span&gt;. The first non-trivial value is at &lt;span class=&quot;math math-inline&quot;&gt;i = n - k&lt;&#x2F;span&gt;, where we have &lt;span class=&quot;math math-inline&quot;&gt;\A_{n-k}^{\text{coarse}} = \binom{n}{k}&lt;&#x2F;span&gt;. We can show that the coarse structure sums to &lt;span class=&quot;math math-inline&quot;&gt;q^k&lt;&#x2F;span&gt; over all weights:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\sum_{i \in [0,n]} \A_i^{\text{coarse}} &amp;amp;= \sum_{i \in [n-k,n]} \binom{n}{i} \sum_{j \in [n - k, i]}(-1)^{i-j} \binom{i}{j} q^{j - n + k} \\
&amp;amp;=  \sum_{j \in [n - k, n]} \sum_{i \in [j,n]} (-1)^{i-j} \binom{n}{i} \binom{i}{j} q^{j - n + k} \\
&amp;amp;=  \sum_{j \in [n - k, n]} q^{j - n + k} \binom{n}{j} \sum_{i \in [0,n-j]} (-1)^i \binom{n - j}{i}  \\
&amp;amp;=  q^k
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where we used that &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i \in [0,n-j]} (-1)^i \binom{n - j}{i} = 0&lt;&#x2F;span&gt; unless &lt;span class=&quot;math math-inline&quot;&gt;n=j&lt;&#x2F;span&gt;, where it is &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;. Since this matches the total number of vectors in the coset, it follows that the fine structure term sums to zero.&lt;&#x2F;p&gt;
&lt;p&gt;We can also polish the &lt;span class=&quot;math math-inline&quot;&gt;\A_i^{\text{fine}}&lt;&#x2F;span&gt; term a bit. Define the number of solutions of size &lt;span class=&quot;math math-inline&quot;&gt;j &amp;lt; n - k&lt;&#x2F;span&gt; to the membership condition &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}}&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\n_j(\vec r, \setn C) =  \norm{\set{ \setn J \subseteq [0,n) \mid \vec r_{\overline{\setn J} } \in \setn C_{\overline{\setn J}} \wedge \norm{\setn J} = j }} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then we can rewrite the fine structure term as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i^{\text{fine}} = \sum_{j \in [0,\min(i, n-k-1)]} (-1)^{i-j} \binom{n-j}{i-j} \n_j
\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I said &quot;no ratios&quot;, but this one is worth it: If instead of counts &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; we had fractions &lt;span class=&quot;math math-inline&quot;&gt;p_j = \n_j &#x2F; \binom{n}{j} \in [0,1]&lt;&#x2F;span&gt;, we can use the identity &lt;span class=&quot;math math-inline&quot;&gt;\binom{n-j}{i-j} \binom{n}{j} = \binom{n}{i} \binom{i}{j}&lt;&#x2F;span&gt; to rewrite the fine structure term as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i^{\text{fine}} = \binom{n}{i} \sum_{j \in [0,\min(i, n-k-1)]} (-1)^{i-j} \binom{i}{j} p_j
\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;span class=&quot;math math-inline&quot;&gt;i &amp;lt; n-k&lt;&#x2F;span&gt; this is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Binomial_transform&quot;&gt;binomial transform&lt;&#x2F;a&gt; of the sequence &lt;span class=&quot;math math-inline&quot;&gt;p_j&lt;&#x2F;span&gt;. It also shows the similarity with the coarse structure term. In fact, the sequence &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt; is simply a binomial transform of the sequence &lt;span class=&quot;math math-inline&quot;&gt;[p_0, p_1, \dots, p_{n-k-1}, 1, q^1, q^2, \dots, q^k]&lt;&#x2F;span&gt; multiplied by factors &lt;span class=&quot;math math-inline&quot;&gt;(-1)^i\binom{n}{i}&lt;&#x2F;span&gt;. It&#x27;s useful to write down the reverse transformation as well, i.e. computing &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; from &lt;span class=&quot;math math-inline&quot;&gt;\A_i^{\text{fine}}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;j \in [0,n-k)&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\n_j = \sum_{i \in [0, j]} \binom{n-i}{n-j} \A_i^{\text{fine}} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So for a given MDS code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt;, the coset weight distributions are completely determined by the first &lt;span class=&quot;math math-inline&quot;&gt;n-k&lt;&#x2F;span&gt; the weight counts &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt;, solution counts &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt;, or fractions &lt;span class=&quot;math math-inline&quot;&gt;p_j&lt;&#x2F;span&gt; (or some combination thereof). Now the task is to find these for all cosets &lt;span class=&quot;math math-inline&quot;&gt;\vec r + \setn C&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fine-structure-of-the-trivial-coset&quot;&gt;Fine Structure of the Trivial Coset&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s solve the fine structure for &lt;span class=&quot;math math-inline&quot;&gt;\vec r = \vec 0&lt;&#x2F;span&gt;. This is the trivial coset since &lt;span class=&quot;math math-inline&quot;&gt;\vec r + \setn C = \setn C&lt;&#x2F;span&gt; is the code itself. In this case &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}}&lt;&#x2F;span&gt; always holds, so we get &lt;span class=&quot;math math-inline&quot;&gt;p_j = 1&lt;&#x2F;span&gt; and thus&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\A_i^{\text{fine}}
&amp;amp;= \binom{n}{i} \sum_{j \in [0,\min(i, n-k-1)]} (-1)^{i-j} \binom{i}{j}
\text{,}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To make this resemble the &lt;span class=&quot;math math-inline&quot;&gt;\A_i^\text{coarse}&lt;&#x2F;span&gt; we will reindex the sum. From the binomial identity &lt;span class=&quot;math math-inline&quot;&gt;\sum_{j\in[0,i]} (-1)^j \binom{i}{j} = 0&lt;&#x2F;span&gt; we have for &lt;span class=&quot;math math-inline&quot;&gt;i \geq n-k&lt;&#x2F;span&gt; that &lt;span class=&quot;math math-inline&quot;&gt;\sum_{j \in [0,n-k)} (-1)^{i-j} \binom{i}{j} = - \sum_{j \in [n-k, i]} (-1)^{i-j} \binom{i}{j}&lt;&#x2F;span&gt;, so we can rewrite as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i^{\text{fine}} = - \binom{n}{i} \sum_{j \in [n-k, i]} (-1)^{i-j} \binom{i}{j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now the summation matches and we can combine the sums to get a nice closed form for the weight distribution of the MDS code itself:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i(\setn C) = \binom{n}{i} \sum_{j \in [n-k, i]} (-1)^{i-j} \binom{i}{j} (q^{j-n+k} - 1) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is exactly the known MDS code weight distribution of e.g. Huffman-Pless theorem 7.4.1. A good sanity check!&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively, we can solve the fine structure term explicitly using the binomial identity&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{j\in[0,m]} (-1)^j \binom{r}{j} =\begin{cases}
1 &amp;amp; \text{if } m = 0 \\
0 &amp;amp; \text{if } 0 &amp;lt; m &amp;lt; r \\
(-1)^m \binom{r-1}{m} &amp;amp; \text{if } m \geq r \text{.}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Applying this with &lt;span class=&quot;math math-inline&quot;&gt;m = \min(i, n-k - 1)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r = i&lt;&#x2F;span&gt; gives the closed form&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i^{\text{fine}} = \begin{cases}
1 &amp;amp; \text{if } i = 0 \\
0 &amp;amp; \text{if } 0 &amp;lt; i \leq n-k -1 \\
(-1)^{n - k -1 + i} \binom{n}{i} \binom{i - 1}{n - k -1} &amp;amp; \text{if } i \geq n - k - 1 \text{.}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first non-trivial term happens at &lt;span class=&quot;math math-inline&quot;&gt;i = n - k + 1 = d&lt;&#x2F;span&gt;, where we have &lt;span class=&quot;math math-inline&quot;&gt;\A_d^{\text{fine}} = -\binom{n}{k-1}&lt;&#x2F;span&gt;. From there on the values alternate in sign.&lt;&#x2F;p&gt;
&lt;p&gt;The set of &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; which produce the trivial coset is exactly &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; itself, which has size &lt;span class=&quot;math math-inline&quot;&gt;q^k&lt;&#x2F;span&gt;. Recall &lt;span class=&quot;math math-inline&quot;&gt;\A_0(\vec r + \setn C) = \norm{ \{ \vec v \in (\vec r + \setn C) \mid \wt(\vec v) = 0 \} }&lt;&#x2F;span&gt; and the only solution to &lt;span class=&quot;math math-inline&quot;&gt;\wt(\vec v) = 0&lt;&#x2F;span&gt; is the zero vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v = \vec 0&lt;&#x2F;span&gt;. So &lt;span class=&quot;math math-inline&quot;&gt;\A_0(\vec r + \setn C) = 1&lt;&#x2F;span&gt; if and only if &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \setn C&lt;&#x2F;span&gt;. From this follows that the only coset with &lt;span class=&quot;math math-inline&quot;&gt;\A_0 &amp;gt; 0&lt;&#x2F;span&gt; is the trivial coset. This leaves only &lt;span class=&quot;math math-inline&quot;&gt;n - k - 1&lt;&#x2F;span&gt; degrees of freedom for the fine structure of the other cosets.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fine-structure-of-the-mds-coset&quot;&gt;Fine Structure of the MDS Coset&lt;&#x2F;h3&gt;
&lt;p&gt;Now let&#x27;s solve it for some offset &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\span(\vec r + \setn C)&lt;&#x2F;span&gt; is also MDS. To show that such an &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; always exists for &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-RS codes with &lt;span class=&quot;math math-inline&quot;&gt;k &amp;lt; n&lt;&#x2F;span&gt;, observe that there is a &lt;span class=&quot;math math-inline&quot;&gt;\vec r \notin \setn C&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; is the evaluation of a degree &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; polynomial at the evaluation points of the RS code. The span &lt;span class=&quot;math math-inline&quot;&gt;\setn D = \span(\vec r + \setn C)&lt;&#x2F;span&gt; is then a &lt;span class=&quot;math math-inline&quot;&gt;[n,k+1]_q&lt;&#x2F;span&gt;-RS code on the same evaluation points, which is also MDS.&lt;&#x2F;p&gt;
&lt;p&gt;We need to solve the membership condition &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}}&lt;&#x2F;span&gt;. From the MDS properties we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\rank\p{\pi_{\overline{\mathcal J}}^{(\setn C)}} &amp;amp;= \min(k, n-j) \\
\rank\p{\pi_{\overline{\mathcal J}}^{(\setn D)}} &amp;amp;= \min(k+1, n-j) \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We also have &lt;span class=&quot;math math-inline&quot;&gt;\setn D_{\overline{\setn J}} = \span(\vec r_{\overline{\setn J}} + \setn C_{\overline{\setn J}})&lt;&#x2F;span&gt;, so&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\vec r_{\overline{\setn J}} \in \setn C_{\overline{\setn J}}
&amp;amp;\iff \setn D_{\overline{\setn J}} = \setn C_{\overline{\setn J}} \\
&amp;amp;\iff \rank\p{\pi_{\overline{\mathcal J}}^{(\setn D)}} = \rank\p{\pi_{\overline{\mathcal J}}^{(\setn C)}} \\
&amp;amp;\iff \min(k, n-j) = \min(k+1, n-j) \\
&amp;amp;\iff j \geq n - k \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So for &lt;span class=&quot;math math-inline&quot;&gt;j&amp;lt; n -k&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;p_j = 0&lt;&#x2F;span&gt;. This gives &lt;span class=&quot;math math-inline&quot;&gt;A_i^{\text{fine}} = 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; and thus the weight distribution of the MDS coset is exactly &lt;span class=&quot;math math-inline&quot;&gt;\A_i^{\text{coarse}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Conjecture.&lt;&#x2F;strong&gt; The MDS coset maximizes &lt;span class=&quot;math math-inline&quot;&gt;\A_{n-k}&lt;&#x2F;span&gt; among all cosets.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fine-structure-of-the-weight-one-coset&quot;&gt;Fine Structure of the Weight One Coset&lt;&#x2F;h3&gt;
&lt;p&gt;We have &lt;span class=&quot;math math-inline&quot;&gt;\A_i^{\text{fine}} = [0, 1, 0, \dots, 0]&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; &lt;span class=&quot;math math-inline&quot;&gt;j &amp;lt; n-k&lt;&#x2F;span&gt;. This gives &lt;span class=&quot;math math-inline&quot;&gt;\n_j = \binom{n-1}{n-j}&lt;&#x2F;span&gt; and thus&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i^{\text{fine}} = \sum_{j \in [0,\min(i, n-k-1)]} (-1)^{i-j} \binom{n-j}{i-j} \binom{n-1}{n-j} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_i^{\text{fine}} = \begin{cases}
0 &amp;amp; \text{if } i = 0 \\
1 &amp;amp; \text{if } i = 1 \\
0 &amp;amp; \text{if } 1 &amp;lt; i &amp;lt; n-k \\
(-1)^{n - k + 1 + i} \binom{n-1}{i - 1} \binom{i-2}{n - k - 2} &amp;amp; \text{if } i \geq n - k \text{.}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A useful result is the value at &lt;span class=&quot;math math-inline&quot;&gt;i = n - k&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_{n-k}^{\text{fine}} = \binom{n - 1}{k} \text{.}
&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A_{n-k} = \binom{n}{k} - \binom{n-1}{k} = \binom{n-1}{k-1} \text{.}
&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bounds&quot;&gt;Bounds&lt;&#x2F;h2&gt;
&lt;p&gt;For an MDS code we only need to consider &lt;span class=&quot;math math-inline&quot;&gt;i &amp;lt; n - k&lt;&#x2F;span&gt; since those determine &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;. From the definitions of &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; immediately follow, for all &lt;span class=&quot;math math-inline&quot;&gt;i,j \in [0,n]&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
0 &amp;amp;\leq \A_i \leq \binom{n}{i} (q-1)^i &amp;amp;
0 &amp;amp;\leq \n_j \leq \binom{n}{j} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We also have linear relationships between the &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt; and the &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; from the MDS structure formulas. We can combine all this to derive bounds on &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; This actually gives stronger upper bounds up to capacity! The transformation rules and non-negativity requirements give stronger upper bounds than the trivial ones above.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Derive weight-one coset.&lt;&#x2F;li&gt;
&lt;li&gt;Show this minimizes &lt;span class=&quot;math math-inline&quot;&gt;\A_{d-1}&lt;&#x2F;span&gt; outside of the zero coset.
&lt;ul&gt;
&lt;li&gt;In fact, show that the weight one and MDS coset are the extremes for all &lt;span class=&quot;math math-inline&quot;&gt;i \geq n - k&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Add this &lt;span class=&quot;math math-inline&quot;&gt;\A_d{d-1}&lt;&#x2F;span&gt; lower bound.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;r \in [0,n]&lt;&#x2F;span&gt;, we want to maximize &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i \in [0,r]} \A_i&lt;&#x2F;span&gt; subject to the constraints above.
We need to consider all the &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt;, which we will treat as our unknowns, but as we will see, it is sufficient to consider only the &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt;s for &lt;span class=&quot;math math-inline&quot;&gt;i \geq n - k&lt;&#x2F;span&gt; to derive upper bounds. Take &lt;span class=&quot;math math-inline&quot;&gt;\mat M \in \mathbb{Z}^{(n-k)\times (n-k+1)}&lt;&#x2F;span&gt; the matrix representing the linear transformation from &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\A_i^{\text{fine}}&lt;&#x2F;span&gt; given by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1\ \, \\
-\binom{n}{1} &amp;amp; 1\ \  \\
\phantom{-}\binom{n}{2} &amp;amp; -\binom{n-1}{1} &amp;amp; 1\ \, \\
-\binom{n}{3} &amp;amp; \phantom{-}\binom{n-1}{2} &amp;amp; -\binom{n-2}{1} &amp;amp; 1\ \, \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots \\
\pm\binom{n}{n-k-1} &amp;amp; \mp\binom{n-1}{n-k-2} &amp;amp;  \pm\binom{n-2}{n-k-3} &amp;amp; \mp\binom{n-3}{n-k-4} &amp;amp; \cdots &amp;amp; 1\ \, \\
\mp\binom{n}{n-k} &amp;amp; \pm\binom{n-1}{n-k-1} &amp;amp;  \mp\binom{n-2}{n-k-2} &amp;amp; \pm\binom{n-3}{n-k-3} &amp;amp; \cdots &amp;amp; \pm\binom{k + 1}{1}\\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;such that &lt;span class=&quot;math math-inline&quot;&gt;\A = \A^{\text{coarse}} + \mat M \n&lt;&#x2F;span&gt;. Note that for &lt;span class=&quot;math math-inline&quot;&gt;i &amp;lt; n-k&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;\A_i^{\text{coarse}} = 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_{n-k}^{\text{coarse}} = \binom{n}{k}&lt;&#x2F;span&gt;. We can then formulate the following integer linear optimization problem that bounds the list decoding size &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i \in [0,r]} \A_i&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;i \leq n-k&lt;&#x2F;span&gt; for any coset of any &lt;span class=&quot;math math-inline&quot;&gt;[n,k]_q&lt;&#x2F;span&gt;-MDS code:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
&amp;amp;\max_{\n}\ [\ \overbrace{1 \, 1 \, \cdots \, 1}^{r+1} \, 0 \, \cdots 0\ ]\, \mat M \n \\
&amp;amp;\text{s.t. }
\begin{bmatrix}
\mat I_{n-k} \\
\mat M
\end{bmatrix}
\n \geq \begin{bmatrix}
\vec 0 \\
-\binom{n}{k} \\
\end{bmatrix} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The constraints only enforce the non-negativity of &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt;. We will relax the integrality constraint to get an upper bound. We claim that the active set of the solution is &lt;span class=&quot;math math-inline&quot;&gt;\n_j \geq 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;j \in [0,r)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i \geq 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;i \neq r&lt;&#x2F;span&gt; (we will proof this later). From this follows &lt;span class=&quot;math math-inline&quot;&gt;\n_j = 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;j&amp;lt; r&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\A_i = 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;i \neq r&lt;&#x2F;span&gt;. From the transform then follows &lt;span class=&quot;math math-inline&quot;&gt;\A_r = \n_r&lt;&#x2F;span&gt;. The remaining constraints then are&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
-\binom{n-r}{r} &amp;amp; 1\ \, \\
\phantom{-}\binom{n-r}{r+1} &amp;amp; -\binom{n-r-1}{r} &amp;amp; 1\ \, \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots \\
\mp\binom{n-1}{n-k-2} &amp;amp;  \pm\binom{n-2}{n-k-3} &amp;amp; \mp\binom{n-3}{n-k-4} &amp;amp; \cdots &amp;amp; 1\ \, \\
\pm\binom{n-1}{n-k-1} &amp;amp;  \mp\binom{n-2}{n-k-2} &amp;amp; \pm\binom{n-3}{n-k-3} &amp;amp; \cdots &amp;amp; \pm\binom{k + 1}{1}\\
\end{bmatrix} \n = \begin{bmatrix}
0 \\
0 \\
\vdots \\
0 \\
-\binom{n}{k} \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0 \leq \n_j = \sum_{i \in [0,j]} \binom{n-i}{n-j} \p{\A_i - \A_i^{\text{coarse}}} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0 \leq \n_j = \sum_{i \in [0,j]} \binom{n-i}{n-j} \p{\A_i - \A_i^{\text{coarse}}} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From &lt;span class=&quot;math math-inline&quot;&gt;\n_{n-k} \geq 0&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;\A_{n-k}^{\text{coarse}} = \binom{n}{k}&lt;&#x2F;span&gt; (the other &lt;span class=&quot;math math-inline&quot;&gt;\A_i^{\text{coarse}}&lt;&#x2F;span&gt; being zero), and the reverse transform we get the bound&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i \in [0,n-k]} \binom{n-i}{k} \A_i \geq \binom{n}{k}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So we want to solve the integer linear optimization problem&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\max_{\A_0,\dots,\A_{n-k}} &amp;amp;\sum_{i \in [0,r]} \A_i \\
\text{s.t. } &amp;amp; \A_i \geq 0 \quad (0 \leq i \leq n-k) \\
&amp;amp;\sum_{i \in [0,n-k]} \binom{n-i}{k} \A_i \geq \binom{n}{k} \text{.} \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This bound only assumes &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;[n,k]&lt;&#x2F;span&gt;-MDS, and does not use any properties of specific codes. Notably it does not depend on &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We can get a thigher bound by assuming that for non-trivial cosets the One coset minimizes &lt;span class=&quot;math math-inline&quot;&gt;\A_{n-k}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The likely provable &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;-independent upper bound solution&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\binom{n}{k}}{\binom{n-r}{k}} = \frac{(n)_r}{(n-k)_r} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;(n)_r = n (n-1) (n-2) \cdots (n-r+1)&lt;&#x2F;span&gt; is the falling factorial.&lt;&#x2F;p&gt;
&lt;p&gt;For large &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; with fixed rate &lt;span class=&quot;math math-inline&quot;&gt;\rho = k&#x2F;n&lt;&#x2F;span&gt; and fixed relative distance &lt;span class=&quot;math math-inline&quot;&gt;\delta = r&#x2F;n &amp;lt; (1-\rho)&lt;&#x2F;span&gt; the upper bound on the list decoding size for MDS codes becomes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\log \L_{\delta n} \leq
\log \frac{\binom{n}{\rho\, n}}{\binom{n-\delta\, n}{\rho\, n}}
= n \p{\H(\rho) - (1-\delta) \H\p{\frac{\rho}{1-\delta}}} + O(1)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The more ambitions one-coset &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;-independent upper bound solution&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\binom{n-1}{k-1}}{\binom{n-r}{k}} = \frac{n}{k} \frac{(n)_r}{(n-k)_r} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For large &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; with fixed rate &lt;span class=&quot;math math-inline&quot;&gt;\rho = k&#x2F;n&lt;&#x2F;span&gt; and fixed relative distance &lt;span class=&quot;math math-inline&quot;&gt;\delta = r&#x2F;n &amp;lt; (1-\rho)&lt;&#x2F;span&gt; the upper bound on the list decoding size for MDS codes becomes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\log \L_{\delta n} \leq
\log \frac{\binom{n-1}{\rho\, n -1}}{\binom{n-\delta\, n}{\rho\, n}}
= \log \rho + n \p{\H(\rho) - (1-\delta) \H\p{\frac{\rho}{1-\delta}}} + O(1)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;previous-bounds&quot;&gt;Previous Bounds&lt;&#x2F;h2&gt;
&lt;p&gt;MDS codes from Cauchy matrices: https:&#x2F;&#x2F;ieeexplore.ieee.org&#x2F;document&#x2F;45291&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;people.seas.harvard.edu&#x2F;~salil&#x2F;research&#x2F;list-lb-Jan10.pdf&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-unique-decoding-bound&quot;&gt;The Unique Decoding Bound&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i \in  [0, \frac{d-1}{2}]} \A_i \leq 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-johnson-bound&quot;&gt;The Johnson Bound&lt;&#x2F;h3&gt;
&lt;p&gt;For all &lt;span class=&quot;math math-inline&quot;&gt;\epsilon \in (0, 1]&lt;&#x2F;span&gt; and&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
r \leq n \p{1 - \frac{1}{q}} \p{1 - \sqrt{1 - (1- \epsilon)\frac{q}{q-1} \frac{d}{n}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i \in  [0, r]} \A_i \leq \frac{1}{\epsilon}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To get the tightest bound for &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; we want to find the largest &lt;span class=&quot;math math-inline&quot;&gt;\epsilon \in (0,1]&lt;&#x2F;span&gt; such that the above holds. We can solve the inequality to get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\epsilon = 1- \frac{q-1}{q} \frac{n}{d}\p{1- \p{1 - \frac{r}{n \p{1 - \frac{1}{q}}}}^2} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;elias-averaging-lemma&quot;&gt;Elias&#x27; Averaging Lemma&lt;&#x2F;h3&gt;
&lt;p&gt;Huffman-Pless lemma 2.5.2.&lt;&#x2F;p&gt;
&lt;p&gt;For every &lt;span class=&quot;math math-inline&quot;&gt;r \in [0, n]&lt;&#x2F;span&gt;, there exists an &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i \in  [0, r]} \A_i(\vec r + \setn C) \geq \frac{V_q(n, r)}{q^{n - k}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
V_q(n, r) = \sum_{i \in  [0, r]} \binom{n}{i} (q-1)^i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;justesen-and-hoholdt&quot;&gt;Justesen and Hoholdt&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.math.uci.edu&#x2F;~dwan&#x2F;listcode.pdf&lt;&#x2F;p&gt;
&lt;p&gt;For any &lt;span class=&quot;math math-inline&quot;&gt;g &amp;lt; n&lt;&#x2F;span&gt; there exists a coset such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_{n -g} \geq \frac{\binom{n}{g}}{q^{g-k}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For any &lt;span class=&quot;math math-inline&quot;&gt;r &amp;lt; n&lt;&#x2F;span&gt; there exists a coset such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_{r} \geq \frac{\binom{n}{r}}{q^{n-k-r}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.math.uci.edu&#x2F;~dwan&#x2F;listcode.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;ieeexplore.ieee.org&#x2F;document&#x2F;923744&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.sciencedirect.com&#x2F;science&#x2F;article&#x2F;abs&#x2F;pii&#x2F;S0097316523001036
https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2112.05592&lt;&#x2F;p&gt;
&lt;h3 id=&quot;numerical-epxperiments&quot;&gt;Numerical Epxperiments&lt;&#x2F;h3&gt;
&lt;p&gt;What we know and suspect:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For an &lt;span class=&quot;math math-inline&quot;&gt;[n,k]&lt;&#x2F;span&gt;-MDS code there is a small list of patterns &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt; &#x2F; &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt; that can occur which depends only on &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The multiplicities of these patterns (after removing a &lt;span class=&quot;math math-inline&quot;&gt;q^k\cdot(q-1)&lt;&#x2F;span&gt; factor) are asymptotically polynomial in &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; of degree up to &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; (or maybe even &lt;span class=&quot;math math-inline&quot;&gt;n-k&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; ?).&lt;&#x2F;li&gt;
&lt;li&gt;The multiplicities are noisy for small &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; and take some time to settle into their asymptotic polynomials. The multiplicities can get to zero due to &#x27;noise&#x27;, or become zero asymptotically.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Since the list decoding sizes are tightly bounded by the allowable set of weight distributions, we should focus on finding this universal list of weight distributions. For this we suspect:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;n_j = 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt; less than the minimum weight of the coset. (Q: And does it equal the number of words at this minimum weight after that?)&lt;&#x2F;li&gt;
&lt;li&gt;List decoding size at &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; is maximized by the coset that maximimizes &lt;span class=&quot;math math-inline&quot;&gt;\n_i&lt;&#x2F;span&gt; while &lt;span class=&quot;math math-inline&quot;&gt;n_j = 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;j &amp;lt; i&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Next steps.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Translate known bounds to constraints on &lt;span class=&quot;math math-inline&quot;&gt;\A_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\n_j&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In particular Elias bound.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Find the universal list.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Investigate multiplicities.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Trivial coset distribution of a (not necessarily MDS) code is related to that of its dual code via MacWilliams identities.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Does this extend to other cosets?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The weight distribution of a coset is related to the weight distribution of an extended code.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This is Huffman-Pless lemma 7.5.1.&lt;&#x2F;li&gt;
&lt;li&gt;This in turn is related to the weight distribution of the dual code.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Use Huffman-Pless lemma 7.5.1.ii.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;ar5iv.labs.arxiv.org&#x2F;html&#x2F;2101.12722&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dr.ntu.edu.sg&#x2F;server&#x2F;api&#x2F;core&#x2F;bitstreams&#x2F;f6ca9d42-8532-42fa-8a1a-e28f5655c1d1&#x2F;content&quot;&gt;https:&#x2F;&#x2F;dr.ntu.edu.sg&#x2F;server&#x2F;api&#x2F;core&#x2F;bitstreams&#x2F;f6ca9d42-8532-42fa-8a1a-e28f5655c1d1&#x2F;content&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cs.utexas.edu&#x2F;~danama&#x2F;courses&#x2F;codes&#x2F;lec8-LP-bound.pdf&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 2.&lt;&#x2F;strong&gt; The set of transformations that preserve the &lt;span class=&quot;math math-inline&quot;&gt;\F_q^n&lt;&#x2F;span&gt;-linear structure and the Hamming weight (equivalently, the Hamming distance) are exactly the monomial transformations together with global &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;-automorphisms. That is, for any  &lt;span class=&quot;math math-inline&quot;&gt;\vec{v} \in \F_q^n&lt;&#x2F;span&gt;, monomial matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat{M} \in \operatorname{Mon}(n, \F_q)&lt;&#x2F;span&gt;, and field automorphism &lt;span class=&quot;math math-inline&quot;&gt;\sigma \in \Aut(\F_q)&lt;&#x2F;span&gt;, we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\wt(\mat{M} \cdot \sigma(\vec{v}) ) = \wt(\vec{v}) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The group of all such weight and distance preserving transformations is denoted&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Iso\!\p{\F_q^n} = \operatorname{Mon}(n, \F_q) \rtimes \Aut(\F_q) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Recall that a &lt;em&gt;monomial matrix&lt;&#x2F;em&gt; is a square matrix with exactly one non-zero entry in each row and column, or equivalently, the product of a permutation matrix and an invertible diagonal matrix.  For finite fields &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^m}&lt;&#x2F;span&gt; the automorphisms are precisely the &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; powers of the Frobenius automorphism &lt;span class=&quot;math math-inline&quot;&gt;\sigma(x) = x^p&lt;&#x2F;span&gt;. For prime field &lt;span class=&quot;math math-inline&quot;&gt;m =1&lt;&#x2F;span&gt; and the only automorphism is the identity. The automorphism &lt;span class=&quot;math math-inline&quot;&gt;\sigma&lt;&#x2F;span&gt; is applied coordinate-wise to high dimensional objects.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 4.&lt;&#x2F;strong&gt; A &lt;em&gt;Reed-Solomon (RS) code&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{RS}_q(n, k, \vec{x})&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\vec{x} \in F_q^n&lt;&#x2F;span&gt; all distinct is generated by the &lt;span class=&quot;math math-inline&quot;&gt;n \times k&lt;&#x2F;span&gt; matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat G_{ij} = x_i^j&lt;&#x2F;span&gt;. We can &lt;em&gt;extend&lt;&#x2F;em&gt; it with an additional evaluation point that has powers &lt;span class=&quot;math math-inline&quot;&gt;x^j = 0&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;j &amp;lt; k - 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;x^{(k-1)} = 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;By monomial equivalence, permuting the evaluation points does not materially change the code. We can also scale the evaluation points by non-zero &lt;span class=&quot;math math-inline&quot;&gt;\lambda_i \in \F_q^\times&lt;&#x2F;span&gt; to get a more general generator matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat G_{ij} = \lambda_i x_i^j&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\vec{\lambda}&lt;&#x2F;span&gt; doesn&#x27;t add much, other than making the class closed under monomial equivalence. Typically the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s form (a coset of) a subgroup of &lt;span class=&quot;math math-inline&quot;&gt;\F_q^\times&lt;&#x2F;span&gt; to allow fast NTT algorithms, but the only requirement is that they are distinct. It is popular to interpret Reed–Solomon codes as evaluations of low-degree polynomials, but we will avoid introducing even more terminology here.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Absolute chaos below&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1109&#x2F;18.45291&quot;&gt;RL89&lt;&#x2F;a&gt; Ron M. Roth, Abraham Lempel (1989). On MDS Codes via Cauchy Matrices.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.4171&#x2F;emss&#x2F;33&quot;&gt;BL19&lt;&#x2F;a&gt; Simeon Ball, Michel Lavrauw (2019). Arcs in finite projective spaces.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~venkatg&#x2F;pubs&#x2F;papers&#x2F;listdecoding-NOW.pdf&quot;&gt;https:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~venkatg&#x2F;pubs&#x2F;papers&#x2F;listdecoding-NOW.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2101.12722&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2101.12722&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.3934&#x2F;amc.2021042&quot;&gt;https:&#x2F;&#x2F;doi.org&#x2F;10.3934&#x2F;amc.2021042&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;•	Andries E. Brouwer and Philippe Delsarte,
“Weight distributions of MDS codes,”
Report ZW 104&#x2F;74, Mathematical Centre (now CWI), Amsterdam, 1974.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2101.12722&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;[WS72] MacWilliams &amp;amp; Sloane — The Theory of Error-Correcting Codes&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;P. G. Bonneau (1990). Weight distribution of translates of MDS codes. Combinatorica, 10(1), 103–105. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1007&#x2F;BF02122700&quot;&gt;doi:10.1007&#x2F;bf02122700&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;errorcorrectionzoo.org&#x2F;kingdom&#x2F;q-ary_digits_into_q-ary_digits&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;errorcorrectionzoo.org&#x2F;c&#x2F;reed_solomon
https:&#x2F;&#x2F;rptu.de&#x2F;channel-codes&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;dspace.mit.edu&#x2F;bitstream&#x2F;handle&#x2F;1721.1&#x2F;4484&#x2F;RLE-TR-335-04734756.pdf&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2101.12722&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sumcheck</title>
        <published>2025-10-27T00:00:00+00:00</published>
        <updated>2025-10-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/26/sumcheck/"/>
        <id>https://2π.com/26/sumcheck/</id>
        
        <content type="html" xml:base="https://2π.com/26/sumcheck/">&lt;h1 id=&quot;sumcheck&quot;&gt;Sumcheck&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\vec#1{\mathbf{#1}}
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, and a linear space &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; given by the tensor product&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
V = T_1 \otimes T_2 \otimes \cdots \otimes T_n \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The prover has a tensor &lt;span class=&quot;math math-inline&quot;&gt;T \in V&lt;&#x2F;span&gt; and wants to prove some linear functional &lt;span class=&quot;math math-inline&quot;&gt;f(T) = s&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;verifiers-perspective&quot;&gt;Verifiers perspective&lt;&#x2F;h1&gt;
&lt;p&gt;Verifier has a sum &lt;span class=&quot;math math-inline&quot;&gt;s_0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the first round it receives a (typically short) vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v_1&lt;&#x2F;span&gt;. And verifies &lt;span class=&quot;math math-inline&quot;&gt;\vec w_1 \cdot \vec v_1 = s_0&lt;&#x2F;span&gt; for some public vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w_1&lt;&#x2F;span&gt;. It then sends a random challenge &lt;span class=&quot;math math-inline&quot;&gt;r_1&lt;&#x2F;span&gt;. It sets &lt;span class=&quot;math math-inline&quot;&gt;s_1 \leftarrow \vec s_1(r_1) \cdot \vec v_1&lt;&#x2F;span&gt; for some public vector valued function &lt;span class=&quot;math math-inline&quot;&gt;\vec s_1(r_1)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This repeats for several rounds and verifier is left with $s_n&lt;&#x2F;p&gt;
&lt;p&gt;What does this prove to the verifier?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;s_n = \vec s_n(r_n) \cdot \vec v_n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec w_n \cdot \vec v_n = s_{n-1}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Merkle Multi-Proofs</title>
        <published>2025-10-16T00:00:00+00:00</published>
        <updated>2025-10-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/merkle-multi-proof/"/>
        <id>https://2π.com/25/merkle-multi-proof/</id>
        
        <content type="html" xml:base="https://2π.com/25/merkle-multi-proof/">&lt;h1 id=&quot;merkle-multi-proofs&quot;&gt;Merkle Multi-Proofs&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\setp#1{\left\{{#1}\right\}}
\gdef\stirlingii#1#2{{{#1} \brace {#2}}}
\gdef\setn#1{\mathcal{#1}}
\gdef\floor#1{\left\lfloor#1\right\rfloor}
\gdef\ceil#1{\left\lceil#1\right\rceil}
\gdef\vec#1{\mathbf{#1}}
\gdef\H{\mathsf{hash}}
\gdef\bar#1{\left\lvert{#1}\right\rvert}
\gdef\Exp#1{\mathbb{E}\!\left[{#1}\right]}
\gdef\Var#1{\operatorname{Var}\!\p{#1}}
\gdef\Cov#1{\operatorname{Cov}\!\p{#1}}
\gdef\intersection{\cap}
\gdef\empty{\varnothing}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Vector commitments, and specifically Merkle proofs, are the heart of every hash-based proof system. They are responsible for a large part of proof size and verifier work, yet we don&#x27;t have sharp estimates of either. This is largely due to a complex dependency on the distribution of opened indices. In hash-based proof systems, this distribution is uniformly random with replacement, which lets us derive the concrete results that follow.&lt;&#x2F;p&gt;
&lt;p&gt;Key results are exact minimum, maximum, mean, variance and probability mass functions of proof size and verifier work, plus approximations and a way to implement Merkle caps purely verifier side.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 1.&lt;&#x2F;strong&gt; A &lt;em&gt;Vector Commitment Scheme&lt;&#x2F;em&gt; for a set &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt; has &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{commit}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; algorithms.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{commit}&lt;&#x2F;span&gt; algorithm takes a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v \in {\setn S}^n&lt;&#x2F;span&gt; and outputs a commitment &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt; algorithm takes a commitment &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;, a list of &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; indices &lt;span class=&quot;math math-inline&quot;&gt;\vec i \in [0,n)^m&lt;&#x2F;span&gt; and values &lt;span class=&quot;math math-inline&quot;&gt;\vec y \in {\setn S}^m&lt;&#x2F;span&gt; and outputs a proof &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; that &lt;span class=&quot;math math-inline&quot;&gt;\vec v_{\vec{i}_j} = \vec y_j&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;j \in [0,m)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; algorithm takes &lt;span class=&quot;math math-inline&quot;&gt;C, \vec i, \vec y, \pi&lt;&#x2F;span&gt; and outputs true if the proof is valid and false otherwise.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The canonical example of a vector commitment scheme is a &lt;em&gt;Merkle tree&lt;&#x2F;em&gt;. There are many expositions of this, so I&#x27;ll just write a quick definition:&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 2.&lt;&#x2F;strong&gt; Given a two-to-one hash function &lt;span class=&quot;math math-inline&quot;&gt;\H: \setn H \times \setn H \rightarrow \setn H&lt;&#x2F;span&gt;, a &lt;em&gt;Merkle tree&lt;&#x2F;em&gt; of height &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt; is a vector commitment scheme for &lt;span class=&quot;math math-inline&quot;&gt;n = 2^h&lt;&#x2F;span&gt; values of &lt;span class=&quot;math math-inline&quot;&gt;\setn H&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{commit}&lt;&#x2F;span&gt; algorithm takes a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v \in {\setn H}^n&lt;&#x2F;span&gt; and constructs a perfect binary tree with &lt;span class=&quot;math math-inline&quot;&gt;\vec v_i&lt;&#x2F;span&gt; as the &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;-th leaf and each node value computed by taking the hash of the child values. The commitment &lt;span class=&quot;math math-inline&quot;&gt;C \in \setn H&lt;&#x2F;span&gt; is the value of the root node.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt; algorithm takes &lt;span class=&quot;math math-inline&quot;&gt;\vec i&lt;&#x2F;span&gt; and marks the corresponding leaves and their ancestors. The proof &lt;span class=&quot;math math-inline&quot;&gt;\pi \in \setn H^\ast&lt;&#x2F;span&gt; are the values of nodes and leaves that are not marked  but have a marked parent.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; algorithm takes &lt;span class=&quot;math math-inline&quot;&gt;C, \vec i, \vec y, \pi&lt;&#x2F;span&gt; and applies &lt;span class=&quot;math math-inline&quot;&gt;\H&lt;&#x2F;span&gt; repeatedly to compute all node values it knows all child values of. This will eventually compute the root node, which is then verified to equal &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We called nodes in &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; the &lt;em&gt;revealed nodes&lt;&#x2F;em&gt; and the ones computed in &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; the &lt;em&gt;computed nodes&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The variant presented here uses &lt;em&gt;compressed multi-proofs&lt;&#x2F;em&gt;. We also allow &lt;span class=&quot;math math-inline&quot;&gt;\vec i&lt;&#x2F;span&gt; to be in arbitrary order and contain repeated values. The revealed indices and values &lt;span class=&quot;math math-inline&quot;&gt;\vec i, \vec y&lt;&#x2F;span&gt; are not part of the proof &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; as the assumption is prover and verifier already established these by other means.&lt;&#x2F;p&gt;
&lt;p&gt;This scheme naturally extends to imperfect trees and higher- or even mixed-arity trees. This allows vector lengths that are not a power of two and can reduce tree depth if this is beneficial. The definition above uses a single hash function for all nodes, but it works with arbitrary hash functions for each node as long as prover and verifier pick the same ones. In verifier circuits the hash function cost for prover and verifier can be wildly different and it would make sense to pick a prover-favorable hash function for the deeper nodes and a verifier-favorable hash function for the nodes closer to the top. Neither of these extensions are considered in this analysis.&lt;&#x2F;p&gt;
&lt;p&gt;In the aforementioned application in hash-based proof systems, the indices &lt;span class=&quot;math math-inline&quot;&gt;\vec i&lt;&#x2F;span&gt; are generated by &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; uniform random draws from &lt;span class=&quot;math math-inline&quot;&gt;[0,n)&lt;&#x2F;span&gt; with repetition. Knowing the distribution of &lt;span class=&quot;math math-inline&quot;&gt;\vec i&lt;&#x2F;span&gt; we can compute the distribution of the proof size &lt;span class=&quot;math math-inline&quot;&gt;\bar{\pi}&lt;&#x2F;span&gt;, i.e. the number of revealed nodes, and the number of hashes the verifier has to compute, i.e. the number of computed nodes. Finally we will look at a verifier implementation with deterministic control flow.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;number-of-computed-nodes&quot;&gt;Number of Computed Nodes&lt;&#x2F;h1&gt;
&lt;p&gt;The number of hashes a verifier needs to perform is the number of computed nodes: non-leaf nodes that are marked. Given a Merkle proof of height &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; uniformly random openings with replacement, let &lt;span class=&quot;math math-inline&quot;&gt;C_d&lt;&#x2F;span&gt; be the number of computed nodes at level &lt;span class=&quot;math math-inline&quot;&gt;d \in [0,h)&lt;&#x2F;span&gt; of the tree. This creates a set of random variables &lt;span class=&quot;math math-inline&quot;&gt;C_d&lt;&#x2F;span&gt; in the choice of openings. Importantly these random variables are not independent as the computation of a node at level &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; implies the computation of its parent at level &lt;span class=&quot;math math-inline&quot;&gt;d+1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Equivalently, consider a uniform random draw of &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; infinite binary strings &lt;span class=&quot;math math-inline&quot;&gt;\setn M \subset \setp{0,1}^\infty&lt;&#x2F;span&gt;. Take &lt;span class=&quot;math math-inline&quot;&gt;\setn M_d \subset \setp{0,1}^d&lt;&#x2F;span&gt; to be the set of prefixes of length &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; of elements in &lt;span class=&quot;math math-inline&quot;&gt;\setn M&lt;&#x2F;span&gt;. We have that &lt;span class=&quot;math math-inline&quot;&gt;C_d = \bar{\setn M_d}&lt;&#x2F;span&gt;, the number of distinct prefixes of length &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;\setn M&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The distribution of &lt;span class=&quot;math math-inline&quot;&gt;C_d&lt;&#x2F;span&gt; is the occupancy distribution of throwing &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; balls into &lt;span class=&quot;math math-inline&quot;&gt;2^d&lt;&#x2F;span&gt; bins uniformly at random with replacement. This is a well-known problem in probability theory and combinatorics. The probability mass function is given by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr[C_d = k] = \frac{k!}{2^{d \cdot m}} \binom{2^d}{k} \stirlingii{m}{k}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\binom{n}{k}&lt;&#x2F;span&gt; is the binomial coefficient and &lt;span class=&quot;math math-inline&quot;&gt;\stirlingii{m}{k}&lt;&#x2F;span&gt; is the Stirling number of the second kind. The support for &lt;span class=&quot;math math-inline&quot;&gt;m &amp;gt; 0&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;k \in [1, \min(2^d, m)]&lt;&#x2F;span&gt;, but note that &lt;span class=&quot;math math-inline&quot;&gt;C_d&lt;&#x2F;span&gt; is also bounded by &lt;span class=&quot;math math-inline&quot;&gt;C_{d+1} \in [C_d, 2 \cdot C_d]&lt;&#x2F;span&gt; due to the tree structure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;expected-value&quot;&gt;Expected Value&lt;&#x2F;h2&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;p_d = 1 - (1 - 2^{-d})^m&lt;&#x2F;span&gt; to be the probability that a node at level &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; is computed. The expected number of computed nodes at level &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; is then &lt;span class=&quot;math math-inline&quot;&gt;\mathbb{E}[C_d] = 2^d \cdot p_d&lt;&#x2F;span&gt;. The total number of computed nodes &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;C = \sum_{d \in [0,h)} C_d&lt;&#x2F;span&gt; and therefore&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\boxed{
\mathbb{E}[C] = \sum_{d \in [0,h)} 2^d \cdot \p{1 - \p{1- 2^{-d}}^m}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This exact expression can be efficiently evaluated in &lt;span class=&quot;math math-inline&quot;&gt;O(h)&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;m \ll 2^h&lt;&#x2F;span&gt; we can also  approximate it well with &lt;span class=&quot;math math-inline&quot;&gt;m \cdot (h - \log_2 m  + 0.11)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;support&quot;&gt;Support&lt;&#x2F;h2&gt;
&lt;p&gt;Let the &lt;span class=&quot;math math-inline&quot;&gt;k \in [k_{\min}(h,m), k_{\max}(h,m)]&lt;&#x2F;span&gt; be the support such that &lt;span class=&quot;math math-inline&quot;&gt;\Pr[C = k] &amp;gt; 0&lt;&#x2F;span&gt;. Then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
k_{\min}(h, m) = \begin{cases}
0 &amp;amp; \text{if } m = 0 \\
h &amp;amp; \text{otherwise} \\
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;follows from the minimal case where all &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; openings fall on the same leaf. Similarly, the maximum follows from distributing the &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; openings as spread out as possible on each level, so &lt;span class=&quot;math math-inline&quot;&gt;k_{\max}(h, m) = \sum_{d \in [0,h)} \min(2^d, m)&lt;&#x2F;span&gt;. This can be written in closed form as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
k_{\max}(h, m) = \begin{cases}
0 &amp;amp; \text{if } m = 0 \\
2^{\floor{\log_2 m} + 1} + m \cdot (h - \floor{\log_2 m} - 1) - 1 &amp;amp; \text{if } 1 \leq m &amp;lt; 2^h \\
2^h -1 &amp;amp; \text{if } m \geq 2^h \text{.}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; support&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) -&amp;gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; min&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;bit_length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;probability-mass-function&quot;&gt;Probability Mass Function&lt;&#x2F;h2&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;p_{h,m}(k) = \Pr[C = k]&lt;&#x2F;span&gt; be the probability mass function. The base cases &lt;span class=&quot;math math-inline&quot;&gt;p_{h,0}(k)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p_{0,m}(k)&lt;&#x2F;span&gt; are &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; when &lt;span class=&quot;math math-inline&quot;&gt;k=0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; otherwise. Then by induction a &lt;span class=&quot;math math-inline&quot;&gt;h&amp;gt;0&lt;&#x2F;span&gt; tree requires the root to be computed, plus computation required in the two subtrees. This results in the recurrence&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_{h+1,m}(k) =
\underbrace{2^{-m} \sum_{m&amp;#39; \in [0,m]} \binom{m}{m&amp;#39;} }_{\boxed{1}}
\underbrace{\sum_{k&amp;#39; \in [0,k-1]}}_{\boxed{2}}
p_{h,m&amp;#39;}(k&amp;#39;) \cdot p_{h, m - m&amp;#39;}(k - 1 - k&amp;#39;)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\boxed{1}&lt;&#x2F;span&gt; accounts for Binomial distribution of the &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; openings into the subtrees as &lt;span class=&quot;math math-inline&quot;&gt;(m&amp;#39;, m-m&amp;#39;)&lt;&#x2F;span&gt;. The number of computed nodes has one subtract for the root node, and the remaining &lt;span class=&quot;math math-inline&quot;&gt;k-1&lt;&#x2F;span&gt; nodes are distributed by &lt;span class=&quot;math math-inline&quot;&gt;\boxed{2}&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;(k&amp;#39;, k-1-k&amp;#39;)&lt;&#x2F;span&gt; over the subtrees.&lt;&#x2F;p&gt;
&lt;p&gt;The PMF can be calculated reasonably quickly on values of practical interest (e.g. &lt;span class=&quot;math math-inline&quot;&gt;h=20, m=200&lt;&#x2F;span&gt;) using memoization and restricting the values to the support:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-decorator z-python z-entity z-name z-function z-decorator z-python&quot;&gt;@cache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ndarray&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; support&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    out&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; dtype&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;float64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        pmf1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        pmf2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        conv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;convolve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;pmf1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; pmf2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;conv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; float&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;comb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; conv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; **&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;25&#x2F;merkle-multi-proof&#x2F;computed_pmf_h20_m200.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The thick black line is the exact PMF computed with the above recurrence formula. The dotted lines are in log scale, with black being the PMF. The red and blue lines are the normal and beta-binomial approximations discussed below.&lt;&#x2F;p&gt;
&lt;p&gt;The resulting PMF is concentrated around a narrow spike near the maximum support. The log scale reveals some skew asymmetry in the peak, but overall it looks like it can be well approximated by a normal distribution. We already have the expected value from above, so we now turn to the variance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;variance&quot;&gt;Variance&lt;&#x2F;h2&gt;
&lt;p&gt;We will compute the variance by deriving a formula for &lt;span class=&quot;math math-inline&quot;&gt;\Cov{C_d, C_e}&lt;&#x2F;span&gt; and using the identity&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Var{C} =
\Var{\sum_{d \in [0,h)]} C_d} = \sum_{d, e \in [0,h) } \Cov{C_d, C_e} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;I_{d,i} \in \setp{0,1}&lt;&#x2F;span&gt; be the indicator random variable for the marking of node &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; at level &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;. It is Bernoulli distributed with &lt;span class=&quot;math math-inline&quot;&gt;p_d = 1 - (1 - 2^{-d})^m&lt;&#x2F;span&gt;, such that &lt;span class=&quot;math math-inline&quot;&gt;\Exp{I_{d,i}} = p_d&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\Var{I_{d,i}} = p_d \cdot (1 - p_d)&lt;&#x2F;span&gt;. Observe that &lt;span class=&quot;math math-inline&quot;&gt;C_d = \sum_{i \in [0, 2^d)} I_{d,i}&lt;&#x2F;span&gt; and we quickly rederive &lt;span class=&quot;math math-inline&quot;&gt;\Exp{C_d} = \sum_{i \in [0, 2^d)} \Exp{I_{d,i}} = 2^d \cdot p_d&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;L_{d,i} \subseteq [0,2^h)&lt;&#x2F;span&gt; be the set of leaves descendant from node &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; at level &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;. Let&#x27;s extend &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; with the joint probability of two node markings conditioned on non-overlapping leaf sets as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_{de} = \Pr(I_{d,i} = 1, I_{e,j} = 1 \mid L_{d,i} \intersection L_{e,j} = \empty)\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;By inclusion-exclusion we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
p_{de} =\ &amp;amp; 1 - \Pr(I_{d,i} = 0) - \Pr(I_{e,j} = 0) \\
&amp;amp; + \Pr(I_{d,i} = 0, I_{e,j} = 0 \mid L_{d,i} \intersection L_{e,j} = \empty) \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first two probabilities are &lt;span class=&quot;math math-inline&quot;&gt;(1 - 2^{-d})^m&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(1 - 2^{-e})^m&lt;&#x2F;span&gt; as we saw before. The last is the probability that all &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; draws avoid the leafs that are descendants of either &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt;, which is &lt;span class=&quot;math math-inline&quot;&gt;(1 - 2^{-d} - 2^{-e})^m&lt;&#x2F;span&gt;. We thus get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_{de} = 1 - (1 - 2^{-d})^m - (1 - 2^{-e})^m + (1 - 2^{-d} - 2^{-e})^m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with the special case &lt;span class=&quot;math math-inline&quot;&gt;p_{dd} = 1 - 2 \cdot (1 - 2^{-d})^m + (1 - 2^{1-d})^m&lt;&#x2F;span&gt; and symmetry &lt;span class=&quot;math math-inline&quot;&gt;p_{de} = p_{ed}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We will use the identity &lt;span class=&quot;math math-inline&quot;&gt;\Cov{C_d, C_e} = \Exp{C_d \cdot C_e} - \Exp{C_d} \cdot \Exp{C_e}&lt;&#x2F;span&gt; to compute the covariance. So next we compute &lt;span class=&quot;math math-inline&quot;&gt;\Exp{C_d \cdot C_e}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathbb{E}[C_d \cdot C_e] = \sum_{i \in [0, 2^d)} \sum_{j \in [0, 2^e)} \mathbb{E}[I_{d,i} \cdot I_{e,j}] \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;f = \max(d,e)&lt;&#x2F;span&gt; the deepest level. We split the sum into two cases, either &lt;span class=&quot;math math-inline&quot;&gt;L_{d,i} \intersection L_{e,j} = \empty&lt;&#x2F;span&gt; or not. If it is not empty then one node is a descendant of or identical with the other and &lt;span class=&quot;math math-inline&quot;&gt;I_{d,i} \cdot I_{e,j} = I_{f,j}&lt;&#x2F;span&gt;. There are &lt;span class=&quot;math math-inline&quot;&gt;2^f&lt;&#x2F;span&gt; such cases. The remaining &lt;span class=&quot;math math-inline&quot;&gt;2^{d+e} - 2^f&lt;&#x2F;span&gt; cases have disjoint leaf sets and thus &lt;span class=&quot;math math-inline&quot;&gt;\mathbb{E}[I_{d,i} \cdot I_{e,j}] = p_{de}&lt;&#x2F;span&gt;. Summing the disjoint and non-disjoint contributions we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mathbb{E}[C_d \cdot C_e] &amp;amp;= 2^f \cdot p_f + \p{2^{d+e} - 2^f} \cdot p_{de} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From &lt;span class=&quot;math math-inline&quot;&gt;\Cov{C_d, C_e} = \Exp{C_d \cdot C_e} - \Exp{C_d} \cdot \Exp{C_e}&lt;&#x2F;span&gt; it then follows&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\Cov{C_d, C_e}
&amp;amp;= 2^f \cdot p_f + \p{2^{d+e} - 2^f} \cdot p_{de} - 2^{d+e} \cdot p_d \cdot p_e \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and thus&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\boxed{
\Var{C} = \sum_{d, e \in [0,h)} 2^f \cdot p_f + \p{2^{d+e} - 2^f} \cdot p_{de} - 2^{d+e} \cdot p_d \cdot p_e
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;f = \max(d,e)&lt;&#x2F;span&gt;. This double sum can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;O(h^2)&lt;&#x2F;span&gt; time.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; exact_moments&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            pe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            qde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; qde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If we compare the mean and variance computed this way to empirical mean and variance computed from the above PMF recurrence we find they match perfectly to within numerical precision (&lt;span class=&quot;math math-inline&quot;&gt;~10^{-11}&lt;&#x2F;span&gt; for the mean and &lt;span class=&quot;math math-inline&quot;&gt;~10^{-5}&lt;&#x2F;span&gt; for the variance).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;normal-approximation&quot;&gt;Normal Approximation&lt;&#x2F;h2&gt;
&lt;p&gt;Given the mean and variance above we can construct a normal approximation as &lt;span class=&quot;math math-inline&quot;&gt;\Pr[C = k] \approx {\setn N}\!\p{\Exp{C}, \Var{C}}&lt;&#x2F;span&gt;. We compute the approximate PMF &lt;span class=&quot;math math-inline&quot;&gt;\hat{p}_{h,m}(k)&lt;&#x2F;span&gt; by evaluating the normal distribution at each integer in the support and normalizing:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pmf_approx_normal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ndarray&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; exact_moments&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; support&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1e-12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # Degenerate point mass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; dtype&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;float64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;clip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;round&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;sqrt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;var&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;arange&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    pmf_approx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;sqrt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;pi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; **&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;    pmf_approx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  # PMF is zero below minimum support&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    pmf_approx&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;pmf_approx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  # Normalize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pmf_approx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note: When computing confidence intervals from the normal distribution, don&#x27;t forget to account for the tails cut off due to finite support.&lt;&#x2F;p&gt;
&lt;p&gt;We can then compute the KL-divergence between the exact PMF and the approximate PMF. For the previous graph of &lt;span class=&quot;math math-inline&quot;&gt;h = 20&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m = 200&lt;&#x2F;span&gt;, the &lt;span class=&quot;math math-inline&quot;&gt;D_{KL} = 0.00362\ \mathrm{bits}&lt;&#x2F;span&gt; which is very small. The linear graphs are visually indistinguishable. The log graphs show an underestimation of the left tail and overestimation of the right tail. This is desirable as it means the normal approximation is conservative in estimating the maximum.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;25&#x2F;merkle-multi-proof&#x2F;compute-normal-kl-divergence.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Over the range &lt;span class=&quot;math math-inline&quot;&gt;h \in [8, 21]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m \in [0, 300]&lt;&#x2F;span&gt; the KL-divergence between the exact PMF and the normal approximation is below &lt;span class=&quot;math math-inline&quot;&gt;0.01\ \mathrm{bits}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;m &amp;gt; 75&lt;&#x2F;span&gt; and below &lt;span class=&quot;math math-inline&quot;&gt;0.1&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;m &amp;gt; 5&lt;&#x2F;span&gt;. For small &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; the discrete nature of the PMF is more pronounced and the normal approximation is less accurate. But fortunately there the exact PMF can be computed quickly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;beta-binomial-approximation&quot;&gt;Beta-Binomial Approximation&lt;&#x2F;h2&gt;
&lt;p&gt;We can do better than a normal approximation by using a discrete distribution that matches the support, mean, and variance exactly. The &lt;span class=&quot;math math-inline&quot;&gt;\beta&lt;&#x2F;span&gt;-binomial distribution is a good candidate as it is defined on &lt;span class=&quot;math math-inline&quot;&gt;[0, n]&lt;&#x2F;span&gt; for integer &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and has two shape parameters that can be tuned to match mean and variance.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pmf_approx_betabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ndarray&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; support&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; exact_moments&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1e-12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # Degenerate point mass&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; dtype&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;float64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;clip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;round&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    from&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; scipy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;stats&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; betabinom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; binom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;kmax&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    denom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; denom&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1e-12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # Under-dispersed: Fallback to binomial&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;pad&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;binom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;arange&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;), (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; var&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; denom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; betabinom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;arange&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;pad&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;kmin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;25&#x2F;merkle-multi-proof&#x2F;compute-betabin-kl-divergence.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The beta-binomial approximation is excellent! Around &lt;span class=&quot;math math-inline&quot;&gt;m &amp;gt; 2^{h-2}&lt;&#x2F;span&gt; (the lower quality bottom region) the variance becomes too low for a beta-binomial and we fall back to a binomial distribution. The binomial approximation gets better as &lt;span class=&quot;math math-inline&quot;&gt;m \gg 2^h&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;number-of-revealed-nodes&quot;&gt;Number of Revealed Nodes&lt;&#x2F;h1&gt;
&lt;p&gt;The proof consists of the hash values associated with the revealed nodes: nodes that have a marked parent but are not themselves marked. Let &lt;span class=&quot;math math-inline&quot;&gt;S_{d,i} \in \set{0,1}&lt;&#x2F;span&gt; be the indicator variable that a node in the &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;-th sibling pair at level &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; is revealed. Then &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; is the XOR of the sibling &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; indicators:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
S_{d,i}
&amp;amp;= I_{d,2i} \oplus I_{d,2i+1} \\
&amp;amp;= I_{d,2i} + I_{d,2i+1} - 2 \cdot I_{d,2i} \cdot I_{d,2i+1}
\text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that there are &lt;span class=&quot;math math-inline&quot;&gt;2^{d-1}&lt;&#x2F;span&gt; sibling pairs at level &lt;span class=&quot;math math-inline&quot;&gt;d &amp;gt; 0&lt;&#x2F;span&gt; with no pairs at level &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; (there is only one root node). Let &lt;span class=&quot;math math-inline&quot;&gt;R_d&lt;&#x2F;span&gt; be the number of revealed nodes at height &lt;span class=&quot;math math-inline&quot;&gt;d \in [0,h]&lt;&#x2F;span&gt;. We have &lt;span class=&quot;math math-inline&quot;&gt;R_0 = 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;R_d = \sum_{i \in [0, 2^{d-1})} S_{d,i}&lt;&#x2F;span&gt; and thus &lt;span class=&quot;math math-inline&quot;&gt;R = \sum_{d \in [1,h]} R_d&lt;&#x2F;span&gt; the total number of revealed nodes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;expected-value-1&quot;&gt;Expected Value&lt;&#x2F;h2&gt;
&lt;p&gt;Computing &lt;span class=&quot;math math-inline&quot;&gt;\Exp{R}&lt;&#x2F;span&gt; is now a matter of expanding definitions and using previous results:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\Exp{R}
&amp;amp;= \sum_{d \in [1,h]} \sum_{i \in [0, 2^{d-1})} \Exp{I_{d,2i} + I_{d,2i+1} - 2 \cdot I_{d,2i} \cdot I_{d,2i+1}} \\
&amp;amp;= \sum_{d \in [1,h]} \sum_{i \in [0, 2^{d-1})} \p{p_d + p_d - 2 \cdot p_{dd}} \\
&amp;amp;= \sum_{d \in [1,h]} 2^d \p{p_d -  p_{dd}} \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where we use the fact that leaf sets of siblings must be disjoint. Expanding &lt;span class=&quot;math math-inline&quot;&gt;p_d&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p_{dd}&lt;&#x2F;span&gt; we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\boxed{
\Exp{R} = \sum_{d \in [1,h]} 2^d \cdot \p{(1 - 2^{-d})^m - (1 - 2^{1-d})^m}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This exact expression can be efficiently evaluated in &lt;span class=&quot;math math-inline&quot;&gt;O(h)&lt;&#x2F;span&gt; operations. For &lt;span class=&quot;math math-inline&quot;&gt;m \ll 2^h&lt;&#x2F;span&gt;
we can approximate it well with &lt;span class=&quot;math math-inline&quot;&gt;m \cdot (h - \log_2 m  - 0.89)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;support-1&quot;&gt;Support&lt;&#x2F;h2&gt;
&lt;p&gt;Clearly for &lt;span class=&quot;math math-inline&quot;&gt;m=0&lt;&#x2F;span&gt; the support is &lt;span class=&quot;math math-inline&quot;&gt;R \in \{0\}&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;m &amp;gt; 0&lt;&#x2F;span&gt; the minimum number of revealed nodes is attained when a maximally sized subtree is fully filled, which gives&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
R_{\min} = h - \min(h, \floor{\log_2 m}) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An easy upper bound for the number of revealed nodes is &lt;span class=&quot;math math-inline&quot;&gt;\sum_{d \in [1, h]} \min(2^d, m)&lt;&#x2F;span&gt; but this is not tight. The maximum is attained by allocating each opening a maximally sized subtree. A greedy procedure suffices where for each additional opening we pick largest subtree containing a single opening and split it into its two child subtrees each containing one opening. When &lt;span class=&quot;math math-inline&quot;&gt;m \ge 2^{h-1}&lt;&#x2F;span&gt; we reach the maximum of &lt;span class=&quot;math math-inline&quot;&gt;2^{h-1}&lt;&#x2F;span&gt; revealed nodes and further openings are made to overlap. For &lt;span class=&quot;math math-inline&quot;&gt;0 &amp;lt; m &amp;lt; 2^{h-1}&lt;&#x2F;span&gt; we can write the maximum as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
R_{\max} = 2^{\ceil{\log_2 m}} + m \cdot (h - \ceil{\log_2 m} - 1)\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; support&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) -&amp;gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    k_min&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; min&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;floor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;log2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k_min&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;ceil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;log2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k_min&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;probability-mass-function-1&quot;&gt;Probability Mass Function&lt;&#x2F;h2&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;p_{h,m}(k) = \Pr[R = k]&lt;&#x2F;span&gt; be the probability mass function. The base cases &lt;span class=&quot;math math-inline&quot;&gt;p_{h,0}(k)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p_{0,m}(k)&lt;&#x2F;span&gt; are &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; when &lt;span class=&quot;math math-inline&quot;&gt;k=0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; otherwise as before. For the inductive step, consider a tree of height &lt;span class=&quot;math math-inline&quot;&gt;h &amp;gt; 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m &amp;gt; 0&lt;&#x2F;span&gt; openings. The root has two children, each of which is the root of a subtree of height &lt;span class=&quot;math math-inline&quot;&gt;h-1&lt;&#x2F;span&gt;. Let &lt;span class=&quot;math math-inline&quot;&gt;m_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m_2&lt;&#x2F;span&gt; be the number of openings that fall in the left and right subtree respectively. Then there are two cases to consider: Either only one subtree has openings, and &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is the number of revealed nodes in that subtree plus one for the current node. Or both subtrees have openings and &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is the sum of the revealed nodes, but doesn&#x27;t contribute itself. This gives the recurrence&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
p_{h+1,m}(k) &amp;amp;= 2^{1-m} \cdot p_{h,m}(k - 1) + \phantom{x} \\
&amp;amp;\phantom{=} 2^{-m} \cdot \sum_{m&amp;#39;=[1,m)} \binom{m}{m&amp;#39;}
\sum_{k&amp;#39; \in [0,k]} p_{h,m&amp;#39;}(k&amp;#39;) \cdot p_{h,m - m&amp;#39;}(k - k&amp;#39;)
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This recurrence leads to a reasonably efficient implementation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-decorator z-python z-entity z-name z-function z-decorator z-python&quot;&gt;@cache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ndarray&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    k_min&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k_max&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; support&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    out&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k_max&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; dtype&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;float64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    f1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;    out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;f1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        f1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        f2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; pmf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        conv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;convolve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;f1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; f2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[:&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;conv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; float&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;comb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; conv    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;25&#x2F;merkle-multi-proof&#x2F;revealed_pmf_h20_m200.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;variance-1&quot;&gt;Variance&lt;&#x2F;h2&gt;
&lt;p&gt;We are going to end up with cubic and quartic terms, so before we start let&#x27;s extend our definition of &lt;span class=&quot;math math-inline&quot;&gt;p_d, p_{de}&lt;&#x2F;span&gt; to its final and most general form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
p_{d_0 d_2 \dots d_{n-1}}
&amp;amp;= \Pr\p{\forall_{j \in [0,n)}\ I_{d_j,i_j} = 1 \mid L_{d_i,i_j} \text{ pairwise disjoint}} \\
&amp;amp;= \Exp{\prod_{j \in [0,n)}  I_{d_j,i_j}} \\
&amp;amp;= \sum_{\setn J \subseteq [0,n)}
   (-1)^{\bar{\setn J}} \cdot
   \p{1 - \sum_{j \in \setn J} 2^{-d_j}}^m \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is obtained by inclusion-exclusion, extending the two-variable case above. It is again symmetric in its arguments.&lt;&#x2F;p&gt;
&lt;p&gt;As before, we start from &lt;span class=&quot;math math-inline&quot;&gt;\Var{R} = \sum_{d, e \in [1,h] } \Cov{R_d, R_e}&lt;&#x2F;span&gt; and use the identity &lt;span class=&quot;math math-inline&quot;&gt;\Cov{R_d, R_e} = \Exp{R_d \cdot R_e} - \Exp{R_d} \cdot \Exp{R_e}&lt;&#x2F;span&gt;, which means we need to compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mathbb{E}[R_d \cdot R_e] &amp;amp;= \sum_{\substack{
  i \in [0, 2^{d-1}) \\
  j \in [0, 2^{e-1})
}} \mathbb{E}[S_{d,i} \cdot S_{e,j}] \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We consider three cases, depending on the relationship between the sibling pairs &lt;span class=&quot;math math-inline&quot;&gt;(d,i)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(e,j)&lt;&#x2F;span&gt;: they can be identical, descendant&#x2F;ancestor, or disjoint.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Identical Sibling Pairs.&lt;&#x2F;strong&gt; When &lt;span class=&quot;math math-inline&quot;&gt;d = e&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;i = j&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;S_{d,i} \cdot S_{e,j} = S_{d,i}^2 = S_{d,i}&lt;&#x2F;span&gt;, the latter follows from indicators being &lt;span class=&quot;math math-inline&quot;&gt;\{0, 1\}&lt;&#x2F;span&gt;. We have &lt;span class=&quot;math math-inline&quot;&gt;\Exp{S_{d,i}} = 2 \cdot (p_d - p_{dd})&lt;&#x2F;span&gt; as before. There are &lt;span class=&quot;math math-inline&quot;&gt;2^{d-1}&lt;&#x2F;span&gt; such cases with total contribution to &lt;span class=&quot;math math-inline&quot;&gt;\Exp{R_d, R_e}&lt;&#x2F;span&gt; of&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
2^d \cdot (p_d - p_{dd}) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Ancestor&#x2F;Descendant Sibling Pairs.&lt;&#x2F;strong&gt; Without loss of generality assume &lt;span class=&quot;math math-inline&quot;&gt;d &amp;lt; e&lt;&#x2F;span&gt; and that the sibling pair &lt;span class=&quot;math math-inline&quot;&gt;(e,j)&lt;&#x2F;span&gt; is a descendant of left branch &lt;span class=&quot;math math-inline&quot;&gt;(d, 2 \cdot i)&lt;&#x2F;span&gt;. Then from &lt;span class=&quot;math math-inline&quot;&gt;S_{e,j} = 1&lt;&#x2F;span&gt; follows &lt;span class=&quot;math math-inline&quot;&gt;I_{d,2i} = 1&lt;&#x2F;span&gt; and thus &lt;span class=&quot;math math-inline&quot;&gt;S_{d,i} = 1 - I_{d,2i+1}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\Exp{S_{d,i} \cdot S_{e,j}}
&amp;amp;= \Exp{\p{1 - I_{d,2i+1}} \cdot \p{I_{e,2j} + I_{e,2j+1} - 2 \cdot I_{e,2j} \cdot I_{e,2j+1}}} \\
&amp;amp;= \Exp{\begin{align*}
&amp;amp;I_{e,2j} + I_{e,2j+1} - 2 \cdot I_{e,2j} \cdot I_{e,2j+1}\\
&amp;amp;-I_{d,2i+1} \cdot I_{e,2j} - I_{d,2i+1} \cdot I_{e,2j+1} \\
&amp;amp;+2 \cdot I_{d,2i+1} \cdot I_{e,2j} \cdot I_{e,2j+1}
\end{align*}} \\
&amp;amp;= 2\cdot \p{ p_e - p_{ee} - p_{de} + p_{dee} }
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the last line follows from all the &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt;s being pairwise disjoint. There are &lt;span class=&quot;math math-inline&quot;&gt;2^{e - 1}&lt;&#x2F;span&gt; sibling pairs at level &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; that each have a unique ancestor at level &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; (which is either left or right in a pair). So the total contribution to &lt;span class=&quot;math math-inline&quot;&gt;\Exp{R_d, R_e}&lt;&#x2F;span&gt; for from this case is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
2^e \cdot \p{ p_e - p_{ee} - p_{de} + p_{dee} } \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Disjoint Pairs.&lt;&#x2F;strong&gt; In this case all &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt;s are disjoint and we just have a big tedious expansion to do&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\Exp{S_{d,i} \cdot S_{e,j}}
&amp;amp;= \p{I_{d,2i} + I_{d,2i+1} - 2 \cdot I_{d,2i} \cdot I_{d,2i+1}} \\
&amp;amp;\phantom{=} \cdot \p{I_{e,2j} + I_{e,2j+1} - 2 \cdot I_{e,2j} \cdot I_{e,2j+1}} \\
&amp;amp;= 4 \cdot \p{p_{de} - p_{dde} - p_{dee} + p_{ddee}} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;span class=&quot;math math-inline&quot;&gt;d &amp;lt; e&lt;&#x2F;span&gt; there are &lt;span class=&quot;math math-inline&quot;&gt;2^{d-1} \cdot 2^{e-1} - 2^{e - 1}&lt;&#x2F;span&gt; such disjoint pairs. Additionally there are &lt;span class=&quot;math math-inline&quot;&gt;2^{d-1} \cdot (2^{d-1} - 1)&lt;&#x2F;span&gt; disjoint pairs when &lt;span class=&quot;math math-inline&quot;&gt;d = e&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Putting this all together we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mathbb{E}[R_d \cdot R_e] 
&amp;amp;= \begin{cases}
\begin{align*}
&amp;amp;2^d \cdot (p_d - p_{dd}) + \\
&amp;amp;(2^{2\cdot d} - 2^{d+1})\cdot \p{p_{dd} - 2 \cdot p_{ddd} + p_{dddd}}
\end{align*}
&amp;amp; \text{if } d = e \\[1.5em]
\begin{align*}
&amp;amp;2^e \cdot \p{ p_e - p_{ee} - p_{de} + p_{dee} } + \\
&amp;amp;\p{2^{d + e} - 2^{e + 1}} \cdot \p{p_{de} - p_{dde} - p_{dee} + p_{ddee}}
\end{align*}
&amp;amp; \text{if } d &amp;lt; e \\[1.5em]
\text{(same as $d &amp;lt; e$ with $d, e$ swapped)} &amp;amp; \text{if } d &amp;gt; e \\
\end{cases}
\\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Recall &lt;span class=&quot;math math-inline&quot;&gt;\Var{R} = \sum_{d, e \in [1,h] } \Exp{R_d \cdot R_e}  - \p{\Exp{R}}^2&lt;&#x2F;span&gt; and we have &lt;span class=&quot;math math-inline&quot;&gt;\Exp{R}&lt;&#x2F;span&gt; from before. We could expand everything out into a huge expression for &lt;span class=&quot;math math-inline&quot;&gt;\Var{R}&lt;&#x2F;span&gt;, but it is not very insightful. Instead we&#x27;ll give a way to compute &lt;span class=&quot;math math-inline&quot;&gt;\Exp{R}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\Var{R}&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;O(h^2)&lt;&#x2F;span&gt; time:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; exact_moments&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;ds&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;ds&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        total&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; J&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            sign&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;J&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;bit_count&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            sum_inv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; **&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;ds&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;J&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            total&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sign&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;log1p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;sum_inv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sum_inv&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; total&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pddd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdddd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pddd&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdddd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            pe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pde&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pee&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            pdee&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdde&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pddee&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pee&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdee&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdde&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pdee&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; pddee&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    var&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mean&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;normal-approximation-1&quot;&gt;Normal Approximation&lt;&#x2F;h2&gt;
&lt;p&gt;With the exact moments we can again construct a normal approximation as &lt;span class=&quot;math math-inline&quot;&gt;\Pr[R = k] \approx {\setn N}\!\p{\Exp{R}, \Var{R}}&lt;&#x2F;span&gt;. We compute the approximate PMF &lt;span class=&quot;math math-inline&quot;&gt;\hat{p}_{h,m}(k)&lt;&#x2F;span&gt; by evaluating the normal distribution at each integer in the support and normalizing as before (identical code).&lt;&#x2F;p&gt;
&lt;p&gt;We can then compute the KL-divergence between the exact PMF and the approximate PMF. For the previous graph of &lt;span class=&quot;math math-inline&quot;&gt;h = 20&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m = 200&lt;&#x2F;span&gt;, the &lt;span class=&quot;math math-inline&quot;&gt;D_{KL} = 0.0024\ \mathrm{bits}&lt;&#x2F;span&gt; which is very small. The linear scale graphs are visually indistinguishable. The log graphs show an underestimation of the left tail and overestimation of the right tail. This is desirable as it means the normal approximation is conservative in estimating the maximum.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;25&#x2F;merkle-multi-proof&#x2F;revealed-normal-kl-divergence.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This time, KL-divergence between the exact PMF and the normal approximation is below &lt;span class=&quot;math math-inline&quot;&gt;0.01\ \mathrm{bits}&lt;&#x2F;span&gt; for essentially the entire range &lt;span class=&quot;math math-inline&quot;&gt;m &amp;gt; 75&lt;&#x2F;span&gt; and below &lt;span class=&quot;math math-inline&quot;&gt;0.1&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;m &amp;gt; 5&lt;&#x2F;span&gt;. For small &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; the discrete nature of the PMF is more pronounced and the normal approximation is less accurate. But fortunately there the exact PMF can be computed quickly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;beta-binomial-approximation-1&quot;&gt;Beta-Binomial Approximation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;25&#x2F;merkle-multi-proof&#x2F;revealed-betabin-kl-divergence.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;circuit-verifier&quot;&gt;Circuit Verifier&lt;&#x2F;h1&gt;
&lt;p&gt;For implementation in circuits we need a Merkle-proof verifier where the control flow does not depend on the proof. We are allowed to do a pre-processing step on the proof before we hand it to the circuit. The simple solution is to preprocess into &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; single-proof verifications. This requires &lt;span class=&quot;math math-inline&quot;&gt;m \cdot h&lt;&#x2F;span&gt; hashes to be computed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;merkle-caps&quot;&gt;Merkle Caps&lt;&#x2F;h2&gt;
&lt;p&gt;We can improve on this using a &lt;em&gt;Merkle cap&lt;&#x2F;em&gt;: First we compute all nodes up to level &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt; using only &lt;span class=&quot;math math-inline&quot;&gt;2^l - 1&lt;&#x2F;span&gt; hashes. Then each opening only requires &lt;span class=&quot;math math-inline&quot;&gt;h - l&lt;&#x2F;span&gt; hashes to be computed up to level &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;. The total number of hashes is &lt;span class=&quot;math math-inline&quot;&gt;2^l - 1 + m \cdot (h - l)&lt;&#x2F;span&gt; which is minimized when&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
l_{\mathrm{min}} = \min(h, \floor{ \log_2 m}) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One complication with this approach is that we may not know all the values at level &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;. We could solve this by having the prover provide all nodes at level &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;, at slightly increased proof size. Another solution is to explicitly support missing values in the circuit. We pursue the latter as it makes Merkle caps a pure verifier side optimization.&lt;&#x2F;p&gt;
&lt;p&gt;There are only two cases to consider: either both children are present, or both children are missing. The case where exactly one child is missing is impossible, as any colored node&#x27;s children are all computed or revealed, and any uncolored node&#x27;s children are all missing. When both children are present, we compute the hash as normal. When both children are missing, we substitute a hint value. The hint value can be either a hash, or &lt;code&gt;None&lt;&#x2F;code&gt; if the parent is also missing. The augmented hash function is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; hash_with_missing&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;    left&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;    right&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;    hint&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Option&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    match&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;left&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; right&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Some&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Some&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Some&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-macro z-rust&quot;&gt; unreachable!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When this computes the correct root hash, all the values at level &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt; are either correctly computed or marked missing. For practical implementation we can use a flag value such as the all-zeros hash instead of an &lt;code&gt;Option&amp;lt;Hash&amp;gt;&lt;&#x2F;code&gt;. The overhead of the modified hash function should then be minimal.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;number-of-computed-hashes&quot;&gt;Number of Computed Hashes&lt;&#x2F;h2&gt;
&lt;p&gt;The number of computed hashes at each level &lt;span class=&quot;math math-inline&quot;&gt;d &amp;lt; l&lt;&#x2F;span&gt; is always &lt;span class=&quot;math math-inline&quot;&gt;2^d&lt;&#x2F;span&gt; as the Merkle cap is fully computed up to level &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;. For levels &lt;span class=&quot;math math-inline&quot;&gt;d \ge l&lt;&#x2F;span&gt; there are &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; individual paths of length &lt;span class=&quot;math math-inline&quot;&gt;h - l&lt;&#x2F;span&gt;. Thus the total number of computed nodes is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C_d = \begin{cases}
2^d &amp;amp; \text{if } d &amp;lt; l_{\min} \\
m &amp;amp; \text{if } l_{\min} \le d &amp;lt; h \\
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and the total number of computed hashes is as we saw before&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C = \sum_{d \in [0,h)} C_d = 2^{l_{\min}} - 1 + m \cdot (h - l_{\min})\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Inner Product Commitments</title>
        <published>2025-10-14T00:00:00+00:00</published>
        <updated>2025-10-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/ipc/"/>
        <id>https://2π.com/25/ipc/</id>
        
        <content type="html" xml:base="https://2π.com/25/ipc/">&lt;h1 id=&quot;inner-product-commitment-schemes&quot;&gt;Inner Product Commitment Schemes&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\Norm#1{\left\lVert{#1}\right\rVert}
\gdef\range#1{\left[#1\right)}
\gdef\setn#1{\mathcal{#1}}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 1.&lt;&#x2F;strong&gt; An &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;-Inner Product Commitment Scheme&lt;&#x2F;em&gt; is a tuple of algorithms &lt;span class=&quot;math math-inline&quot;&gt;(\mathsf{commit}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify})&lt;&#x2F;span&gt; such that.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathsf{commit}&lt;&#x2F;span&gt; algorithm takes a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v \in \F_q^n&lt;&#x2F;span&gt; and outputs a commitment &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt; algorithm takes &lt;span class=&quot;math math-inline&quot;&gt;\vec v, C&lt;&#x2F;span&gt;, a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^n&lt;&#x2F;span&gt;, and a value &lt;span class=&quot;math math-inline&quot;&gt;y \in \F_q&lt;&#x2F;span&gt; and outputs a proof &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; that the inner product &lt;span class=&quot;math math-inline&quot;&gt;\vec v \cdot \vec w&lt;&#x2F;span&gt; equals &lt;span class=&quot;math math-inline&quot;&gt;y&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; algorithm takes &lt;span class=&quot;math math-inline&quot;&gt;C, \vec w, y, \pi&lt;&#x2F;span&gt; and outputs true if the proof is valid and false otherwise.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Let&#x27;s look at how Ligerito and WHIR construct such a scheme.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tree-occupancy-distributions&quot;&gt;Tree Occupancy Distributions&lt;&#x2F;h2&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 2.&lt;&#x2F;strong&gt; The &lt;em&gt;Occupancy Distribution&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{D}(n, m)&lt;&#x2F;span&gt; is the distribution by throwing &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; balls uniformly at random into &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; bins and counting the number of bins which contain at least one ball. Given &lt;span class=&quot;math math-inline&quot;&gt;X \sim \mathcal{D}(n, m)&lt;&#x2F;span&gt;, the probability that &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; takes the value &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr[X = k] = \frac{\binom{m}{k} \cdot S(n, k) \cdot k!}{m^n}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;S(n, k)&lt;&#x2F;span&gt; is the Stirling number of the second kind.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;linear-codes&quot;&gt;Linear Codes&lt;&#x2F;h2&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 2.&lt;&#x2F;strong&gt; A &lt;em&gt;Linear Code&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; over a field &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; is a subspace of &lt;span class=&quot;math math-inline&quot;&gt;\F_q^n&lt;&#x2F;span&gt;. The elements of &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; are called &lt;em&gt;codewords&lt;&#x2F;em&gt;. The &lt;em&gt;dimension&lt;&#x2F;em&gt; of the code is the dimension of &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; as a vector space over &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;. The &lt;em&gt;minimum distance&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; of the code is the minimum Hamming distance between any two distinct codewords in &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;. A linear code with parameters &lt;span class=&quot;math math-inline&quot;&gt;[n, k, d]&lt;&#x2F;span&gt; has &lt;em&gt;length&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, &lt;em&gt;dimension&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;, &lt;em&gt;minimum distance&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;, &lt;em&gt;rate&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\rho = k&#x2F;n&lt;&#x2F;span&gt; and &lt;em&gt;expansion&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\rho^{-1} = n &#x2F;k&lt;&#x2F;span&gt;. The generator matrix &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt; of a linear code is a &lt;span class=&quot;math math-inline&quot;&gt;k \times n&lt;&#x2F;span&gt; matrix whose rows form a basis for the code.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;em&gt;Hamming Weight&lt;&#x2F;em&gt; Take &lt;span class=&quot;math math-inline&quot;&gt;\Norm{\vec v}_0&lt;&#x2F;span&gt; to mean the number of non-zero entries in &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;. Despite notation it is not a proper norm as it fails homogeneity.&lt;&#x2F;p&gt;
&lt;p&gt;We will work over vectors of size &lt;span class=&quot;math math-inline&quot;&gt;2^k&lt;&#x2F;span&gt; for some integer &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;. These can be reshaped into matrices of size &lt;span class=&quot;math math-inline&quot;&gt;2^l \times 2^{k-l}&lt;&#x2F;span&gt; for some integer &lt;span class=&quot;math math-inline&quot;&gt;l \in \range{0,k}&lt;&#x2F;span&gt;. Denote this &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Mat}_{k\,l}(\vec v)&lt;&#x2F;span&gt;, where we can drop the &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; if it is clear from context.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;commitment&quot;&gt;Commitment&lt;&#x2F;h2&gt;
&lt;p&gt;Given a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v \in \F_q^n&lt;&#x2F;span&gt;, the commitment algorithm works as follows:&lt;&#x2F;p&gt;
&lt;p&gt;Parameters:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Field &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Vector size &lt;span class=&quot;math math-inline&quot;&gt;n = 2^k&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Matrix dimensions &lt;span class=&quot;math math-inline&quot;&gt;l \in \range{0,k}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Vector commitment scheme &lt;span class=&quot;math math-inline&quot;&gt;\setn{VC}&lt;&#x2F;span&gt; of size &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&lt;&#x2F;span&gt; with parameters &lt;span class=&quot;math math-inline&quot;&gt;[m, 2^{k - l}, d]&lt;&#x2F;span&gt; and generator matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat G&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Code &lt;span class=&quot;math math-inline&quot;&gt;\setn C&amp;#39;&lt;&#x2F;span&gt; with parameters &lt;span class=&quot;math math-inline&quot;&gt;[m&amp;#39;, 2^{k - l}, d&amp;#39;]&lt;&#x2F;span&gt; and generator matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat G&amp;#39;&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Number of out-of-domain samples &lt;span class=&quot;math math-inline&quot;&gt;n_o&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reshape &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt; into a matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat V&lt;&#x2F;span&gt; of size &lt;span class=&quot;math math-inline&quot;&gt;2^l \times 2^{k -l}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Encode rows using the generator matrix: &lt;span class=&quot;math math-inline&quot;&gt;\mat V&amp;#39; = \mat V \cdot \mat G&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Commit to the columns of &lt;span class=&quot;math math-inline&quot;&gt;\mat V&amp;#39;&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;\setn{VC}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Pick challenges &lt;span class=&quot;math math-inline&quot;&gt;\setn{S} \subseteq \range{0, n&amp;#39;}&lt;&#x2F;span&gt; by uniformly drawing &lt;span class=&quot;math math-inline&quot;&gt;n_0&lt;&#x2F;span&gt; samples.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;\mat V&amp;#39;&amp;#39;&lt;&#x2F;span&gt; by encoding the rows of &lt;span class=&quot;math math-inline&quot;&gt;\mat V&amp;#39;&amp;#39; = \mat V \cdot \mat G&amp;#39;_{\setn S}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Send &lt;span class=&quot;math math-inline&quot;&gt;\mat V&amp;#39;&amp;#39;&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Transcript size (ignoring dedpulication in &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt;):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{hash} + n_0 \cdot 2^l \cdot \mathsf{field}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;opening&quot;&gt;Opening&lt;&#x2F;h2&gt;
&lt;p&gt;Parameters:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Commitment parameters as above.&lt;&#x2F;li&gt;
&lt;li&gt;Vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^n&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Value &lt;span class=&quot;math math-inline&quot;&gt;y \in \F_q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Number of in-domain samples &lt;span class=&quot;math math-inline&quot;&gt;n_i&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Number of folds &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reshape &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; into a matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat W&lt;&#x2F;span&gt; of size &lt;span class=&quot;math math-inline&quot;&gt;2^l \times 2^{k -l}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Pick challenges &lt;span class=&quot;math math-inline&quot;&gt;\setn{T} \subseteq \range{0, 2^{k-l}}&lt;&#x2F;span&gt; by uniformly drawing &lt;span class=&quot;math math-inline&quot;&gt;n_i&lt;&#x2F;span&gt; samples.&lt;&#x2F;li&gt;
&lt;li&gt;Compute $\&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;adding-zero-knowledge&quot;&gt;Adding Zero-Knowledge&lt;&#x2F;h2&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;1586&quot;&gt;ACFY24&lt;&#x2F;a&gt; Gal Arnon, Alessandro Chiesa, Giacomo Fenzi, Eylon Yogev (2024). WHIR: Reed–Solomon Proximity Testing with Super-Fast Verification.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;1187&quot;&gt;NA25&lt;&#x2F;a&gt; Andrija Novakovic, Guillermo Angeris (2025). Ligerito: A Small and Concretely Fast Polynomial Commitment Scheme.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
k \cdot \p{\frac{n}{k} + \log \frac{n}{k}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;ethereum.github.io&#x2F;consensus-specs&#x2F;ssz&#x2F;merkle-proofs&#x2F;?utm_source=chatgpt.com#merkle-multiproofs&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Succinct Multi-Linear Extensions</title>
        <published>2025-10-10T00:00:00+00:00</published>
        <updated>2025-10-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/succint-mle/"/>
        <id>https://2π.com/25/succint-mle/</id>
        
        <content type="html" xml:base="https://2π.com/25/succint-mle/">&lt;h1 id=&quot;succinct-multi-linear-extensions&quot;&gt;Succinct Multi-Linear Extensions&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\ceil#1{\left\lceil{#1}\right\rceil}
\gdef\floor#1{\left\lfloor{#1}\right\rfloor}
\gdef\set#1{\left\{#1\right\}}
\gdef\range#1{\left[#1\right)}
\gdef\setn#1{\mathcal{#1}}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Many interactive proof systems rely on multi-linear extensions (MLEs) that can be efficiently evaluated, e.g. Jolt (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;611&quot;&gt;NTZ25&lt;&#x2F;a&gt; appendix A for Jolt, see also the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;a16z&#x2F;jolt&#x2F;tree&#x2F;35a4df4df70e82408b899478e531ad6328405c86&#x2F;jolt-core&#x2F;src&#x2F;zkvm&#x2F;lookup_table&quot;&gt;source code&lt;&#x2F;a&gt; for many examples), SuperSpartan (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;552&quot;&gt;STW23&lt;&#x2F;a&gt; section 5) , or GKR (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;351&quot;&gt;Tha13&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;ProofsArgsAndZK.pdf&quot;&gt;Tha23&lt;&#x2F;a&gt; section 4.6.6).&lt;&#x2F;p&gt;
&lt;p&gt;Despite their importance, it is not easy to come up with specific efficient MLEs, or even get a sense of what is possible. At least, that was the case for me until I read &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;917&quot;&gt;HJR+25&lt;&#x2F;a&gt; &quot;Jagged Polynomial Commitments&quot; and played with the ideas presented there and in this article. It turns out a lot more is possible than I initially expected! In the process I learned how to&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;avoid needing power-of-two alignment,&lt;&#x2F;li&gt;
&lt;li&gt;arbitrarily mask and move coefficients around to efficiently pack of polynomials,&lt;&#x2F;li&gt;
&lt;li&gt;generally manipulate coefficient indices in a structured way,&lt;&#x2F;li&gt;
&lt;li&gt;trivially construct many common lookup tables,&lt;&#x2F;li&gt;
&lt;li&gt;solve the small field inner product embedding problems from a previous post.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So, time to get good at succinct MLEs!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;multi-linear-extensions&quot;&gt;Multi-Linear Extensions&lt;&#x2F;h1&gt;
&lt;p&gt;Here follows a brief review of multi-linear extensions (MLEs) and their properties. For a more extensive treatment see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;ProofsArgsAndZK.pdf&quot;&gt;Tha23&lt;&#x2F;a&gt; § 3.5.&lt;&#x2F;p&gt;
&lt;p&gt;Denote with &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{bits}_k: \mathbb{N} \rightarrow \F_q^k&lt;&#x2F;span&gt; the bitvector &lt;span class=&quot;math math-inline&quot;&gt;\vec b \in \{0,1\}^k&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;i = \sum_{j \in [0,k)} b_j \cdot 2^{k-j-1}&lt;&#x2F;span&gt;, i.e. in big-endian order. We will leave the field &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; implicit and often drop the subscript &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; when it is clear from context.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 1.&lt;&#x2F;strong&gt; A &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-variable &lt;em&gt;Multi-Linear Extension (MLE) evaluation&lt;&#x2F;em&gt; is a map&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{MLE}_k: \F_q^{2^k} \times \F_q^k \rightarrow \F_q
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;such that &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}_k(\vec w, \mathsf{bits}(i)) = w_i&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;i \in [0,2^k)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}_k(\vec w, \vec r)&lt;&#x2F;span&gt; is a polynomial in &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; of degree at most 1 in each variable.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Now we show this map is unique and present several equivalent definitions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 2.&lt;&#x2F;strong&gt; The MLE evaluation map is unique and equivalent to the recursion&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mathsf{MLE}_0([w_0], []) &amp;amp;= w_0 \\[4pt]
\mathsf{MLE}_{k+1}([\vec w_0 \, \vec w_1], [r_0 \, \vec r]) &amp;amp;= u_0 + r_0 \cdot (u_1 - u_0) \\
\text{ where } u_i &amp;amp;= \mathsf{MLE}_k(\vec w_i, \vec r) \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; Uniqueness follows from the fact that there are &lt;span class=&quot;math math-inline&quot;&gt;2^k&lt;&#x2F;span&gt; interpolation points and a polynomial of degree at most 1 in each of &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; variable has at most &lt;span class=&quot;math math-inline&quot;&gt;2^k&lt;&#x2F;span&gt; coefficients.&lt;&#x2F;p&gt;
&lt;p&gt;Multi-linearity in &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt;: The base case is trivial. For the inductive case, it is a linear combination of &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}&lt;&#x2F;span&gt;s in the &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; variables and is linear in the new &lt;span class=&quot;math math-inline&quot;&gt;r_0&lt;&#x2F;span&gt; variable.&lt;&#x2F;p&gt;
&lt;p&gt;Interpolation: The base case is trivial. For the inductive case, observe that for &lt;span class=&quot;math math-inline&quot;&gt;b \in \{0,1\}, i \in [0,2^k)&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{MLE}_{k+1}([\vec w_0 \, \vec w_1], [b \, \mathsf{bits}_k(i)])
= \mathsf{MLE}_k(\vec w_b, \mathsf{bits}_k(i)) = w_{b, i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and since concatenation results in &lt;span class=&quot;math math-inline&quot;&gt;[\vec w_0 \, \vec w_1]_{b \cdot 2^k + i} = w_{b,i}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{bits}_{k+1}(b \cdot 2^k + i) = [b\, \mathsf{bits}_k(i)]&lt;&#x2F;span&gt;, the interpolation property holds.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;This definition can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;2^k-1&lt;&#x2F;span&gt; field multiplications, additions and subtractions. This makes it an &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; operation algorithm where &lt;span class=&quot;math math-inline&quot;&gt;n = 2^k&lt;&#x2F;span&gt;. Since in general all &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; coefficients of &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; are needed to compute the result, &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; is optimal. But as we will see, if &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; has some special structure, we can do better.&lt;&#x2F;p&gt;
&lt;p&gt;Another common and useful expression is in terms of Lagrange basis polynomials, which in the context of MLEs are commonly denoted as &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{eq}_i(\vec r)&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 3.&lt;&#x2F;strong&gt; The MLE evaluation map is equivalent to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{MLE}_k(\vec w, \vec r) = \sum_{i \in [0, 2^k)} \mathsf{eq}_{k\,i}(\vec r) \cdot w_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{eq}_{k\,i}(\vec r) = \prod_{j \in [0, k)} \begin{cases}
1- r_j &amp;amp; \mathsf{bits}_k(i)_j = 0 \\
r_j &amp;amp; \mathsf{bits}_k(i)_j = 1  \text{.}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; Observe that &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{eq}_i(\vec r)&lt;&#x2F;span&gt; is linear in each &lt;span class=&quot;math math-inline&quot;&gt;r_j&lt;&#x2F;span&gt; and for &lt;span class=&quot;math math-inline&quot;&gt;i,j \in [0, 2^k)&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{eq}_i(\mathsf{bits}(j)) =
\begin{cases} 1 &amp;amp; i = j \\ 0 &amp;amp; i \neq j \end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which makes &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{eq}_i&lt;&#x2F;span&gt; a multi-linear Lagrange basis for &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}^k&lt;&#x2F;span&gt;. The properties of the expression for &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}&lt;&#x2F;span&gt; follow from this.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;We can rewrite this lemma using the tensor product notation &lt;span class=&quot;math math-inline&quot;&gt;\otimes&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 4.&lt;&#x2F;strong&gt; The MLE evaluation map is equivalent to the inner product&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{MLE}_k(\vec w, \vec r) =
\vec w \cdot \p{\bigotimes_{i \in \range{0,k}} \begin{bmatrix} 1 - r_i  \\ r_i \end{bmatrix} } \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;From this equivalent definition it follows directly that the MLE is linear in the &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; argument:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 5.&lt;&#x2F;strong&gt; (&lt;em&gt;Linearity&lt;&#x2F;em&gt;) For all &lt;span class=&quot;math math-inline&quot;&gt;\alpha, \beta \in \F_q&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec w, \vec w&amp;#39; \in \F_q^{2^k}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_q^k&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{MLE}(\alpha \cdot \vec w + \beta \cdot \vec w&amp;#39;, \vec r) =
\alpha \cdot \mathsf{MLE}(\vec w, \vec r) +
\beta \cdot \mathsf{MLE}(\vec w&amp;#39;, \vec r) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;However, it does not follow that the MLE is linear in the &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; argument. Instead it is multi-linear, i.e. linear in each variable separately, which is a much weaker property.&lt;&#x2F;p&gt;
&lt;p&gt;The MLE evaluation respects the symmetries of the hyper-cube. The hypercube &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}^k&lt;&#x2F;span&gt; has a large symmetry group, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hyperoctahedral_group&quot;&gt;hyper-octahedral group&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;B_k&lt;&#x2F;span&gt; of order &lt;span class=&quot;math math-inline&quot;&gt;k! \cdot 2^k&lt;&#x2F;span&gt; which is generated by permutations of the &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; axes and reflections in each axis. The MLE respects these symmetries in the following sense:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 6.&lt;&#x2F;strong&gt; (&lt;em&gt;Hypercube Symmetries&lt;&#x2F;em&gt;) Every symmetry of the hyper-cube &lt;span class=&quot;math math-inline&quot;&gt;\sigma \in B_k&lt;&#x2F;span&gt; induces an equivalent symmetry on the &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{MLE}_k(\sigma_w(\vec w), \vec r) = \mathsf{MLE}_k(\vec w, \sigma_r(\vec r)) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; It suffices to show this for the generators of the group, which come in two types:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Permutation of axes&lt;&#x2F;em&gt;: &lt;span class=&quot;math math-inline&quot;&gt;\sigma_r(\vec r) = (r_{\pi(0)}, \dots, r_{\pi(k-1)})&lt;&#x2F;span&gt; for some permutation &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;[0,k)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\sigma_w(\vec w) = (w_{\pi&amp;#39;(0)}, \dots, w_{\pi&amp;#39;(2^k - 1)})&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\pi&amp;#39;&lt;&#x2F;span&gt; is the permutation on &lt;span class=&quot;math math-inline&quot;&gt;[0,2^k)&lt;&#x2F;span&gt; induced by &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; on the bit representations of the indices.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Reflection in axis &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;: &lt;span class=&quot;math math-inline&quot;&gt;\sigma_r(\vec r) = (r_0, \dots, 1 - r_j, \dots, r_{k-1})&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\sigma_w(\vec w) = (w_{0 \oplus 2^j}, \dots, w_{i \oplus 2^j}, \dots, w_{(2^k - 1)  \oplus 2^j})&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\oplus&lt;&#x2F;span&gt; is bitwise XOR.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;It is sufficient to show that the left and right side of the equation are MLEs and agree on the interpolation points &lt;span class=&quot;math math-inline&quot;&gt;\set{0,1}^k&lt;&#x2F;span&gt;. The only non-trivial case is the right side of the reflection, where we note that &lt;span class=&quot;math math-inline&quot;&gt;1 - r_j&lt;&#x2F;span&gt; is still linear in &lt;span class=&quot;math math-inline&quot;&gt;r_j&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;The ability to permute variables plays nicely with other lemma&#x27;s that allow us to split or combine variables. For example, we can compose two MLE evaluations into one:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 7.&lt;&#x2F;strong&gt; (&lt;em&gt;Tensor Composition&lt;&#x2F;em&gt;) Given &lt;span class=&quot;math math-inline&quot;&gt;k, k&amp;#39;&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^{2^k}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39; \in \F_q^{2^{k&amp;#39;}}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_q^k&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;\vec r&amp;#39; \in \F_q^{k&amp;#39;}&lt;&#x2F;span&gt;  we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{MLE}_k(\vec w, \vec r) \cdot \mathsf{MLE}_k(\vec w&amp;#39;, \vec r&amp;#39;) = \mathsf{MLE}_{k+k&amp;#39;}(\vec w \otimes \vec w&amp;#39;, [\vec r\, \vec r&amp;#39;]) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;In the opposite direction, factoring an &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}&lt;&#x2F;span&gt; is hard as &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; doesn&#x27;t generally have a tensor decomposition. But when we fix &lt;span class=&quot;math math-inline&quot;&gt;\vec r&amp;#39;&lt;&#x2F;span&gt; to a bitvector we can do it:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 8.&lt;&#x2F;strong&gt; (&lt;em&gt;Partial Fixing&lt;&#x2F;em&gt;) Given  &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^{2^{k +l}}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_q^k&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;\vec b \in \set{0,1}^{l}&lt;&#x2F;span&gt;  we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{MLE}_{k+l}(\vec w, [\vec r\, \vec b]) = \mathsf{MLE}_{k}(\vec w&amp;#39;, \vec r)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39; \in \F_q^{2^k}&lt;&#x2F;span&gt; is given by &lt;span class=&quot;math math-inline&quot;&gt;w&amp;#39;_i = w_{i \cdot 2^{l} + j}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\vec b = \mathsf{bits}_{l}(j)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;That concludes the basic properties of &lt;em&gt;general&lt;&#x2F;em&gt; MLE evaluations. We will now look at special cases for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; that allow efficient evaluation of &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}_k(\vec w, \vec r)&lt;&#x2F;span&gt;, i.e. sub-linear in the size of &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; or, equivalently, sub-exponential in &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;tensor-weights&quot;&gt;Tensor Weights&lt;&#x2F;h1&gt;
&lt;p&gt;For succinct verification we need to restrict &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; to vectors that allow MLE evaluation in &lt;span class=&quot;math math-inline&quot;&gt;O(\log n)&lt;&#x2F;span&gt; or better (where &lt;span class=&quot;math math-inline&quot;&gt;n = 2^k&lt;&#x2F;span&gt;). A simple but useful class is those where &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; can be decomposed as the tensor product of &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;-vectors.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 9.&lt;&#x2F;strong&gt; Given &lt;span class=&quot;math math-inline&quot;&gt;\vec t_0,\dots,\vec t_{k-1} \in \F_q^2&lt;&#x2F;span&gt;, there is an &lt;span class=&quot;math math-inline&quot;&gt;O(k)&lt;&#x2F;span&gt; algorithm to compute &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}_k(\vec w, \vec r)&lt;&#x2F;span&gt; where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec w = \bigotimes_{i \in [0,k)} \vec t_i \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; Consider the base case &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}_0([1], []) = 1&lt;&#x2F;span&gt; and recursion:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mathsf{MLE}_{k+1}(\vec t_0 \otimes \vec w&amp;#39;, [r_0, \vec r])
&amp;amp;= \p{(\vec t_0)_0 \cdot (1 - r_0) + (\vec t_0)_1 \cdot r_0} \cdot \mathsf{MLE}_k(\vec w&amp;#39;, \vec r)
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The recursive step is linear in &lt;span class=&quot;math math-inline&quot;&gt;r_0&lt;&#x2F;span&gt; and for &lt;span class=&quot;math math-inline&quot;&gt;r_0 \in \{0,1\}&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;(\vec t_0)_0&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;(\vec t_0)_1&lt;&#x2F;span&gt; times the MLE in the remaining variables, which results in the MLE of the tensor product by induction. Finally the algorithm is &lt;span class=&quot;math math-inline&quot;&gt;O(k)&lt;&#x2F;span&gt; since it does &lt;span class=&quot;math math-inline&quot;&gt;O(1)&lt;&#x2F;span&gt; work per variable.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;This class is closed under the hypercube symmetries, as permutations just permute the &lt;span class=&quot;math math-inline&quot;&gt;\vec t_i&lt;&#x2F;span&gt; and reflections swap the two elements of some &lt;span class=&quot;math math-inline&quot;&gt;\vec t_i&lt;&#x2F;span&gt;. We can also scale a tensor program by scaling one of the &lt;span class=&quot;math math-inline&quot;&gt;\vec t_i&lt;&#x2F;span&gt;, but we can not generally add two tensor programs as the sum of two tensor products is not generally a tensor product. However, tensor weights are closed under element-wise multiplication of the weights vectors by taking the element-wise products of the &lt;span class=&quot;math math-inline&quot;&gt;\vec t_i&lt;&#x2F;span&gt;. This extends to element-wise exponentiation, division and inverses.&lt;&#x2F;p&gt;
&lt;p&gt;This is a very useful class of weights, as it allows us to evaluate polynomials in some useful bases. Here are some multi-linear examples:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 10.&lt;&#x2F;strong&gt; (&lt;em&gt;Multi-Linear Monomial Basis&lt;&#x2F;em&gt;)
Given &lt;span class=&quot;math math-inline&quot;&gt;\vec x \in \F_q^k&lt;&#x2F;span&gt; the tensor weights for evaluating a multi-linear polynomial in monomial basis are &lt;span class=&quot;math math-inline&quot;&gt;\vec t_i = \begin{bmatrix} 1 &amp;amp; x_i \end{bmatrix}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 11.&lt;&#x2F;strong&gt; (&lt;em&gt;Multi-Linear Boolean Hypercube Basis&lt;&#x2F;em&gt;)
Given &lt;span class=&quot;math math-inline&quot;&gt;\vec x \in \F_q^k&lt;&#x2F;span&gt; the tensor weights for evaluating a polynomial in the &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}^k&lt;&#x2F;span&gt; multi-linear basis are &lt;span class=&quot;math math-inline&quot;&gt;\vec t_i = \begin{bmatrix} 1 - x_i &amp;amp; x_i \end{bmatrix}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 12.&lt;&#x2F;strong&gt; (&lt;em&gt;General Multi-Linear Hypercube Basis&lt;&#x2F;em&gt;)
Given &lt;span class=&quot;math math-inline&quot;&gt;\vec x \in \F_q^k&lt;&#x2F;span&gt; the tensor weights for evaluating a polynomial in the &lt;span class=&quot;math math-inline&quot;&gt;\{a_i,b_i\}_{i \in [0,k)}&lt;&#x2F;span&gt; multi-linear basis are&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec t_i = \begin{bmatrix}
\displaystyle \frac{x_i - b_i}{a_i - b_i} &amp;amp;
\displaystyle \frac{x_i - a_i}{b_i - a_i}
\end{bmatrix} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; The &lt;span class=&quot;math math-inline&quot;&gt;\set{0, \infty}^k&lt;&#x2F;span&gt; basis.&lt;&#x2F;p&gt;
&lt;p&gt;We can also do some univariate evaluation, but it is much more restrictive. Monomial evaluation works:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 13.&lt;&#x2F;strong&gt; (&lt;em&gt;Univariate Monomial Basis&lt;&#x2F;em&gt;)
Given &lt;span class=&quot;math math-inline&quot;&gt;x \in \F_q&lt;&#x2F;span&gt; the weights vector for evaluating a polynomial in the univariate monomial basis has &lt;span class=&quot;math math-inline&quot;&gt;w_i = x^i&lt;&#x2F;span&gt; and tensor weights &lt;span class=&quot;math math-inline&quot;&gt;\vec t_i = \begin{bmatrix} 1 &amp;amp; x^{2^i} \end{bmatrix}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Evaluation on one or two Lagrange points are just degenerate multi-linears. We can also do three Lagrange points (where we ignore &lt;span class=&quot;math math-inline&quot;&gt;w_4&lt;&#x2F;span&gt;), but barely:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 14.&lt;&#x2F;strong&gt; (&lt;em&gt;Univariate 3-Point Lagrange Basis&lt;&#x2F;em&gt;)
Given Lagrange basis points &lt;span class=&quot;math math-inline&quot;&gt;x_0,x_1,x_2 \in \F_q&lt;&#x2F;span&gt; and evaluation point &lt;span class=&quot;math math-inline&quot;&gt;x \in \F_q&lt;&#x2F;span&gt;,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\vec t_0 &amp;amp;= \begin{bmatrix}
\displaystyle (x - x_2) \\[1em]
\displaystyle \frac{(x - x_0)}{(x_2 - x_1) \cdot (x_1 - x_0)^{-1}}
\end{bmatrix} &amp;amp;
\vec t_1 &amp;amp;= \begin{bmatrix}
\displaystyle \dfrac{(x - x_1)}{(x_0 - x_1) \cdot (x_0 - x_2)} \\[1em]
\displaystyle \frac{(x - x_0)}{(x_1 - x_0) \cdot (x_1 - x_2)}
\end{bmatrix} \text{.} \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;This is cheating a bit, as &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; is length &lt;span class=&quot;math math-inline&quot;&gt;4&lt;&#x2F;span&gt; and we simply ignore the last element. To show that we can&#x27;t do better, we first introduce a lemma that succinctly characterizes tensor weights:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 15.&lt;&#x2F;strong&gt; (&lt;em&gt;Face Identities&lt;&#x2F;em&gt;) For &lt;span class=&quot;math math-inline&quot;&gt;m &amp;lt; k&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;i,k \in \range{0, 2^m}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;j,l \in \range{0,2^{k-m}}&lt;&#x2F;span&gt; we have for tensor weights &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w_{i + j \cdot 2^m} \cdot w_{k + l \cdot 2^m} - w_{i + l \cdot 2^m} \cdot w_{k + j \cdot 2^m} = 0 \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These identities correspond to the faces of the &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-hypercube and they are necessary and sufficient conditions for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; to be a tensor product of &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;-vectors.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; To show necessity split &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; in two parts &lt;span class=&quot;math math-inline&quot;&gt;\vec w = \vec w&amp;#39; \otimes \vec w&amp;#39;&amp;#39;&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39; \in \F_q^{2^l}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39;&amp;#39; \in \F_q^{2^{k-l}}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;w_{i + j \cdot 2^l} = w&amp;#39;_i \cdot w&amp;#39;&amp;#39;_j&lt;&#x2F;span&gt; and similar for the other terms. Then the identity becomes trivially true:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w&amp;#39;_i \cdot w&amp;#39;&amp;#39;_j \cdot w&amp;#39;_k \cdot w&amp;#39;&amp;#39;_l  - w&amp;#39;_i \cdot w&amp;#39;&amp;#39;_l \cdot w&amp;#39;_k \cdot w&amp;#39;&amp;#39;_j = 0 \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To show sufficiency, we use induction on &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;. The base case &lt;span class=&quot;math math-inline&quot;&gt;k = 1&lt;&#x2F;span&gt; is trivial. For the inductive case, split &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; in two halves &lt;span class=&quot;math math-inline&quot;&gt;\vec w = [\vec w_0\, \vec w_1]&lt;&#x2F;span&gt;. We will show that &lt;span class=&quot;math math-inline&quot;&gt;\vec w_1 = \alpha \cdot \vec w_0&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; and then we can take &lt;span class=&quot;math math-inline&quot;&gt;\vec t_0 = [1\, \alpha]&lt;&#x2F;span&gt; and use the inductive hypothesis on &lt;span class=&quot;math math-inline&quot;&gt;\vec w_0&lt;&#x2F;span&gt; to get the remaining &lt;span class=&quot;math math-inline&quot;&gt;\vec t_i&lt;&#x2F;span&gt;. Consider the face identities for &lt;span class=&quot;math math-inline&quot;&gt;m = 1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;i=0&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;k=1&lt;&#x2F;span&gt; and all &lt;span class=&quot;math math-inline&quot;&gt;j,l \in \range{0,2^{k-1}}&lt;&#x2F;span&gt; which we can rewrite as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{w_{0 + j \cdot 2}}{w_{1 + j \cdot 2}}  = \frac{w_{0 + l \cdot 2}}{w_{1 + l \cdot 2}} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If all the &lt;span class=&quot;math math-inline&quot;&gt;w_{1 + j \cdot 2} = 0&lt;&#x2F;span&gt; then we set &lt;span class=&quot;math math-inline&quot;&gt;\alpha = 0&lt;&#x2F;span&gt; and we are done. Otherwise they all have the same ratio, which we take as &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;We can now show that no dense univariate basis exists for more than &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt; points using tensor weights:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 16.&lt;&#x2F;strong&gt; For &lt;span class=&quot;math math-inline&quot;&gt;k &amp;gt; 1&lt;&#x2F;span&gt; it is not possible to construct a univariate basis for &lt;span class=&quot;math math-inline&quot;&gt;n \geq 2^k&lt;&#x2F;span&gt; interpolation points using weights tensors.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; The &lt;span class=&quot;math math-inline&quot;&gt;n&amp;gt;2^k&lt;&#x2F;span&gt; case is trivial. For &lt;span class=&quot;math math-inline&quot;&gt;n = 2^k&lt;&#x2F;span&gt; we are looking for tensor weights such that &lt;span class=&quot;math math-inline&quot;&gt;w_i = l_i(x)&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;l_i&lt;&#x2F;span&gt; is the &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;-th Lagrange basis polynomial for some set of points &lt;span class=&quot;math math-inline&quot;&gt;\set{x_j}_{j \in \range{0, n}}&lt;&#x2F;span&gt;. Pick four corners of a face of the hyper-cube, &lt;span class=&quot;math math-inline&quot;&gt;a, b, c,d&lt;&#x2F;span&gt;, the face identity becomes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
l_a(x) \cdot l_b(x) - l_c(x) \cdot l_d(x) = 0 \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This identity needs to hold for any &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; and the left side is a degree &lt;span class=&quot;math math-inline&quot;&gt;2(n-1)&lt;&#x2F;span&gt; polynomial. Taking the derivative we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{l_a(x) \cdot l_b&amp;#39;(x)  + l_a&amp;#39;(x) \cdot l_b(x)} - \p{l_c(x) \cdot l_d&amp;#39;(x)  + l_c&amp;#39;(x) \cdot l_d(x)} = 0 \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;span class=&quot;math math-inline&quot;&gt;x=x_a&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;l_a(x_a) = 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;l_b(x_a) = l_c(x_a) = l_d(x_a) = 0&lt;&#x2F;span&gt; and the above simplifies to &lt;span class=&quot;math math-inline&quot;&gt;l_b&amp;#39;(x_a) = 0&lt;&#x2F;span&gt;, which contradicts every zero of &lt;span class=&quot;math math-inline&quot;&gt;l_b&amp;#39;&lt;&#x2F;span&gt; being simple.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s an open question (to me at least) if a dense univariate Lagrange basis MLE can be computed efficiently.&lt;&#x2F;p&gt;
&lt;p&gt;While tensor weights already capture a surprisingly useful class of succinct MLEs, they remain limited to factorizable structures and are, for example, not closed under addition. To go further, we can replace each scalar by a matrix, allowing more complex linear combinations of partial results. This leads to &lt;em&gt;Weighted Ordered Binary Decision Diagram&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;weighted-obbds&quot;&gt;Weighted OBBDs&lt;&#x2F;h1&gt;
&lt;p&gt;A large class of efficient MLEs can be constructed by replacing the scalars in the tensors by matrices. This was first introduced in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;861&quot;&gt;HR18&lt;&#x2F;a&gt; in the proof of thm. 5.4, later refined in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;917&quot;&gt;HJR+25&lt;&#x2F;a&gt; § 4.1 where they are called &lt;em&gt;read-once matrix branching program&lt;&#x2F;em&gt;s. We will use terminology more in line with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1137&#x2F;1.9780898719789&quot;&gt;Weg00&lt;&#x2F;a&gt;, augmented with terms from automata theory.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 17.&lt;&#x2F;strong&gt; A &lt;em&gt;Weighted Ordered Binary Decision Diagram&lt;&#x2F;em&gt; (&lt;em&gt;WOBDD&lt;&#x2F;em&gt;) consists of permutation &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;\range{0,k}&lt;&#x2F;span&gt; and weight matrices&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\set{\mat M_{i\,0},\mat M_{i\,1} \in \mathbb{F}_q^{\,u_i \times u_{i+1}}}_{i \in [0,k)} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;u_i&lt;&#x2F;span&gt; are matrix dimensions such that the initial and final dimension &lt;span class=&quot;math math-inline&quot;&gt;u_0 = u_k = 1&lt;&#x2F;span&gt;. The evaluation of the program in &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; is then defined as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\prod_{i \in [0,k)} \p{ (1 - r_{\pi(i)}) \cdot \mathrm{M}_{i\,0} + r_{\pi(i)} \cdot \mathrm{M}_{i\,1} } \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We call &lt;span class=&quot;math math-inline&quot;&gt;\max_i u_i&lt;&#x2F;span&gt; the &lt;em&gt;width&lt;&#x2F;em&gt; of the WOBDD. When the permutation is given, we call it a &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-WOBDD&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; This definition differs from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;917&quot;&gt;HJR+25&lt;&#x2F;a&gt; and literature on weighted automata in allowing matrices of varying dimensions. The requirement that &lt;span class=&quot;math math-inline&quot;&gt;u_0 = u_l = 1&lt;&#x2F;span&gt; ensures that the result is a scalar, where in other literature this is achieved using separate source and sink vectors. This mostly makes the notation cleaner, but it&#x27;s easy to convert between the two.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s establish that these are indeed MLE evaluations and can be evaluated efficiently.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 18.&lt;&#x2F;strong&gt; A WOBDD is an MLE evaluation for &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^{2^k}&lt;&#x2F;span&gt; where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w_i = \prod_{j \in [0,k)} \mathrm{M}_{j\, b_{\pi(i)}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\vec b = \mathsf{bits}_k(i)&lt;&#x2F;span&gt;. If the width is bounded evaluation takes &lt;span class=&quot;math math-inline&quot;&gt;O(k)&lt;&#x2F;span&gt; operations.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; Each &lt;span class=&quot;math math-inline&quot;&gt;r_i&lt;&#x2F;span&gt; appears only once in the product and the expression is linear in each &lt;span class=&quot;math math-inline&quot;&gt;r_i&lt;&#x2F;span&gt;, hence it is multi-linear in &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;r_i \in \set{0, 1}&lt;&#x2F;span&gt; the values of &lt;span class=&quot;math math-inline&quot;&gt;w_i&lt;&#x2F;span&gt; follow directly from the definition.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;To show how this work, let&#x27;s look at a simple example that interpolates over the vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w = (0, 1, \dots, 2^k -1)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 19.&lt;&#x2F;strong&gt; (&lt;em&gt;Popcount&lt;&#x2F;em&gt;) We can construct a WOBDD for the MLE of &lt;span class=&quot;math math-inline&quot;&gt;w_i = \mathsf{popcount}(i) \pmod{\F_q}&lt;&#x2F;span&gt; using permutation &lt;span class=&quot;math math-inline&quot;&gt;\pi = \mathsf{id}&lt;&#x2F;span&gt; and matrices&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mat M_{0\,b} &amp;amp;= \begin{bmatrix} 1 &amp;amp; b \end{bmatrix} &amp;amp;
\mat M_{i\,b} &amp;amp;= \begin{bmatrix} 1 &amp;amp; b \\ 0 &amp;amp; 1 \end{bmatrix} &amp;amp;
\mat M_{k-1\,b} &amp;amp;= \begin{bmatrix} b \\ 1 \end{bmatrix} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 20.&lt;&#x2F;strong&gt; (&lt;em&gt;Counter&lt;&#x2F;em&gt;) We can construct a WOBDD for the MLE of &lt;span class=&quot;math math-inline&quot;&gt;w_i = i \pmod{\F_q}&lt;&#x2F;span&gt; using permutation &lt;span class=&quot;math math-inline&quot;&gt;\pi = \mathsf{id}&lt;&#x2F;span&gt; and matrices&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mat M_{0\,b} &amp;amp;= \begin{bmatrix} 2 &amp;amp; b \end{bmatrix} &amp;amp;
\mat M_{i\,b} &amp;amp;= \begin{bmatrix} 2 &amp;amp; b \\ 0 &amp;amp; 1 \end{bmatrix} &amp;amp;
\mat M_{k-1\,b} &amp;amp;= \begin{bmatrix} b \\ 1 \end{bmatrix} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;In Jolt there are many lookup tables for &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;-arry functions where the &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-bit inputs &lt;span class=&quot;math math-inline&quot;&gt;a_0, a_1, \dots, a_{m-1} \in \range{0,2^k}&lt;&#x2F;span&gt; are combined into an index &lt;span class=&quot;math math-inline&quot;&gt;i = \sum_{j \in [0,m)} a_j \cdot 2^{j \cdot k}&lt;&#x2F;span&gt; into the weight vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^{m \cdot k}&lt;&#x2F;span&gt;. The goal is then to find a succinct MLE for this &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt;. For boolean binary operations we can do this as&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 21.&lt;&#x2F;strong&gt; (&lt;em&gt;Bitwise Operation&lt;&#x2F;em&gt;) Given a boolean binary operation &lt;span class=&quot;math math-inline&quot;&gt;\ast&lt;&#x2F;span&gt; such as AND, OR or XOR, we can construct a WOBDD for the &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}_{2\cdot k}&lt;&#x2F;span&gt; evaluation of&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w_{\vec a \, \vec b} =\sum_{i \in \range{0,k}} 2^i \cdot \p{a_i \ast b_i} \pmod{\F_q} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Pick interleaved permutation &lt;span class=&quot;math math-inline&quot;&gt;\pi = (a_0, b_0, a_1, b_1, \dots)&lt;&#x2F;span&gt; and matrices&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mat M_{2\cdot i+1\,b} &amp;amp;= \begin{bmatrix}
1 &amp;amp; 0 &amp;amp; (1 - b) &amp;amp; b \\
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0
\end{bmatrix} &amp;amp;
\mat M_{0\,b} &amp;amp;= \begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 1 - b &amp;amp; b
\end{bmatrix} \\
\mat M_{2\cdot i\,b} &amp;amp;= \begin{bmatrix}
1 &amp;amp; 0 \\
0 &amp;amp; 1 \\
0 &amp;amp;  2^i \cdot (b \ast 0) \\
0 &amp;amp; 2^i \cdot (b \ast 1)
\end{bmatrix} &amp;amp;
\mat M_{k-1\,b} &amp;amp;= \begin{bmatrix}
0 \\ 1 \\ 2^i \cdot (b \ast 0) \\  2^i \cdot (b \ast 1)
\end{bmatrix} \text{.}\\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;When we have WOBDDs for two vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec w, \vec w&amp;#39;&lt;&#x2F;span&gt; we can combine them in several ways to get WOBDDs for new vectors. The following lemma&#x27;s show three useful constructions.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 22.&lt;&#x2F;strong&gt; (&lt;em&gt;Linear Combinations&lt;&#x2F;em&gt;) Given two &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-WOBDDs for &lt;span class=&quot;math math-inline&quot;&gt;\vec w, \vec w&amp;#39;&lt;&#x2F;span&gt; we can construct a &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-WOBDD for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39;&amp;#39;&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;w&amp;#39;&amp;#39;_i = \alpha \cdot w_i + \beta \cdot w&amp;#39;_i&lt;&#x2F;span&gt; by taking block matrices&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\mat M_{0\,j}&amp;#39;&amp;#39; &amp;amp;= \begin{bmatrix} M_{0\, j} &amp;amp; M_{0, j}&amp;#39; \end{bmatrix} &amp;amp;
\mat M_{ij}&amp;#39;&amp;#39; &amp;amp;= \begin{bmatrix}
\mat M_{ij} &amp;amp; 0 \\[4pt]
0 &amp;amp; \mat M_{ij}&amp;#39;
\end{bmatrix} &amp;amp;
\mat M_{k-1\,l}&amp;#39;&amp;#39; &amp;amp;= \begin{bmatrix}
\alpha \cdot \mat M_{k-1\,j} \\[4pt]
\beta \cdot \mat M_{k-1\,j}&amp;#39; \end{bmatrix} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The width of the resulting WOBDD is the sum of the widths of the input WOBDDs.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 23.&lt;&#x2F;strong&gt; (&lt;em&gt;Multiplication&lt;&#x2F;em&gt;) Given two &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-variable &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-WOBDDs for &lt;span class=&quot;math math-inline&quot;&gt;\vec w, \vec w&amp;#39;&lt;&#x2F;span&gt; we can construct a &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-WOBDD$ for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39;&amp;#39;&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;w&amp;#39;&amp;#39;_i = w_i \cdot w&amp;#39;_i&lt;&#x2F;span&gt; by taking tensor product matrices&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat M_{ij}&amp;#39;&amp;#39; = \mat M_{ij} \otimes \mat M_{ij}&amp;#39;\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The width of the resulting WOBDD is the product of the widths of the input WOBDDs.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 24.&lt;&#x2F;strong&gt; (&lt;em&gt;Reversing&lt;&#x2F;em&gt;) Given a WOBDD with permutation &lt;span class=&quot;math math-inline&quot;&gt;i_0, \dots, i_{k-1}&lt;&#x2F;span&gt; we can construct an equivalent WOBDD of same width with the reversed permutation &lt;span class=&quot;math math-inline&quot;&gt;i_{k-1},\dots,i_0&lt;&#x2F;span&gt; by transposing matrices &lt;span class=&quot;math math-inline&quot;&gt;\mat M_{i\,b}&amp;#39; = \mat M_{(k-i-1)\,b}^{\mathsf{T}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 25.&lt;&#x2F;strong&gt; (&lt;em&gt;Composition&lt;&#x2F;em&gt;) Given a &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; variable WOBDD and &lt;span class=&quot;math math-inline&quot;&gt;k&amp;#39;&lt;&#x2F;span&gt; variable WOBDD we can construct a &lt;span class=&quot;math math-inline&quot;&gt;k+k&amp;#39;&lt;&#x2F;span&gt; variable WOBBD for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39;&amp;#39;&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;w&amp;#39;&amp;#39;_{i + j\cdot2^{k}} = w_i \cdot w&amp;#39;_j&lt;&#x2F;span&gt; by concatenating the permutations and matrices.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Using these constructions we can e.g. build a lookup table for squaring by taking the counter from example 20 and multiplying it with itself using lemma 23.&lt;&#x2F;p&gt;
&lt;p&gt;We could generalize the WOBDD definition by replacing the permutation with a set partitioning of &lt;span class=&quot;math math-inline&quot;&gt;r_i&lt;&#x2F;span&gt; into subvectors &lt;span class=&quot;math math-inline&quot;&gt;\vec r_i \in \F_q^{k_i}&lt;&#x2F;span&gt;, having &lt;span class=&quot;math math-inline&quot;&gt;2^{k_i}&lt;&#x2F;span&gt; matrices for each &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; and evaluating using the &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{eq}&lt;&#x2F;span&gt; polynomials:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\prod_{i \in [0,l)} \sum_{j \in [0, 2^{k_i})} \mathrm{eq}_{k_i\,j}(\vec r_i) \cdot \mathrm{M}_{ij}\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This allows for a time-space trade-off, especially if we can eliminate a large intermediate &lt;span class=&quot;math math-inline&quot;&gt;u_i&lt;&#x2F;span&gt; value. For simplicity we will not consider this generalization further.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;transducers&quot;&gt;Transducers&lt;&#x2F;h1&gt;
&lt;p&gt;To create more powerful manipulations of WOBDDs we introduce &lt;em&gt;transducers&lt;&#x2F;em&gt;, which are like weighted non-deterministic finite transducers (WFSTs) except they have a layered structure. They also extend the read-once branching programs from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;917&quot;&gt;HJR+25&lt;&#x2F;a&gt; and OR-OBDDs from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1137&#x2F;1.9780898719789&quot;&gt;Weg00&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 26.&lt;&#x2F;strong&gt; An &lt;em&gt;Non-deterministic Weighted Ordered Binary Decision Transducer&lt;&#x2F;em&gt;, is a matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat T \in \F_q^{2^k \times 2^k}&lt;&#x2F;span&gt; specified as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;There is an input permutation &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;\range{0,k}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;There are layered sets of states &lt;span class=&quot;math math-inline&quot;&gt;\setn{S}_0,\dots,\setn{S}_k&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;For each &lt;span class=&quot;math math-inline&quot;&gt;i \in \range{0,k}&lt;&#x2F;span&gt; there is a transition weight function
&lt;span class=&quot;math math-display&quot;&gt;
  \delta_i : \setn{S}_i \times \set{0,1} \times \setn{S}_{i+1} \times \set{0,1} \rightarrow \F_q
&lt;&#x2F;span&gt;
such that in state &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; on input bit &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; we can transition to state &lt;span class=&quot;math math-inline&quot;&gt;s&amp;#39;&lt;&#x2F;span&gt; outputting bit &lt;span class=&quot;math math-inline&quot;&gt;b&amp;#39;&lt;&#x2F;span&gt; with weight &lt;span class=&quot;math math-inline&quot;&gt;\delta_i(s, b, s&amp;#39;, b&amp;#39;)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;\widehat{\setn{S}} = S_0 \times S_1 \times \cdots \times S_k&lt;&#x2F;span&gt; then the matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat T&lt;&#x2F;span&gt; is specified by summing over all paths while accumulating weights multiplicatively,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat T_{i j} = \sum_{\vec s \in \widehat{\setn S}} \prod_{l \in \range{0, k}} \delta_l(s_l, \mathsf{bits}(i)_{\pi(l)}, s_{l+1}, \mathsf{bits}(j)_{\pi(l)}) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;width&lt;&#x2F;em&gt; of the transducer is &lt;span class=&quot;math math-inline&quot;&gt;\max_i |\setn{S}_i|&lt;&#x2F;span&gt;. For a given &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; we call it a &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-transducer&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Transducers can be used to transform WOBDDs such that each resulting weight is a a linear combination of the original weights:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 27.&lt;&#x2F;strong&gt; (&lt;em&gt;Transducer Action&lt;&#x2F;em&gt;) Given a &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-transducer &lt;span class=&quot;math math-inline&quot;&gt;\mat T&lt;&#x2F;span&gt; and a &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-WOBDD for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; we can construct a &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt;-WOBDD for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39; = \mat T \cdot \vec w&lt;&#x2F;span&gt; using the block matrices&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(\mat M&amp;#39;_{i\, b})_{s\,s&amp;#39;} = \sum_{b&amp;#39; \in \set{0,1}} \delta_i(s, b, s&amp;#39;, b&amp;#39;) \cdot \mat M_{i\, b&amp;#39;}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the initial and final dimension are collapsed to &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; by summation. The width of resulting WOBDD is at most the product of the width of the original WOBDD and the width of the transducer.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; For each path in &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt;, the construction picks the matrices from the original program according to the output and multiplies them.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;The non-determinism complicates things compared to the deterministic read-once branching programs (ROBP) from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;917&quot;&gt;HJR+25&lt;&#x2F;a&gt;, but it also makes it more powerful. For one, it allows us to reverse the permutation without increasing the width. Without non-determinism, many useful programs can only be expressed in either MSB or LSB order and we would not be able to combine them. The class of efficiently computable functions is also larger (see e.g. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1137&#x2F;1.9780898719789&quot;&gt;Weg00&lt;&#x2F;a&gt; thm 12.2.1). In terms of the matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat T&lt;&#x2F;span&gt;, adding the output bit allows us to go from diagonal matrices to (generalized) permutation matrices and adding non-determinism allows us to go dense matrices.&lt;&#x2F;p&gt;
&lt;p&gt;For convenience, we will talk about &lt;em&gt;Most-Significant Bit first&lt;&#x2F;em&gt; (&lt;em&gt;MSB&lt;&#x2F;em&gt;) and &lt;em&gt;Least-Significant Bit first&lt;&#x2F;em&gt; (&lt;em&gt;LSB&lt;&#x2F;em&gt;) transducers, where the input permutation is &lt;span class=&quot;math math-inline&quot;&gt;\pi(i) = i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\pi(i) = k-i-1&lt;&#x2F;span&gt; respectively. When the transducer is deterministic we specify transitions as a function &lt;span class=&quot;math math-inline&quot;&gt;\delta_i: \setn{S}_i \times \set{0,1} \rightarrow \setn{S}_{i+1} \times \set{0,1} \times \F_q&lt;&#x2F;span&gt;. We also omit the output and weight when they equal the input and &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; respectively. We say we &lt;em&gt;associate a weight to an initial&#x2F;final state&lt;&#x2F;em&gt; to mean applying the weight to each transition entering or leaving that state respectively.&lt;&#x2F;p&gt;
&lt;p&gt;To show the utility of this class, let&#x27;s look at some simple examples of transducers. The first example does a MSB lexicographic comparison with a constant:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 28.&lt;&#x2F;strong&gt; (&lt;em&gt;MSB Comparison&lt;&#x2F;em&gt;) A comparison for &lt;span class=&quot;math math-inline&quot;&gt;c \in \range{0, 2^{k}}&lt;&#x2F;span&gt; is constructed as an MSB-transducer with states &lt;span class=&quot;math math-inline&quot;&gt;\setn S_0 = \set{\mathtt{equal}}, \setn S_i = \set{\mathtt{less}, \mathtt{equal}, \mathtt{greater}}&lt;&#x2F;span&gt; and transition function&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\delta_i(\mathtt{less}, b) &amp;amp;= \mathtt{less} \\[4pt]
\delta_i(\mathtt{equal}, b) &amp;amp;= \begin{cases}
\mathtt{less} &amp;amp; \text{if } b &amp;lt; \mathsf{bits}(c)_{k-i-1} \\
\mathtt{equal} &amp;amp; \text{if } b = \mathsf{bits}(c)_{k-i-1} \\
\mathtt{greater} &amp;amp; \text{if } b &amp;gt; \mathsf{bits}(c)_{k-i-1}
\end{cases} \\[6pt]
\delta_i(\mathtt{greater}, b) &amp;amp;= \mathtt{greater} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We associate weights to the final state &lt;span class=&quot;math math-inline&quot;&gt;(\mathtt{less}, \mathtt{equal}, \mathtt{greater})&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;(1, 0, 0)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;(1, 1, 0)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;(0, 1, 0)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;(1, 0 ,1)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;(0, 1, 1)&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;(0, 0, 1)&lt;&#x2F;span&gt; to get the transducers for &lt;span class=&quot;math math-inline&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\leq&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;=&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\neq&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\geq&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; respectively.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;This method is width 3. There is also a width 2 LSB-transducer using subtraction:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 29.&lt;&#x2F;strong&gt; (&lt;em&gt;LSB Comparison&lt;&#x2F;em&gt;) A comparison for &lt;span class=&quot;math math-inline&quot;&gt;c \in \range{0, 2^{k}}&lt;&#x2F;span&gt; is constructed as an LSB-transducer with states &lt;span class=&quot;math math-inline&quot;&gt;\setn S_0 = \set{0}, \setn S_i = \set{0,1}&lt;&#x2F;span&gt; and transition function&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delta_i(s, b) = \begin{cases}
1 &amp;amp; \text{if } b &amp;lt; s + \mathsf{bits}(c)_{k-i-1} \\[4pt]
0 &amp;amp; \text{otherwise} \\[4pt]
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The weights associating to the final state can be set to &lt;span class=&quot;math math-inline&quot;&gt;(0, 1)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;(1, 0)&lt;&#x2F;span&gt; to get the transducers for &lt;span class=&quot;math math-inline&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\geq&lt;&#x2F;span&gt; respectively.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The next example shows the utility of the output function to permute the weights, in this case shift them by any amount:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 30.&lt;&#x2F;strong&gt; (&lt;em&gt;Shift&lt;&#x2F;em&gt;) For a cyclic rotation of the indices by an amount &lt;span class=&quot;math math-inline&quot;&gt;c \in \range{0,2^k}&lt;&#x2F;span&gt; we construct a LSB-transducer with states &lt;span class=&quot;math math-inline&quot;&gt;\setn S_0 = \set{0}, \setn S_i = \set{0,1}&lt;&#x2F;span&gt; representing the carry bit, and transition function &lt;span class=&quot;math math-inline&quot;&gt;\delta_i(s, b) = (s&amp;#39;, b&amp;#39;)&lt;&#x2F;span&gt; where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
t &amp;amp;= s + b + \mathsf{bits}(c)_{k-i-1} \\[4pt]
(s&amp;#39;, b&amp;#39;) &amp;amp;= (\floor{t &#x2F; 2}, t \bmod 2) \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The weights associated with final states can then be set to &lt;span class=&quot;math math-inline&quot;&gt;(1, 1), (1,0), (0,1)&lt;&#x2F;span&gt; for cyclic rotation, left shift, and right shift (of &lt;span class=&quot;math math-inline&quot;&gt;2^k - c&lt;&#x2F;span&gt;) respectively.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Combining these two examples we can move any contiguous range of weights from a WOBDD to anywhere in the weight vector and set the rest to zero. In Inner Product Commitment Schemes this allows us to pack many polynomials of various shapes in a single commitment and open them with appropriately shifted weights, i.e. to move the range of weights &lt;span class=&quot;math math-inline&quot;&gt;\range{0,c}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\range{d, c+d}&lt;&#x2F;span&gt; and set all other zero we can apply a less-than-&lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; followed by a &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;-right shift. This expands the width by &lt;span class=&quot;math math-inline&quot;&gt;4&lt;&#x2F;span&gt;. Neither &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; nor &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; need to be powers of two.&lt;&#x2F;p&gt;
&lt;p&gt;Another interesting example to show the expressiveness of transducers is division, which for an arbitrary (but small) &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; transforms the weights as &lt;span class=&quot;math math-inline&quot;&gt;w_i&amp;#39; = w_{\floor{i &#x2F; c}}&lt;&#x2F;span&gt; using a width &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 31.&lt;&#x2F;strong&gt; (&lt;em&gt;Division&lt;&#x2F;em&gt;) For a floored division of the indices by an amount &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; we construct an MSB-transducer with states &lt;span class=&quot;math math-inline&quot;&gt;\setn S_0 = \set{0}, \setn S_i = \range{0,c}&lt;&#x2F;span&gt; and transition function &lt;span class=&quot;math math-inline&quot;&gt;\delta_i(s, b) = (s&amp;#39;, b&amp;#39;)&lt;&#x2F;span&gt; where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
t &amp;amp;= 2 \cdot s + b \\
(s&amp;#39;, b&amp;#39;) &amp;amp;= (t \bmod c, \floor{t &#x2F; c}) \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Finally we show the power of non-determinism to construct dense matrices &lt;span class=&quot;math math-inline&quot;&gt;\mat T&lt;&#x2F;span&gt; in bounded width:&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 32.&lt;&#x2F;strong&gt; (&lt;em&gt;Hadamard Transform&lt;&#x2F;em&gt;) For a Hadamard transform of the weights such that &lt;span class=&quot;math math-inline&quot;&gt;w_i&amp;#39; = \sum_{j \in [0, 2^k)} (-1)^{i \cdot j} \cdot w_j&lt;&#x2F;span&gt; we construct a LSB-transducer with one state &lt;span class=&quot;math math-inline&quot;&gt;\setn S_i = \set{\circ}&lt;&#x2F;span&gt; and transition weight function&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delta_i(\circ, b, \circ, b&amp;#39;, ) = (-1)^{b \cdot b&amp;#39;} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 33.&lt;&#x2F;strong&gt; (&lt;em&gt;Prefix Sum&lt;&#x2F;em&gt;) For a prefix sum of the weights such that &lt;span class=&quot;math math-inline&quot;&gt;w_i&amp;#39; = \sum_{j \in [0, i]} w_j&lt;&#x2F;span&gt; we construct an MSB-transducer with states &lt;span class=&quot;math math-inline&quot;&gt;\setn S_0 = \set{\mathsf{eq}}, \setn S_i = \set{\mathsf{lt}, \mathsf{eq}}&lt;&#x2F;span&gt; and transition weight function&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\delta_i(\mathsf{lt}, b, \mathsf{lt}, b&amp;#39;) &amp;amp;= 1 \text{ for all } b, b&amp;#39; \\
\delta_i(\mathsf{eq}, b, \mathsf{eq}, b) &amp;amp;= 1 \text{ for all } b \\
\delta_i(\mathsf{eq}, 1, \mathsf{lt}, 0) &amp;amp;= 1 \\
\delta_i(s,b, s&amp;#39;, b&amp;#39;) &amp;amp;= 0 \text { otherwise.} \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h1 id=&quot;extension-fields-and-embeddings&quot;&gt;Extension fields and embeddings&lt;&#x2F;h1&gt;
&lt;p&gt;With these tool, we can tackle the problem from my post on &lt;a href=&quot;..&#x2F;embedding-inner-products&quot;&gt;&quot;Embedding Inner Products&quot;&lt;&#x2F;a&gt;. Recall the setup, we have an inner product commitment scheme&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 34.&lt;&#x2F;strong&gt; An &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;-Inner Product Commitment Scheme&lt;&#x2F;em&gt; is a tuple of algorithms &lt;span class=&quot;math math-inline&quot;&gt;(\mathsf{commit}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify})&lt;&#x2F;span&gt; such that.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathsf{commit}&lt;&#x2F;span&gt; algorithm takes a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v \in \F_q^n&lt;&#x2F;span&gt; and outputs a commitment &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt; algorithm takes &lt;span class=&quot;math math-inline&quot;&gt;\vec v, C&lt;&#x2F;span&gt;, a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^n&lt;&#x2F;span&gt;, and a value &lt;span class=&quot;math math-inline&quot;&gt;y \in \F_q&lt;&#x2F;span&gt; and outputs a proof &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; that the inner product &lt;span class=&quot;math math-inline&quot;&gt;\vec v \cdot \vec w = \sum_{i \in [0,n)} v_i \cdot w_i&lt;&#x2F;span&gt; equals &lt;span class=&quot;math math-inline&quot;&gt;y&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; algorithm takes &lt;span class=&quot;math math-inline&quot;&gt;C, \vec w, y, \pi&lt;&#x2F;span&gt; and outputs true if the proof is valid and false otherwise.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;In Ligerito and WHIR the running time of &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;O(\log n)&lt;&#x2F;span&gt; iff there is a succinct MLE for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt;. Those schemes also require that &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; is cryptographically large, which we can achieve by taking an extension field &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; and an embedding:&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 35.&lt;&#x2F;strong&gt; An &lt;em&gt;embedding&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; is given by a &lt;span class=&quot;math math-inline&quot;&gt;\vec c \in \F_{q^d}^p&lt;&#x2F;span&gt; such that the embedding map &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{embed}_{\vec c}: \F_q^n \rightarrow \F_{q^d}^{n&amp;#39;}: \vec w \mapsto \vec w&amp;#39;&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;n&amp;#39; = \ceil{n &#x2F; p}&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w_i&amp;#39; = \sum_{j \in [0, p)} c_j \cdot w_{i \cdot p + j} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, when &lt;span class=&quot;math math-inline&quot;&gt;p = d&lt;&#x2F;span&gt; we call it a &lt;em&gt;packed embedding&lt;&#x2F;em&gt; and when &lt;span class=&quot;math math-inline&quot;&gt;\vec c = [1]&lt;&#x2F;span&gt; we call it the &lt;em&gt;natural embedding&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;We then apply embeddings to &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; and use an &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt;-inner product commitment scheme and extract the &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; result from the &lt;span class=&quot;math math-inline&quot;&gt;\F_{q_d}&lt;&#x2F;span&gt; inner product. With careful choice of embeddings this can work.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 36.&lt;&#x2F;strong&gt; (&lt;em&gt;Embedding Inner Products&lt;&#x2F;em&gt;) For towers of extensions with suitable moduli, there exist packed embeddings &lt;span class=&quot;math math-inline&quot;&gt;\vec c, \vec c&amp;#39;&lt;&#x2F;span&gt; such that for any &lt;span class=&quot;math math-inline&quot;&gt;\vec v, \vec w \in \F_q^n&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec v \cdot \vec w = \mathsf{unembed}( \mathsf{embed}_{\vec c}(\vec v) \cdot \mathsf{embed}_{\vec c&amp;#39;}(\vec w)) \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{unembed}: \F_{q^d} \rightarrow \F_q&lt;&#x2F;span&gt; simply takes the constant coefficient.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; See &lt;a href=&quot;..&#x2F;embedding-inner-products&quot;&gt;&quot;Embedding Inner Products&quot;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;This raises the question: If we have a succinct MLE for &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^n&lt;&#x2F;span&gt;, can we get a succinct MLE for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39; = \mathsf{embed}_{\vec c}(\vec w) \in \F_{q^d}^{n&amp;#39;}&lt;&#x2F;span&gt;? It turns out we often can, using transducers.&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 37.&lt;&#x2F;strong&gt; (&lt;em&gt;Folding Transducer&lt;&#x2F;em&gt;) For a weighted sum of indices such that &lt;span class=&quot;math math-inline&quot;&gt;w&amp;#39;_i = \sum_{j \in [0, p)} c_j \cdot w_{i \cdot p + j}&lt;&#x2F;span&gt; we can construct a LSB-transducer with states &lt;span class=&quot;math math-inline&quot;&gt;\setn S_i = \range{0,p}&lt;&#x2F;span&gt; and transition function &lt;span class=&quot;math math-inline&quot;&gt;\delta_i(s, b) = (s&amp;#39;, b&amp;#39;)&lt;&#x2F;span&gt; where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
t &amp;amp;= s + p \cdot b \\
(s&amp;#39;, b&amp;#39;) &amp;amp;= (t \bmod 2, \floor{t &#x2F; 2}) \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the weights for the initial states are &lt;span class=&quot;math math-inline&quot;&gt;(c_0, \dots, c_{p-1})&lt;&#x2F;span&gt; and the weights for the final states are &lt;span class=&quot;math math-inline&quot;&gt;(1, 0, \dots, 0)&lt;&#x2F;span&gt;. This transducer has width &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;With this transducer, we can answer the question above positively for MSB- and LSB-WOBDDs:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 38.&lt;&#x2F;strong&gt; (&lt;em&gt;Embedding Succinct MLEs&lt;&#x2F;em&gt;) Given an embedding &lt;span class=&quot;math math-inline&quot;&gt;\vec c \in \F_{q^d}^p&lt;&#x2F;span&gt; and a MSB- or LSB-WOBDD for &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^n&lt;&#x2F;span&gt; we can construct a WOBDD for &lt;span class=&quot;math math-inline&quot;&gt;\vec w&amp;#39; = \mathsf{embed}_{\vec c}(\vec w)&lt;&#x2F;span&gt; with width at most &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; times the width of the original WOBDD.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; Reverse the original WOBDD if needed to make it LSB. Lift the matrices from &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; (i.e. take the natural embedding), then apply the folding transducer above.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;This solves it for inner product commitments, but often there are more parts to a protocol and these may not necessarily allow for packed embeddings. For example if we have a naturally embedded sumcheck round, we may need to evaluate &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{MLE}(\vec v&amp;#39;, \vec r)&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F_{q^d}^k&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\vec v&amp;#39; \in \F_q^{2^k}&lt;&#x2F;span&gt; is the natural embedding of &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We can do this using an inner product with MLE evaluation weights for &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; (see example 11). But now we have an inner product between &lt;span class=&quot;math math-inline&quot;&gt;\vec v \in \F_q&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_{q^d}&lt;&#x2F;span&gt; vector and can only do inner products in &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;. We can easily solved this by taking any basis &lt;span class=&quot;math math-inline&quot;&gt;\beta_0, \dots, \beta_{d-1}&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; and expressing the &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; inner product as a sum of &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; inner products, each with a different set of weights &lt;span class=&quot;math math-inline&quot;&gt;\vec w^{(l)}&lt;&#x2F;span&gt; which are the coefficients of &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; in the basis such that &lt;span class=&quot;math math-inline&quot;&gt;\vec w = \sum_{l \in \range{0,d}} \beta_l \cdot \vec w^{(l)}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec v \cdot \vec w = \sum_{l \in \range{0,d}} \beta_l \cdot \p{\vec v \cdot \vec w^{(l)}}&lt;&#x2F;span&gt;. But this raises the question:&lt;&#x2F;p&gt;
&lt;p&gt;If we have a succinct MLE for &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_{q^d}^n&lt;&#x2F;span&gt; and some basis &lt;span class=&quot;math math-inline&quot;&gt;\vec \beta&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;, can we get an succinct MLEs for each of the &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; coefficient vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec w^{(l)} \in \F_q^n&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;It turns out, we can, for any WOBDD in fact:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 39.&lt;&#x2F;strong&gt; (&lt;em&gt;Lowering&lt;&#x2F;em&gt;) Given a &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; WOBDD and a basis &lt;span class=&quot;math math-inline&quot;&gt;\beta_0, \dots, \beta_{d-1}&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; we can construct WOBDDs for each of the &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; coefficient vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec w^{(l)} \in \F_q^{2^k}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;w_i = \sum_{l \in [0,d)} w_i^{(l)} \cdot \beta_l&lt;&#x2F;span&gt;. Take the original permutation and block matrices&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(\mat M&amp;#39;_{i\,b})_{u\,v} = \mathsf{mul}_{\vec \beta}((\mat M_{i\,b})_{u\,v})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{mul}_{\vec \beta}(t)&lt;&#x2F;span&gt; is the matrix of the &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;-linear map &lt;span class=&quot;math math-inline&quot;&gt;x \mapsto t \cdot x&lt;&#x2F;span&gt; in basis &lt;span class=&quot;math math-inline&quot;&gt;\vec \beta&lt;&#x2F;span&gt;. The initial matrix is multiplied by the &lt;span class=&quot;math math-inline&quot;&gt;\beta&lt;&#x2F;span&gt; representation of &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;. The final matrix is turned into &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; vectors by taking its columns, each of these final matrices computes the WOBDD for one of the coefficient vectors. The new WOBDDs has &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; times the original width.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;It makes sense to extend the definition of WOBDDs to allow vector results so that we can skip selecting the final column and compute all &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; evaluations in one pass. If we do this, the evaluation is optimal as it performs exactly the operations that the original WOBDD would have done, just expressed in the basis. To use it in the above packing, we then still need to apply the folding transducer which multiplies the width by &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; again. It also lifts all the intermediate values to &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt;, though the matrices remain in &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;. On the other hand, we gain some efficiency by packing requiring &lt;span class=&quot;math math-inline&quot;&gt;\floor{\log_2 p}&lt;&#x2F;span&gt; fewer variables.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;further-thoughts-and-questions&quot;&gt;Further Thoughts and Questions&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;General WOBDDs are not closed under addition, even though we know efficient MLEs are. Can we find a more powerful class that is closed under addition? Since the set of &lt;span class=&quot;math math-inline&quot;&gt;\pi, \pi_{\text{reversed}}&lt;&#x2F;span&gt;-WOBDDs are closed under addition, we need a way to add incompatible programs. I suspect a weighted version of FBDDs might work, where we sum over merging paths, but I haven&#x27;t worked out the details.&lt;&#x2F;li&gt;
&lt;li&gt;We have shown transducers to be equivalent to matrices &#x2F; linear maps. Can we characterize which linear maps are succinctly representable as transducers?&lt;&#x2F;li&gt;
&lt;li&gt;We could extend transducers with matrix weights on the transitions and tensor products when applied to a WOBDD. I don&#x27;t see a good use for this yet, but it may prove to be more powerful in the same way that WOBDDs are more powerful than tensor weights. Though I suspect it is redundant with the states.&lt;&#x2F;li&gt;
&lt;li&gt;Some examples can be optimized when &lt;span class=&quot;math math-inline&quot;&gt;c = 2^{k&amp;#39;} \cdot c&amp;#39;&lt;&#x2F;span&gt; for odd &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; by splitting off the &lt;span class=&quot;math math-inline&quot;&gt;2^{k&amp;#39;}&lt;&#x2F;span&gt; part using variable tricks. This can probably be implemented as an optimization pass on the transducer state machine. In general the current implementation can do more optimization such as dead state elimination.&lt;&#x2F;li&gt;
&lt;li&gt;For Weighted Finite Automata there is good literature on minimization, which can likely be augmented to apply to WOBDDs. Similarly there is literature on minimizing state-machines&#x2F;transducers.&lt;&#x2F;li&gt;
&lt;li&gt;For Jolt style lookup tables we could imagine a variant of transducers where we can see the &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;-arry input as &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; parallel bit streams and have transitions that read one bit from each stream at a time.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1137&#x2F;1.9780898719789&quot;&gt;Weg00&lt;&#x2F;a&gt; Ingo Wegner (2000). Branching Programs and Binary Decision Diagrams.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1007&#x2F;978-3-642-01492-5&quot;&gt;DKV09&lt;&#x2F;a&gt; Manfred Droste, Werner Kuich, Heiko Vogler (2009). Handbook of Weighted Automata.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1007&#x2F;978-3-642-24508-4&quot;&gt;Juk12&lt;&#x2F;a&gt; Stasys Jukna (2012). Boolean Function Complexity.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;351&quot;&gt;Tha13&lt;&#x2F;a&gt; Justin Thaler (2013). Time-Optimal Interactive Proofs for Circuit Evaluation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;861&quot;&gt;HR18&lt;&#x2F;a&gt; Justin Holmgren, Ron D. Rothblum (2018). Delegating computations with (almost) minimal time and space overhead.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;ProofsArgsAndZK.pdf&quot;&gt;Tha23&lt;&#x2F;a&gt; Justin Thaler (2023). Proofs, Arguments, and Zero Knowledge.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;552&quot;&gt;STW23&lt;&#x2F;a&gt; Srinath Setty, Justin Thaler, Riad Wahby (2023). Customizable constraint systems for succinct arguments&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;917&quot;&gt;HJR+25&lt;&#x2F;a&gt; Tamir Hemo, Kevin Jue, Eugene Rabinovich, Gyumin Roh, Ron D. Rothblum (2025). Jagged Polynomial Commitments.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;611&quot;&gt;NTZ25&lt;&#x2F;a&gt; Vineet Nair, Justin Thaler, Michael Zhu (2025). Proving CPU Executions in Small Space&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;sage-implementation&quot;&gt;Sage Implementation&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; reversed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;ZZ&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;digits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; padto&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; unbits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; msb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    P&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; P&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; lsb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    P&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; P&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)[::&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; eq&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;index i=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; larger than 2^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; = &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;    if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; sage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;Vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;r is not a vector&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;length of r is not k = &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{k}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mle&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;    if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; sage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;Vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;w is not a vector&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;    if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; sage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;Vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;x is not a vector&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;w and x are not over the same field&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;length of w is not a 2^len(x)&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; rec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;lo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; hi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;lo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        mid&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;lo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        u0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; rec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;lo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; mid&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        u1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; rec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;mid&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; hi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; rec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;class-wobdd&quot;&gt;Class WOBDD&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-magic z-python&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; not in &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        # Make sure matrix set size is correct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;matrices is not a list of list of matrices&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Number of matrix sets does not equal &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;            if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;mis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;mis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;matrices[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;] is not a pair of matrices&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;mis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;                if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; sage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                    raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;matrices[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;] is not a matrix&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                    raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;matrices[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;] is not a matrix over the field&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;ncols&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                    v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;dimensions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                    raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;matrices[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;] is not of dimension &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; field&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; max_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)).&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;random_element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;randint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; max_width&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            V&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; MatrixSpace&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;V&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;random_element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; V&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;random_element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-magic z-python&quot;&gt; __repr__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;WOBDD width=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;width&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; over &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;VectorSpace&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-magic z-python&quot;&gt; __call__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; Integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; sage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;Vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;r is not a vector&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;r is not over the field&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        M&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Mi0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Mi1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            M&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ri&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Mi0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ri&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Mi1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; M&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; width&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;nrows&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; weights&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; assert_compatible&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;Not in same field&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;Different permutation&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; is_compatible&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        try&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;assert_compatible&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        except&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; True&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; lift&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;has_coerce_map_from&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Can not lift from &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; to &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;change_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; lower&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;V&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v_to_f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f_to_v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;vector_space&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        basis&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;v_to_f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; V&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;basis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;        def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;f_to_v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; beta&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; beta&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; basis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;        def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; lower_matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; block_matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; row&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;lower_matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; f_to_v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; V&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;basis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;T&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-magic z-python&quot;&gt; __add__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; NotImplemented&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;assert_compatible&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;block_matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;block_matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;], [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;block_matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;], [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-magic z-python&quot;&gt; __mul__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TODO&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: Scalar multiplication.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; NotImplemented&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;assert_compatible&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;tensor_product&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m1s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m2s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m1s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m2s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; other&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; reverse&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        P&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; P&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[::&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mis&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[::&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;transpose&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;wobdd-examples&quot;&gt;WOBDD Examples&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; popcount&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;], [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; lsb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; start&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;], [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; lsb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; bitwise&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; op&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; op&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; op&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ]).&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;T&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; op&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; op&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]]).&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;T&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;class-transducer&quot;&gt;Class Transducer&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Transducer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-magic z-python&quot;&gt; __init__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; not in &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Permutations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        # Expand repeated rules to lists&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;len(transitions) is &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; not &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        # Validate, extract reachable states by layer, and relabel states to [0, len(states))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        transition_relation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            # Expand functions to relations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; callable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                relation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                        [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        relation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; relation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            # Remove zero-weight transitions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;set&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            transition_relation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TODO&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: Backwards reachability pass, general minimization, pow-2 tricks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; field&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; states&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; transition_relation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-magic z-python&quot;&gt; __repr__&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Transducer on &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bits of width &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;width&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; width&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; Integer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;            input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;GF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; sage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;Vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;input is not a vector&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ri&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ri&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ri&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;input is not a bitvector&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;        input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,[],&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        output&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; zip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            next_paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; input&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;                        continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                    next_paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; next_paths&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;        def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; unpermute&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;                result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;unpermute&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;paths&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;                m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; unbits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; action&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-function z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; wobdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;wobdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;wobdd is not a WOBDD&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wobdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;wobdd is not compatible&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;        #&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; TODO&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt;: This fails in the degenerate case where there are zero states.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; enumerate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;zip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; wobdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; Mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;].&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;dimensions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            blocks&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [[[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;wobdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;                blocks&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;][&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; Mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;o&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;block_matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; blocks&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;M&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; M&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            elif&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;matrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;M&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;columns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;())).&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;T&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; M&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;mi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; WOBDD&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;wobdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-special z-self z-python&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; matrices&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;transducer-examples&quot;&gt;Transducer Examples&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; less_than&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; lsb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;ZZ&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)[::&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; input_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        output_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input_bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; next_state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; output_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Transducer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;left&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;left&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        weights&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;right&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        weights&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;cyclic&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        weights&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;Unknown kind &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-format z-placeholder z-other z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; lsb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;ZZ&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)[::&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        output_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; weights&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;  else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; output_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Transducer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; division&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; msb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; input_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input_bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        output_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;next_state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; output_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Transducer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; lsb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;s&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Transducer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prefix_sum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; msb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;eq&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; []&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;eq&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;eq&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;eq&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;lt&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;eq&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;eq&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Transducer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; transitions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; fold&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; coeffs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;coeffs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; lsb&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;    def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; carry&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; input_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; carry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input_bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        next_carry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        output_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; coeffs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;carry&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; next_carry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;next_carry&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; output_bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; weight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Transducer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; permutation&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; initial_states&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; transition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Embedding Inner Products</title>
        <published>2025-09-19T00:00:00+00:00</published>
        <updated>2025-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/embedding-inner-products/"/>
        <id>https://2π.com/25/embedding-inner-products/</id>
        
        <content type="html" xml:base="https://2π.com/25/embedding-inner-products/">&lt;h1 id=&quot;embedding-inner-products&quot;&gt;Embedding Inner Products&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\ceil#1{\left\lceil{#1}\right\rceil}
\gdef\norm#1{\left|{#1}\right|}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\F{\mathbb{F}}
\gdef\i{\mathrm{i}}
\gdef\j{\mathrm{j}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In cryptographic protocols it&#x27;s useful to compute inner products over small fields &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; while using a large extension field &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^d}&lt;&#x2F;span&gt;. The naive approach of embedding &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; into &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^d}&lt;&#x2F;span&gt; directly incurs a &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; overhead in memory and &lt;span class=&quot;math math-inline&quot;&gt;d^2&lt;&#x2F;span&gt; overhead in multiplications. In this article I present an approach based on bilinear embeddings that is simple, has no memory overhead, and only a &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; overhead in multiplications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inner-product-commitment-schemes&quot;&gt;Inner Product Commitment Schemes&lt;&#x2F;h2&gt;
&lt;p&gt;Recent commitment schemes such as WHIR (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;1586&quot;&gt;AC+24&lt;&#x2F;a&gt;) and Ligerito (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;1187&quot;&gt;NA25&lt;&#x2F;a&gt;) are not just multivariate polynomial commitment schemes, but something more general: inner product commitment schemes. Let&#x27;s quickly define these:&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 1.&lt;&#x2F;strong&gt; An &lt;em&gt;Inner Product Commitment Scheme&lt;&#x2F;em&gt; has &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{commit}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; algorithms.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{commit}&lt;&#x2F;span&gt; algorithm takes a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v \in \F_q^n&lt;&#x2F;span&gt; and outputs a commitment &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{open}&lt;&#x2F;span&gt; algorithm takes a commitment &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;, a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w \in \F_q^n&lt;&#x2F;span&gt; and a value &lt;span class=&quot;math math-inline&quot;&gt;y \in \F_q&lt;&#x2F;span&gt; and outputs a proof &lt;span class=&quot;math math-inline&quot;&gt;\pi&lt;&#x2F;span&gt; that the inner product &lt;span class=&quot;math math-inline&quot;&gt;\vec v \cdot \vec w = \sum_{i \in [0,n)} v_i \cdot w_i&lt;&#x2F;span&gt; equals &lt;span class=&quot;math math-inline&quot;&gt;y&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{verify}&lt;&#x2F;span&gt; algorithm takes &lt;span class=&quot;math math-inline&quot;&gt;C, \vec w, y, \pi&lt;&#x2F;span&gt; and outputs true if the proof is valid and false otherwise.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Observe that this generalizes over polynomial commitment schemes: Take &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt; to be coefficients in some basis and &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; to be evaluations of the basis polynomials at a certain point. This works regardless of the basis so this includes Lagrange, monomial and multivariate bases.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;aside-verifier-succinctness&quot;&gt;Aside: Verifier Succinctness&lt;&#x2F;h3&gt;
&lt;p&gt;In the definition above, the verifier needs to process a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; of size &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. This is not ideal, as we would like the verifier&#x27;s work to be sub-linear in &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. Both WHIR and Ligerito only require the verifier to compute a single value from &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\widetilde{w} = \sum_{i \in [0,n)} \mathrm{eq}_i(\vec x) \cdot w_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;for some &lt;span class=&quot;math math-inline&quot;&gt;\vec x \in \F_q^k&lt;&#x2F;span&gt;. Here &lt;span class=&quot;math math-inline&quot;&gt;k \geq \log_2 n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{eq}_i(\vec x)&lt;&#x2F;span&gt; is the multi-linear basis polynomial that is 1 at &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; and 0 at all other indices, with indices interpreted as corners on the &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}^k&lt;&#x2F;span&gt; hypercube.&lt;&#x2F;p&gt;
&lt;p&gt;In the general case, this requires &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; work, but for many useful structures of &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; this can be computed more efficiently. Classifying these efficient structures is a topic for a future post. For now I&#x27;ll just note that they include monomial and multi-linear polynomial basis evaluation, so an inner product commitment scheme with this succinctness property is also a succinct polynomial commitment scheme.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;small-fields-and-bilinear-embeddings&quot;&gt;Small Fields and Bilinear Embeddings&lt;&#x2F;h2&gt;
&lt;p&gt;For technical reasons, we want to use WHIR over a large field, i.e. &lt;span class=&quot;math math-inline&quot;&gt;\norm{\F_q} &amp;gt; 2^{128}&lt;&#x2F;span&gt;. However, many applications require inner products over a small field, e.g. &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; a 31-bit prime. Typically this is solved by using a field extension &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^d}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; large enough that &lt;span class=&quot;math math-inline&quot;&gt;\norm{\F_{p^d}} &amp;gt; 2^{128}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;One can then take the natural embedding of &lt;span class=&quot;math math-inline&quot;&gt;\F_p^n&lt;&#x2F;span&gt; into &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^d}^n&lt;&#x2F;span&gt; by mapping each element of &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; to its representation in &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^d}&lt;&#x2F;span&gt;. Applying this to both vectors, the inner product can be computed in &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^d}&lt;&#x2F;span&gt;. The downside of this approach is that the vectors grow in size by a factor &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; in memory, and the computation by a factor &lt;span class=&quot;math math-inline&quot;&gt;d^2&lt;&#x2F;span&gt;. To reduce this overhead, several solutions have been proposed, notably Ring-Switching (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;504&quot;&gt;DP24&lt;&#x2F;a&gt;) as used in Binius. Here I&#x27;ll present a different, simpler approach that generalizes over a clever embedding discovered by Bryan Gillespie for inner products in multi-party computation (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;705&quot;&gt;BG+24&lt;&#x2F;a&gt; eq. 2).&lt;&#x2F;p&gt;
&lt;p&gt;Inner products are an example of a bilinear map, and the general embedding of bilinear maps in finite algebras looks like this:&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 2.&lt;&#x2F;strong&gt;
Given a bilinear map &lt;span class=&quot;math math-inline&quot;&gt;f:𝔽^n × 𝔽^m → 𝔽^k&lt;&#x2F;span&gt; and a finite &lt;span class=&quot;math math-inline&quot;&gt;𝔽&lt;&#x2F;span&gt;-algebra &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt;, an &lt;em&gt;embedding&lt;&#x2F;em&gt; or &lt;em&gt;packing&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt; is a triplet of linear maps &lt;span class=&quot;math math-inline&quot;&gt;(\mat A, \mat B, \mat C)&lt;&#x2F;span&gt; such that for all &lt;span class=&quot;math math-inline&quot;&gt;\vec x  ∈ 𝔽^n, \vec y  ∈ 𝔽^m&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(\vec x, \vec y) = \mat C \p{\mat A \vec x ⋅_K \mat B \vec y }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\mat A: 𝔽^n → K, \mat B: 𝔽^m → K&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mat C: K → 𝔽^k&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;⋅_K&lt;&#x2F;span&gt; denotes multiplication in &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt; is isomorphic to &lt;span class=&quot;math math-inline&quot;&gt;𝔽^l&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt; and given a representation of &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt; the &lt;span class=&quot;math math-inline&quot;&gt;\mat A, \mat B, \mat C&lt;&#x2F;span&gt; are represented by matrices.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 3.&lt;&#x2F;strong&gt;
If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is symmetric (i.e. &lt;span class=&quot;math math-inline&quot;&gt;f(x,y) = f(y,x)&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;x, y&lt;&#x2F;span&gt;) and &lt;span class=&quot;math math-inline&quot;&gt;(\mat A, \mat B, \mat C)&lt;&#x2F;span&gt; is an embedding, then so is &lt;span class=&quot;math math-inline&quot;&gt;(\mat B, \mat A, \mat C)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;This lemma is useful as we will have &lt;span class=&quot;math math-inline&quot;&gt;\mat A&lt;&#x2F;span&gt; the identity and this allows us to choose to apply &lt;span class=&quot;math math-inline&quot;&gt;\mat B&lt;&#x2F;span&gt; to either the committed vector or the weights vector.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;results-for-inner-products&quot;&gt;Results for Inner Products&lt;&#x2F;h2&gt;
&lt;p&gt;The main result we&#x27;ll derive here is&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 4.&lt;&#x2F;strong&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; inner products can be embedded in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;d = 2^n \cdot 3^m&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\mat A = \mat I&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mat B&lt;&#x2F;span&gt; a sparse matrix and &lt;span class=&quot;math math-inline&quot;&gt;\mat C&lt;&#x2F;span&gt; the projection on the first coordinate.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The restriction on the extension degree is likely not necessary in practice but it is hard to prove. Furthermore,&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s focus on embedding &lt;span class=&quot;math math-inline&quot;&gt;\F_q^d&lt;&#x2F;span&gt; inner products in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt;. Larger vectors can be handled by zero padding to the next largest multiple of &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; and doing a &lt;span class=&quot;math math-inline&quot;&gt;k=\ceil{\frac{n}{d}}&lt;&#x2F;span&gt;-sized inner product in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}^k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 5.&lt;&#x2F;strong&gt;
Given a field &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; represented by &lt;span class=&quot;math math-inline&quot;&gt;\F_q [X]&#x2F;(X^d - m_1 ⋅ X - m_0)&lt;&#x2F;span&gt;, there exists an embedding of the &lt;span class=&quot;math math-inline&quot;&gt;\F_q^d&lt;&#x2F;span&gt; inner product in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\mat A&lt;&#x2F;span&gt; the identity &lt;span class=&quot;math math-inline&quot;&gt;\mat I&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mat C&lt;&#x2F;span&gt; the projection on the first coefficient &lt;span class=&quot;math math-inline&quot;&gt;(1, 0, \dots, 0)&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;\mat B&lt;&#x2F;span&gt; the monomial matrix&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; \cdots &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; \cdots &amp;amp; 0 &amp;amp; m_0^{-1} \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; \cdots &amp;amp;  m_0^{-1} &amp;amp; 0 \\
\vdots &amp;amp; \vdots &amp;amp;\vdots &amp;amp; \ddots &amp;amp; \vdots &amp;amp; \vdots \\
0 &amp;amp; 0 &amp;amp; m_0^{-1} &amp;amp; \cdots &amp;amp; 0 &amp;amp; 0\\
0 &amp;amp; m_0^{-1} &amp;amp; 0 &amp;amp; \cdots &amp;amp; 0 &amp;amp; 0
\end{bmatrix}\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt;
The embedding of vectors &lt;span class=&quot;math math-inline&quot;&gt;(a_0, a_1, \dots, a_{d-1})&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(b_0, b_1, \dots, b_{d-1})&lt;&#x2F;span&gt; results in&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
a &amp;amp; = a_0 + a_1 \cdot X + \cdots + a_{d-1} \cdot X^{d-1} \\
b &amp;amp; = b_0 + m_0^{-1} \cdot \p{ b_{d-1} \cdot  X + \cdots + b_1 \cdot X^{d-1}} \\
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The product &lt;span class=&quot;math math-inline&quot;&gt;a⋅b&lt;&#x2F;span&gt; has powers up to &lt;span class=&quot;math math-inline&quot;&gt;X^{2⋅(d-1)}&lt;&#x2F;span&gt;. Note that in the quotient we have &lt;span class=&quot;math math-inline&quot;&gt;X^d = m_0 + m_1 ⋅ X&lt;&#x2F;span&gt;. Of the unreduced product, only &lt;span class=&quot;math math-inline&quot;&gt;X^0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;X^d&lt;&#x2F;span&gt; contribute to the constant term of the reduced result. To see this, consider a term &lt;span class=&quot;math math-inline&quot;&gt;X^{d + k}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;k ∈ [1, d-2]&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X^{d + k} = (m_0 + m_1 ⋅ X) ⋅ X^k = m_0⋅X^k + m_1⋅X^{k+1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;since &lt;span class=&quot;math math-inline&quot;&gt;k &amp;gt;0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;k+1 &amp;lt; d&lt;&#x2F;span&gt; this does not contribute to &lt;span class=&quot;math math-inline&quot;&gt;X^0&lt;&#x2F;span&gt;. Thus the constant term is given by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_0 \cdot b_0 + m_0 \cdot \p{a_1 \cdot m_0^{-1} \cdot b_1 + \cdots + a_{d-1} \cdot m_0^{-1} \cdot b_{d-1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which is the inner product as required.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Note that the &lt;span class=&quot;math math-inline&quot;&gt;\mat B&lt;&#x2F;span&gt; matrix is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Generalized_permutation_matrix&quot;&gt;monomial matrix&lt;&#x2F;a&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;, i.e. a generalized permutation matrix that allows for non-zero entries other than 1. These can be applied in at most &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; multiplications.&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 6.&lt;&#x2F;strong&gt; &lt;em&gt;Complex Numbers&lt;&#x2F;em&gt;. The field &lt;span class=&quot;math math-inline&quot;&gt;\mathbb{C}&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;\mathbb{R}[X]&#x2F;(X^2 + 1)&lt;&#x2F;span&gt;. Here &lt;span class=&quot;math math-inline&quot;&gt;m_1 = 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m_0 = -1&lt;&#x2F;span&gt;. The embedding matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat B&lt;&#x2F;span&gt; is thus&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat B = \begin{bmatrix}
1 &amp;amp; 0 \\
0 &amp;amp; -1
\end{bmatrix}\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The map &lt;span class=&quot;math math-inline&quot;&gt;\mat B&lt;&#x2F;span&gt; happens to correspond to complex conjugation. The inner product of two real vectors &lt;span class=&quot;math math-inline&quot;&gt;(a_0, a_1)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(b_0, b_1)&lt;&#x2F;span&gt; can thus be computed as the real part of&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(a_0 + a_1 \i) \cdot \overline{(b_0 + b_1 \i)} = (a_0 b_0 + a_1 b_1) + (a_1 b_0 - a_0 b_1) \i \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Lemma 5 requires an irreducible polynomial of the form &lt;span class=&quot;math math-inline&quot;&gt;X^d - m_1 ⋅ X - m_0&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;. Such polynomials are typically easy to find. It is however hard to &lt;em&gt;prove&lt;&#x2F;em&gt; that they exist. By construction they always exist for &lt;span class=&quot;math math-inline&quot;&gt;d=2&lt;&#x2F;span&gt; and by the Hansen–Mullen theorem (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20170827094158id_&#x2F;http:&#x2F;&#x2F;www.ams.org&#x2F;journals&#x2F;mcom&#x2F;1992-59-200&#x2F;S0025-5718-1992-1134730-7&#x2F;S0025-5718-1992-1134730-7.pdf&quot;&gt;HM92&lt;&#x2F;a&gt; conj. B, later proven) we know they exist for &lt;span class=&quot;math math-inline&quot;&gt;d=3&lt;&#x2F;span&gt;, but beyond that it is hard to prove. Instead, to get to larger fields we can use &lt;em&gt;towers&lt;&#x2F;em&gt; of extensions.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 7.&lt;&#x2F;strong&gt; (&lt;em&gt;Towers&lt;&#x2F;em&gt;)
Given a &lt;span class=&quot;math math-inline&quot;&gt;\F_q^m&lt;&#x2F;span&gt; inner product embedding in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^m}&lt;&#x2F;span&gt; given by &lt;span class=&quot;math math-inline&quot;&gt;(\mat A_m, \mat B_m, \mat C_m)&lt;&#x2F;span&gt; and an &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^m}^n&lt;&#x2F;span&gt; inner product embedding in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^{m \cdot n}}&lt;&#x2F;span&gt; given by &lt;span class=&quot;math math-inline&quot;&gt;(\mat A_n, \mat B_n, \mat C_n)&lt;&#x2F;span&gt;, we can construct an &lt;span class=&quot;math math-inline&quot;&gt;\F_q^{m \cdot n}&lt;&#x2F;span&gt; inner product embedding in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^{m \cdot n}}&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(\mat A_n&amp;#39; \cdot (\mat I_n \otimes \mat A_m), \mat B_n&amp;#39; \cdot (\mat I_n \otimes \mat B_m), \mat C_m \cdot \mat C_n&amp;#39;)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\mat A_n&amp;#39;, \mat B_n&amp;#39;, \mat C_n&amp;#39;&lt;&#x2F;span&gt; are &lt;span class=&quot;math math-inline&quot;&gt;\mat A_n, \mat B_n, \mat C_n&lt;&#x2F;span&gt; represented with coefficients in &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mat I_n&lt;&#x2F;span&gt; is the &lt;span class=&quot;math math-inline&quot;&gt;n \times n&lt;&#x2F;span&gt; identity matrix and &lt;span class=&quot;math math-inline&quot;&gt;\otimes&lt;&#x2F;span&gt; denotes the Kronecker product.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt;
Given vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec x, \vec y ∈ \F_q^{m \cdot n}&lt;&#x2F;span&gt; we can interpret them as &lt;span class=&quot;math math-inline&quot;&gt;\vec x = (\vec x_0, \vec x_1, \dots, \vec x_{n-1})&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec y = (\vec y_0, \vec y_1, \dots, \vec y_{n-1})&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\vec x_i, \vec y_i ∈ \F_q^m&lt;&#x2F;span&gt;. Using the first embedding we turn this into an &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^m}^n&lt;&#x2F;span&gt; inner product&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i \in [0,n)} \vec x_i \cdot \vec
y_i = \sum_{i \in [0,n)} \mat C_m \p{\mat A_m \vec x_i ⋅_{\F_{q^m}} \mat B_m \vec y_i} = \mat C_m \p{\sum_{i \in [0,n)} \mat A_m \vec x_i ⋅_{\F_{q^m}} \mat B_m \vec y_i}\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^m}^n&lt;&#x2F;span&gt; inner product is over two vectors&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\vec{\widetilde x} &amp;amp;= (\mat A_m \vec x_0, \mat A_m \vec x_1, \dots, \mat A_m \vec x_{n-1})
= (\mat I_n \otimes \mat A_m) \vec x \\
\vec{\widetilde y} &amp;amp;= (\mat B_m \vec y_0, \mat B_m \vec y_1, \dots, \mat B_m \vec y_{n-1})
= (\mat I_n \otimes \mat B_m) \vec y \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Applying the second embedding we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
C_n \p{\mat A_n \vec{\widetilde x} ⋅_{\F_{q^{m \cdot n}}} \mat B_n \vec{\widetilde y}}
&amp;amp;= C_n \p{\mat A_n&amp;#39; \cdot (\mat I_n \otimes \mat A_m) \vec x ⋅_{\F_{q^{m \cdot n}}} \mat B_n&amp;#39; \cdot (\mat I_n \otimes \mat B_m) \vec y} \text{.}
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where we used the mixed-product property of the Kronecker product. Finally, we need to apply &lt;span class=&quot;math math-inline&quot;&gt;\mat C_m&lt;&#x2F;span&gt; to get back to &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;, and this gets us the desired result.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Observe that the Kronecker product of identity matrices is an identity matrix, the Kronecker product of monomial matrices is a monomial matrix and the product of the first-coordinate projections is a first-coordinate projection. This proofs Lemma 4 by induction, starting from the base cases &lt;span class=&quot;math math-inline&quot;&gt;d=2&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;d=3&lt;&#x2F;span&gt; from Lemma 5 and applying Lemma 7 repeatedly.&lt;&#x2F;p&gt;
&lt;p&gt;While &lt;span class=&quot;math math-inline&quot;&gt;\mat B_n&lt;&#x2F;span&gt; is monomial this does not guarantee that &lt;span class=&quot;math math-inline&quot;&gt;\mat B_n&amp;#39;&lt;&#x2F;span&gt; is monomial. In practice we can and want to find values of &lt;span class=&quot;math math-inline&quot;&gt;m_0&lt;&#x2F;span&gt; that make this the case, and if we do then monomiality is preserved in towering.&lt;&#x2F;p&gt;
&lt;div class=&quot;example&quot; &gt;&lt;p&gt;&lt;strong&gt;Example 8.&lt;&#x2F;strong&gt; &lt;em&gt;Mersenne 31&lt;&#x2F;em&gt;. Take &lt;span class=&quot;math math-inline&quot;&gt;p = 2^{31} - 1&lt;&#x2F;span&gt; and a tower of extensions over &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align*}
\F_{p^2} &amp;amp;= \F_p [\i]&#x2F;(\i^2 + 1) \\
\F_{p^6} &amp;amp;= \F_{p^2} [\j]&#x2F;(\j^3 - 5)
\end{align*}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;then inner products can be embedded in &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^6}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\mat B =&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{pmatrix}
1 &amp;amp;  \phantom{-}0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; -1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp;  \phantom{-}0 &amp;amp; 0 &amp;amp; 0 &amp;amp; \phantom{-}5^{-1} &amp;amp; 0 \\
0 &amp;amp;  \phantom{-}0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; -5^{-1} \\
0 &amp;amp;  \phantom{-}0 &amp;amp;  \phantom{-}5^{-1} &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp;  \phantom{-}0 &amp;amp; 0 &amp;amp; -5^{-1} &amp;amp; 0 &amp;amp; 0  \\
\end{pmatrix}\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;The method presented here prescribes a particular representation of the field &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt;, but one can use any representation and make the appropriate change of basis to &lt;span class=&quot;math math-inline&quot;&gt;(\mat A, \mat B, \mat C)&lt;&#x2F;span&gt; matrices. This won&#x27;t necessarily preserve their sparsity, but it will still be an embedding. Fortunately, the prescribed representation is already very efficient and typical of what one would choose in practice.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;overhead&quot;&gt;Overhead&lt;&#x2F;h2&gt;
&lt;p&gt;The embedding is perfect in the sense that no memory is wasted. The overhead to apply &lt;span class=&quot;math math-inline&quot;&gt;\mat B&lt;&#x2F;span&gt; is also minimal, as it is a monomial matrix. The main overhead is in the field multiplications.&lt;&#x2F;p&gt;
&lt;p&gt;Directly evaluating the inner product would take &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; multiplications in &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt;. Using the embedding in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt;, we need &lt;span class=&quot;math math-inline&quot;&gt;k = \ceil{\frac{n}{d}}&lt;&#x2F;span&gt; multiplications in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt;. Each multiplication in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; takes &lt;span class=&quot;math math-inline&quot;&gt;d^2&lt;&#x2F;span&gt; multiplications in &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; using schoolbook multiplication. Thus the overhead is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{d^2 \cdot k}{n} \leq \frac{d^2 \cdot (n&#x2F;d + 1)}{n} = d + \frac{d^2}{n} \text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For the expected case of &lt;span class=&quot;math math-inline&quot;&gt;n \gg d&lt;&#x2F;span&gt; the number of multiplications increases roughly by the extension degree &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;open-questions&quot;&gt;Open questions&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;What is the most efficient embedding for other bilinear operations, e.g. matrix multiplication?&lt;&#x2F;li&gt;
&lt;li&gt;Is there a generalization of the towers lemma beyond inner products?&lt;&#x2F;li&gt;
&lt;li&gt;Before we project to the first coordinate, we have a bilinear map &lt;span class=&quot;math math-inline&quot;&gt;\F_q^d × \F_q^d → \F_q^d&lt;&#x2F;span&gt;. What is this map? Is it useful?&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; is has a succinct evaluation of &lt;span class=&quot;math math-inline&quot;&gt;\widetilde w&lt;&#x2F;span&gt;, can we also compute &lt;span class=&quot;math math-inline&quot;&gt;\widetilde{\mat B \vec w}&lt;&#x2F;span&gt; efficiently?&lt;&#x2F;li&gt;
&lt;li&gt;This embedding works for linear sumchecks, but what about quadratic sumchecks?&lt;&#x2F;li&gt;
&lt;li&gt;We can probably generalize this further and try to embed &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^e}^n&lt;&#x2F;span&gt; inner products in &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^d}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;d \neq e&lt;&#x2F;span&gt;. What is the best we can do here?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20170827094158id_&#x2F;http:&#x2F;&#x2F;www.ams.org&#x2F;journals&#x2F;mcom&#x2F;1992-59-200&#x2F;S0025-5718-1992-1134730-7&#x2F;S0025-5718-1992-1134730-7.pdf&quot;&gt;HM92&lt;&#x2F;a&gt; Tom Hansen, Gary L. Mullen (1992). Primitive Polynomials over Finite Fields.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;504&quot;&gt;DP24&lt;&#x2F;a&gt; Benjamin E. Diamond, Jim Posen (2024). Polylogarithmic Proofs for Multilinears over Binary Towers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;705&quot;&gt;BG+24&lt;&#x2F;a&gt; Remco Bloemen, Bryan Gillespie, Daniel Kales, Philipp Sippl, Roman Walch (2024). Large-Scale MPC: Scaling Private Iris Code Uniqueness Checks to Millions of Users.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;1586&quot;&gt;AC+24&lt;&#x2F;a&gt; Gal Arnon, Alessandro Chiesa, Giacomo Fenzi, Eylon Yogev (2024). WHIR: Reed–Solomon Proximity Testing with Super-Fast Verification.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2025&#x2F;1187&quot;&gt;NA25&lt;&#x2F;a&gt; Andrija Novakovic, Guillermo Angeris (2025). Ligerito: A Small and Concretely Fast Polynomial Commitment Scheme.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;sage-implementation&quot;&gt;Sage Implementation&lt;&#x2F;h1&gt;
&lt;p&gt;Here is a Sage implementation of the &lt;span class=&quot;math math-inline&quot;&gt;\mat A&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mat B&lt;&#x2F;span&gt; embeddings described above:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; embed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; extension_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # Check vector&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;    if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; isinstance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; sage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;Vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; TypeError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;x is not a vector&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; extension_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; is not&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; extension_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; extension_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;degree&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            # Tower: Recursively embed in base field first.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; embed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; extension_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;base_ring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;x is not a vector over the base field&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # Check extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; extension_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; extension_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;modulus&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;degree&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;dict&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;().&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;keys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;())&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; not in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;], [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; ValueError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;extension not of form X^d - m_1 X - m_0&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # Compute embedding coefficients&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    elif&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kind&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        raise&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; ArgumentError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;kind must be &amp;#39;A&amp;#39; or &amp;#39;B&amp;#39;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # Compute embedded vector (implicitly zero-pads)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;extension_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And here&#x27;s a test for various extension of M31:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; GF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;31&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;R&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; PolynomialRing&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;# Plain extensions over F&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F6&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;6&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;# Towered extensions over F2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;R2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; PolynomialRing&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; R2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;gen&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F22&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;F23&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;X&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        # Generate random vectors of length n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; VectorSpace&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;random_element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; VectorSpace&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;random_element&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        expected&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; FE&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F22&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F23&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; FE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;is_field&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            # Embed in FE and compute FE dot product&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            xe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; embed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; FE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;A&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            ye&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; embed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; FE&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;B&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; xe&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ye&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            # (Recursively) extract constant coefficient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            while&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;parent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            # Check against base field dot product&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;            assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; expected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nullifiers</title>
        <published>2025-01-12T00:00:00+00:00</published>
        <updated>2025-01-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/nullifiers/"/>
        <id>https://2π.com/25/nullifiers/</id>
        
        <content type="html" xml:base="https://2π.com/25/nullifiers/">&lt;h1 id=&quot;nullifiers&quot;&gt;Nullifiers&lt;&#x2F;h1&gt;
&lt;p&gt;It’s important to note that the nullifiers exist for one purpose only: to provide anonymity while preventing an account from repeating an action. For this to make sense at all creating accounts needs to be gated somehow. For anonymous currency (where nullifiers originate) an account is created on receiving a coin. In our case it is created on biometrically proven uniqueness.&lt;&#x2F;p&gt;
&lt;p&gt;Nullifiers achieve their purpose by assigning each (account, action) pair a verifiably unique pseudo-random number, the nullifier. The same account repeating the same action can then be blocked by rejecting repeated nullifiers. Anonymity is achieved by the pseudo-randomness of the nullifiers, which can not be linked back to accounts using public information. In our implementation, the nullifier is the hash of the private key with the action. The associated public key is publicly attached to the account. This allows the user to generate a zk-proof that it generated the nullifier correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Note that while the zk-proof in the process also proofs knowledge of the private key and allows signing a message, this a side-effects and could also be implemented in other ways. The major drawback of this approach is that it permanently attaches a unique private key to the user, or at least for the duration of the repeat protection. Knowledge of this key allows computing all the account’s nullifiers, thus a leak also implies full traceability of this account’s actions. Conversely, a loss of key means permanent inability to generate nullifiers for the account.&lt;&#x2F;p&gt;
&lt;p&gt;Nullifiers as we use them are just one way of achieving the purpose, and others could be imagined. It is however, to the best of our knowledge, the only way to achieve the whole goal in a fully decentralized setting. In situations where we do not care about anonymity, repeated actions or decentralization, we don’t need nullifiers and could substitute other methods with different trade-offs. Specifically:
If we don’t care about anonymity, regular signatures suffice.
If we don’t care about repeatability, zk-signatures suffice.
If we allow limited repeatability, reset counters
If we don’t care about decentralization and verifiability, a trusted service can provide repeat-prevention while keeping users secret.
If we don’t care about decentralization, a trusted service can generate verifiable nullifiers.&lt;&#x2F;p&gt;
&lt;p&gt;Before we go further I want to address the wide-spread abuse of our nullifiers. They are not intended to be re-used! By design they are there to prevent an action from re-occurring (e.g. double-spend in the case of anonymous currencies).
So the idea of using them as ‘logins’ is wrong and there can be no problem of replayability.&lt;&#x2F;p&gt;
&lt;p&gt;The major drawback of nullifiers having long-lived keys is exacerbated by our abuse of nullifiers and our reliance on its side-effect of signing. A more conformant design for one-per-human accounts would use a nullifier to gate account creation, and then use traditional methods to do authentication, authorization, recovery, etc. If this account needs anonymity, it can use its own methods (including nullifiers using a different keypair) to achieve that. This doesn’t solve all the problems of WorldID nullifier private keys, but should limit the impact of leak to deanonymization and loss to ability to create new accounts.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Oluś: a Pure CPS Language</title>
        <published>2025-01-12T00:00:00+00:00</published>
        <updated>2025-01-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/olus/"/>
        <id>https://2π.com/25/olus/</id>
        
        <content type="html" xml:base="https://2π.com/25/olus/">&lt;h1 id=&quot;olus-a-pure-continuation-passing-style-language&quot;&gt;Oluś: a Pure Continuation-Passing-Style Language&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;fact n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;is_zero n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) (:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) (:)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;fact&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;sub n&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;ve always been facinated by programming languages and proof systems (they are closely related). In particular I&#x27;m fascinated by expressive minimal languages like Lisp, Forth and Metamath. These repesent some stable local optima in the design space of languages. They are simple, expressive and powerful. They are also very different from each other. I&#x27;ve been exploring for a long time what the next stable optimum may look like, and I gravitated towards a language that takes continuation-passing-style to the extreme. As far as I know, such a language has not been implemented before.&lt;&#x2F;p&gt;
&lt;p&gt;Over many years I&#x27;ve build several compilers (e.g. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;Principia&quot;&gt;1&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;principia-cpp&quot;&gt;2&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;olus&quot;&gt;3&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;olus-rust&quot;&gt;4&lt;&#x2F;a&gt;) for variants of this language, some of which had unique properties. Pure CPS does not require a stack and one compiler produced x86 assembly that did not use a stack at all. This frees up &lt;code&gt;rsp&lt;&#x2F;code&gt; as a general purpose register, and, mostly for fun, I also made it use &lt;code&gt;push&lt;&#x2F;code&gt; and &lt;code&gt;pop&lt;&#x2F;code&gt; when writing&#x2F;reading from a data structure if it was pointed to by &lt;code&gt;rsp&lt;&#x2F;code&gt;. I&#x27;m sure it would have posed an interesting challenge to reverse engineers.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;continuation-passing-style&quot;&gt;Continuation Passing Style&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;scott-encoding&quot;&gt;Scott Encoding&lt;&#x2F;h2&gt;
&lt;p&gt;In CPS Scott encoding correspods to a &lt;code&gt;match&lt;&#x2F;code&gt; operator.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;syntax-and-sugar&quot;&gt;Syntax and Sugar&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;refrences&quot;&gt;Refrences&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Steele (1978). RABBIT: A Compiler for SCHEME&lt;&#x2F;li&gt;
&lt;li&gt;Kranz (1986). ORBIT: An Optimizing Compiler for Scheme.&lt;&#x2F;li&gt;
&lt;li&gt;Appel (1992). Compiling with Continuations.&lt;&#x2F;li&gt;
&lt;li&gt;Baker&#x27;s . CONS Should Not CONS Its Arguments.&lt;&#x2F;li&gt;
&lt;li&gt;Jim, Appel. Continuation-passing, Closure-passing Style.&lt;&#x2F;li&gt;
&lt;li&gt;Danvy, Filinski. Representing Control: A Study of the CPS Transformation.&lt;&#x2F;li&gt;
&lt;li&gt;Danvy, Filinski. Abstracting Control.&lt;&#x2F;li&gt;
&lt;li&gt;Danvy, Filinski. A Syntactic Theory of Control and State in Imperative Higher-Order Programming Languages.&lt;&#x2F;li&gt;
&lt;li&gt;Danvy, Filinski. A Functional Abstraction of Typed Contexts.&lt;&#x2F;li&gt;
&lt;li&gt;Sergey Dmitriev . Closure Inlining.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;roc-lang&#x2F;roc&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;legacy.cs.indiana.edu&#x2F;~dyb&#x2F;papers&#x2F;3imp.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2009.05539&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2502.20546&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Field Extensions</title>
        <published>2025-01-08T00:00:00+00:00</published>
        <updated>2025-01-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/extensions/"/>
        <id>https://2π.com/25/extensions/</id>
        
        <content type="html" xml:base="https://2π.com/25/extensions/">&lt;h1 id=&quot;field-extensions&quot;&gt;Field Extensions&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\norm#1{\left|{#1}\right|}
\gdef\F{\mathbb{F}}
\gdef\i{\mathrm{i}}
\gdef\j{\mathrm{j}}
\gdef\om{\mathrm{\omega}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a prime field &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;p = 2^{31} - 1&lt;&#x2F;span&gt;. Because &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; is a Mersenne prime, it can be implemented particularly efficiently. It also neatly fits into a 32-bit integer allowing fast SIMD and GPU implementations and efficient use of memory.&lt;&#x2F;p&gt;
&lt;p&gt;While fast, this field has two downsides: it does not support efficient NTTs and it is not large enough to effectively use the Schwartz-Zippel lemma. We can address both by constructing a larger field extension.&lt;&#x2F;p&gt;
&lt;p&gt;The smallest generator of the multiplicative group is &lt;span class=&quot;math math-inline&quot;&gt;7&lt;&#x2F;span&gt;, with order&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\norm{\F_p^\times} = 2 \cdot 3^2 \cdot 7 \cdot 11 \cdot 31 \cdot 151 \cdot 331
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The size of the field is almost 31-bits:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\log_2 \norm{\F_p} \approx 31 - 6.7\cdot10^{-10}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;complex-extension&quot;&gt;Complex Extension&lt;&#x2F;h2&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;-1&lt;&#x2F;span&gt; is not a square if &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; and thus &lt;span class=&quot;math math-inline&quot;&gt;X^2 + 1&lt;&#x2F;span&gt; is irreducible over &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt;. We can thus construct &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^2}&lt;&#x2F;span&gt; by the extension &lt;span class=&quot;math math-inline&quot;&gt;\F_p[X]&#x2F;(X^2 + 1)&lt;&#x2F;span&gt;. Because of analogy with complex numbers, we will call the root &lt;span class=&quot;math math-inline&quot;&gt;\i&lt;&#x2F;span&gt; and for &lt;span class=&quot;math math-inline&quot;&gt;a + b \cdot \i&lt;&#x2F;span&gt; we cann &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; the &lt;em&gt;real&lt;&#x2F;em&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; the &lt;em&gt;imaginary&lt;&#x2F;em&gt; component.&lt;&#x2F;p&gt;
&lt;p&gt;The complex extension has a generator &lt;span class=&quot;math math-inline&quot;&gt;12 + \i&lt;&#x2F;span&gt; with order&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\norm{\F_{p^2}^\times} = 2^{32} \cdot 3^2 \cdot 7 \cdot 11 \cdot 31 \cdot 151 \cdot 331
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So we can now efficiently perform NTTs up to size &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt;, larger than &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; itself! If we are ambitious, we can also implement &lt;span class=&quot;math math-inline&quot;&gt;3^2&lt;&#x2F;span&gt;, and use Rader&#x27;s NTT to &lt;span class=&quot;math math-inline&quot;&gt;7&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;2 \cdot 3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the 8-th roots of unity have nice structure:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\{ \pm 1, \pm i, \pm 2^{15} \pm 2^{15}\cdot\i \}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Frobenius endomorphism is given in coefficient form by the map&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; 0 \\
0 &amp;amp; -1
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which is also known as &lt;em&gt;complex conjugation&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;larger-extensions&quot;&gt;Larger extensions&lt;&#x2F;h2&gt;
&lt;p&gt;The complex extension is still not large enough for some cryptographic purposes:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\log_2 \norm{\F_p} \approx 62 - 1.34\cdot10^{-9}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With a target security of about &lt;span class=&quot;math math-inline&quot;&gt;128&lt;&#x2F;span&gt; bits, we need to look at a degree 4, 5 or 6 extension. We elliminate 5 as it does not have &lt;span class=&quot;math math-inline&quot;&gt;F_{p^2}&lt;&#x2F;span&gt; as a subfield. The degree 4 extension is slightly under our security target, and in practice we actually need some overhead. So we look at the degree 6 extension.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s construct &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^6}&lt;&#x2F;span&gt; as a cubic extension over &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^2}&lt;&#x2F;span&gt;, some low Hamming weight cubic non-roots in &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^2}&lt;&#x2F;span&gt; are &lt;span class=&quot;math math-inline&quot;&gt;5, 1 + 2 \cdot \i, 2 + \i, \dots&lt;&#x2F;span&gt;. Let&#x27;s pick the irriducible polynomial &lt;span class=&quot;math math-inline&quot;&gt;X^3 - 5&lt;&#x2F;span&gt; and construct &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^2}[X]&#x2F;(X^3 - 5)&lt;&#x2F;span&gt;. We&#x27;ll write the new cube root of &lt;span class=&quot;math math-inline&quot;&gt;5&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;\j&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\j^3 = 5&lt;&#x2F;span&gt; so we now have values &lt;span class=&quot;math math-inline&quot;&gt;a + b \cdot \j + c \cdot \j^2&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;a, b, c&lt;&#x2F;span&gt; themselves are complex.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; \om_3 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; \om_3^2
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\om_3 = 1513477735&lt;&#x2F;span&gt;. Together with conjugation, these generate the six elements of the automorphism group of &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^6}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dot-products&quot;&gt;Dot products&lt;&#x2F;h2&gt;
&lt;p&gt;We are interested in computing dot product over the vector space &lt;span class=&quot;math math-inline&quot;&gt;\F_p^n&lt;&#x2F;span&gt;. We want to do this by efficiently representing the vector space using elements of &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^6}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Observe that &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^2}&lt;&#x2F;span&gt; can be seen as an algebra over the vector space &lt;span class=&quot;math math-inline&quot;&gt;\F_p^2&lt;&#x2F;span&gt;. Equiped with a bilinear operator&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(a_0 + a_1 \cdot \i) \cdot (b_0 + b_1 \cdot \i) = (a_0 \cdot b_0 - a_1 \cdot b_1) + (a_0 \cdot b_1 + a_1 \cdot b_0) \cdot \i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Observe that the constant term is almost a dot product of the vectors &lt;span class=&quot;math math-inline&quot;&gt;(a_0, a_1)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(b_0, b_1)&lt;&#x2F;span&gt;. To fix it we only need to flip the sign on &lt;span class=&quot;math math-inline&quot;&gt;a_1&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;b_1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Observe that &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^6}&lt;&#x2F;span&gt; can be seen as an algebra over the vector space &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^2}^3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
(a_0 + a_1 \cdot j + a_2 \cdot \j^2) \cdot (b_0 + b_1 \cdot j + b_2 \cdot \j^2) = &amp;amp;\\
(a_0 \cdot b_0 + 5 \cdot a_1 \cdot b_2 + 5 \cdot a_2 \cdot b_1) +&amp;amp; \\
(a_0 \cdot b_1 + a_1 \cdot b_0 + 5 \cdot a_2 \cdot b_2) \cdot \j +&amp;amp; \\
(a_0 \cdot b_2 + a_1 \cdot b_1 + a_2 \cdot b_0) \cdot \j^2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;extension&quot;&gt;Extension&lt;&#x2F;h2&gt;
&lt;p&gt;When we create an extension &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&#x2F;(f)&lt;&#x2F;span&gt; with some polynomial &lt;span class=&quot;math math-inline&quot;&gt;f(X)&lt;&#x2F;span&gt;, we artificially create an element &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; that is a root of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;, i.e. &lt;span class=&quot;math math-inline&quot;&gt;f(\alpha) = 0&lt;&#x2F;span&gt; by decree.&lt;&#x2F;p&gt;
&lt;p&gt;If we have a different field of same degree, but with a different polynomial &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; then this will have a different artificial root &lt;span class=&quot;math math-inline&quot;&gt;\beta&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;g(\beta) = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;From ??? theorem it follows that these fields are isomorphic. That means there are functions between them such that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\phi(a + b) = \phi(a) + \phi(b)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\phi(a \cdot b) = \phi(a) \cdot \phi(b)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;From this it follows that &lt;span class=&quot;math math-inline&quot;&gt;\phi&lt;&#x2F;span&gt; preserves the identity elements &lt;span class=&quot;math math-inline&quot;&gt;0, 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It also follows that for &lt;span class=&quot;math math-inline&quot;&gt;c \in \F_p&lt;&#x2F;span&gt; &lt;span class=&quot;math math-inline&quot;&gt;\phi(c \cdot a) = c \cdot \phi(a)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\phi(c) = c&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\phi(0) = \phi(0 + 0) = \phi(0) + \phi(0)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this it follows that &lt;span class=&quot;math math-inline&quot;&gt;\phi(\alpha)&lt;&#x2F;span&gt; is a root of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;\F_\beta&lt;&#x2F;span&gt;. There are exactly &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; such roots. When we pick such a root, &lt;span class=&quot;math math-inline&quot;&gt;\phi&lt;&#x2F;span&gt; is fully specified.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;field-isomorphisms&quot;&gt;Field Isomorphisms&lt;&#x2F;h2&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 1.&lt;&#x2F;strong&gt; A &lt;em&gt;field isomorphism&lt;&#x2F;em&gt; is a bijective function between two fields &lt;span class=&quot;math math-inline&quot;&gt;A, B&lt;&#x2F;span&gt; such that for &lt;span class=&quot;math math-inline&quot;&gt;a, b \in A&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\phi(a + b) &amp;amp;= \phi(a) + \phi(b) \\
\phi(a \cdot b) &amp;amp;= \phi(a) \cdot \phi(b)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 1.&lt;&#x2F;strong&gt; If &lt;span class=&quot;math math-inline&quot;&gt;\phi&lt;&#x2F;span&gt; is a field isomorphism, then &lt;span class=&quot;math math-inline&quot;&gt;\phi^{-1}&lt;&#x2F;span&gt; is too.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; We need to proof &lt;span class=&quot;math math-inline&quot;&gt;\phi^{-1}(a + b) = \phi^{-1}(a) + \phi^{-1}(b)&lt;&#x2F;span&gt;, substitute this back into the relation for &lt;span class=&quot;math math-inline&quot;&gt;\phi&lt;&#x2F;span&gt; and apply &lt;span class=&quot;math math-inline&quot;&gt;\phi^{-1}&lt;&#x2F;span&gt; to both sides:
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\phi(\phi^{-1}(a) + \phi^{-1}(b)) &amp;amp;= \phi(\phi^{-1}(a)) + \phi(\phi^{-1}(b)) \\
\phi(\phi^{-1}(a) + \phi^{-1}(b)) &amp;amp;= a + b \\
\phi^{-1}\p{\phi(\phi^{-1}(a) + \phi^{-1}(b))} &amp;amp;= \phi^{-1}\p{a + b} \\
\phi^{-1}(a) + \phi^{-1}(b) &amp;amp;= \phi^{-1}\p{a + b} \\
\end{aligned}
&lt;&#x2F;span&gt;
Similarly for multiplication.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 2.&lt;&#x2F;strong&gt; Field isomorphism perserve &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;. Given fields &lt;span class=&quot;math math-inline&quot;&gt;A, B&lt;&#x2F;span&gt; and an isomorphism &lt;span class=&quot;math math-inline&quot;&gt;\phi: A \to B&lt;&#x2F;span&gt; we have
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\phi(0_A) &amp;amp;= 0_B \\
\phi(1_A) &amp;amp;= 1_B
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; Consider
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\phi(0_A) &amp;amp;= \phi(0_A + 0_A) \\
&amp;amp;= \phi(0_A) + \phi(0_A)
\end{aligned}
&lt;&#x2F;span&gt;
Subtracting &lt;span class=&quot;math math-inline&quot;&gt;\phi(0_A)&lt;&#x2F;span&gt; from both sides we obtain &lt;span class=&quot;math math-inline&quot;&gt;0_B = \phi(0_A)&lt;&#x2F;span&gt;. Now consider
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\phi(1_A) &amp;amp;= \phi(1_A \cdot 1_A) \\
&amp;amp;= \phi(1_A) \cdot \phi(1_A) \\
0_B &amp;amp;= \phi(1_A) \cdot (1_B -  \phi(1_A))
\end{aligned}
&lt;&#x2F;span&gt;
The two solutions are &lt;span class=&quot;math math-inline&quot;&gt;\phi(1_A) = 0_B&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\phi(1_A) = 1_B&lt;&#x2F;span&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; are non-trivial then &lt;span class=&quot;math math-inline&quot;&gt;0_B \neq 1_B&lt;&#x2F;span&gt; and the first solution is not possible because &lt;span class=&quot;math math-inline&quot;&gt;\phi&lt;&#x2F;span&gt; is bijective and the preimage of &lt;span class=&quot;math math-inline&quot;&gt;0_B&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;0_A&lt;&#x2F;span&gt;. Therefore, &lt;span class=&quot;math math-inline&quot;&gt;\phi(1_A) = 1_B&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 3.&lt;&#x2F;strong&gt; Isomorphism perserves the base field, for &lt;span class=&quot;math math-inline&quot;&gt;n \in \F_p&lt;&#x2F;span&gt;, we have &lt;span class=&quot;math math-inline&quot;&gt;\phi(n_A) = n_B&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;

&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; This follows from &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; generating the prime order subfield:
&lt;span class=&quot;math math-display&quot;&gt;
\phi(n_A) = \phi\p{\sum_{i\in[0,n)} 1_A} =\sum_{i\in[0,n)} \phi(1_A) = \sum_{i\in[0,n)} 1_B = n_B
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 4.&lt;&#x2F;strong&gt; Field isomorphisms are vector space isomorphisms.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Given a basis, vector space isomorphism are represented by invertible matrices.&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 5.&lt;&#x2F;strong&gt; The isomorphism is fully specified by the map of the extension generator, and there are exactly &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; isomorphisms.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 2.&lt;&#x2F;strong&gt; A &lt;em&gt;field automorphism&lt;&#x2F;em&gt; is a field isomorphism from &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; onto itself.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 6.&lt;&#x2F;strong&gt; The Frobenius map &lt;span class=&quot;math math-inline&quot;&gt;x \mapsto x^p&lt;&#x2F;span&gt; is a field automorphism.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 6.&lt;&#x2F;strong&gt; The Frobenius map generates all &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; field automorphisms.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;[Len91] H. Lenstra (1991). Finding isomorphism between finite fields.
[Len91]: https:&#x2F;&#x2F;people.tamu.edu&#x2F;~rojas&#x2F;&#x2F;lenstraFq.pdf&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;math&#x2F;9204234&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.math.u-bordeaux.fr&#x2F;~ballombe&#x2F;fpisom.ps&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hensel Lifting</title>
        <published>2025-01-08T00:00:00+00:00</published>
        <updated>2025-01-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/hensel-lifting/"/>
        <id>https://2π.com/25/hensel-lifting/</id>
        
        <content type="html" xml:base="https://2π.com/25/hensel-lifting/">&lt;h1 id=&quot;hensel-lifting&quot;&gt;Hensel Lifting&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\F{\mathbb{F}}
\gdef\Z{\mathbb{Z}}
\gdef\vd{𝛅}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are many variants of Hensel&#x27;s lemma and the one derived here is for quadratic lifting of multivariate roots. This is useful solving systems of polynomial equations in modular and Galois rings. One starts by finding a solution in the residue field where other methods may be available (e.g. exhaustive search). Once found, these residue field solutions are &#x27;lifted&#x27; to progressively larger rings until a solution in the target ring is found. See &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;therisingsea.org&#x2F;notes&#x2F;HenselsLemma.pdf&quot;&gt;Mur05&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;home.cs.colorado.edu&#x2F;~jgrochow&#x2F;hensel-notes.pdf&quot;&gt;Gro24&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kconrad.math.uconn.edu&#x2F;blurbs&#x2F;gradnumthy&#x2F;multivarhensel.pdf&quot;&gt;Con24&lt;&#x2F;a&gt; for alternative lemmas and further elaboration of the multivariate case.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;algebraic-preliminaries&quot;&gt;Algebraic Preliminaries&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;em&gt;ring&lt;&#x2F;em&gt; is a set of numbers with operations of addition and multiplication (in this post assumed finite, unital and commutative).  There is also a notion of division, but unlike fields this does not necessarily work for all non-zero numbers. An ubiquitous example of a ring is &lt;span class=&quot;math math-inline&quot;&gt;\Z_{2^{64}}&lt;&#x2F;span&gt;, the ring of 64-bit unsigned integers that all computers use. In this ring, multiplicative inverses exist only for odd numbers.&lt;&#x2F;p&gt;
&lt;p&gt;An &lt;em&gt;ideal&lt;&#x2F;em&gt; for a ring &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is a subset &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; that is closed under addition and multiplication, including multiplication by any element of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;. If the values of &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; are all the &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-multiples of a single element &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;, we write &lt;span class=&quot;math math-inline&quot;&gt;I = (p)&lt;&#x2F;span&gt; and called it a &lt;em&gt;principal ideal&lt;&#x2F;em&gt;.  The trivial ideals are &lt;span class=&quot;math math-inline&quot;&gt;(0) = \{0\}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(1) = R&lt;&#x2F;span&gt;. The ring &lt;span class=&quot;math math-inline&quot;&gt;\Z_{2^{64}}&lt;&#x2F;span&gt; has the ideals&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(1), (2), (2^2), (2^3), …, (2^{63}), (0).
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can also define the product of two ideals as &lt;span class=&quot;math math-inline&quot;&gt;I ⋅ J = \{i ⋅ j \mid i \in I, j \in J\}&lt;&#x2F;span&gt;. The product of two ideals is itself an ideal. We say an ideal &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; &lt;em&gt;squares to zero&lt;&#x2F;em&gt; if &lt;span class=&quot;math math-inline&quot;&gt;I ⋅ I = (0)&lt;&#x2F;span&gt;. This just means that for each &lt;span class=&quot;math math-inline&quot;&gt;a, b \in I&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;a ⋅ b = 0&lt;&#x2F;span&gt;. In &lt;span class=&quot;math math-inline&quot;&gt;\Z_{2^{64}}&lt;&#x2F;span&gt; the ideals &lt;span class=&quot;math math-inline&quot;&gt;(2^k)&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;k ≥ 32&lt;&#x2F;span&gt; square to zero.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;em&gt;quotient ring&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;I&lt;&#x2F;span&gt; is the set of all cosets &lt;span class=&quot;math math-inline&quot;&gt;r + I = \{r + i \mid i \in I\}&lt;&#x2F;span&gt; with addition and multiplication defined as &lt;span class=&quot;math math-inline&quot;&gt;(r + I) + (s + I) = (r + s) + I&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(r + I) ⋅ (s + I) = (r ⋅ s) + I&lt;&#x2F;span&gt;. The quotient ring is a ring itself, and captures the idea of &#x27;modulo &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt;&#x27; arithmetic. In fact, &lt;span class=&quot;math math-inline&quot;&gt;\Z_{2^{64}}&#x2F;(2^k) = \Z_{2^k}&lt;&#x2F;span&gt; is the ring of integers modulo &lt;span class=&quot;math math-inline&quot;&gt;2^k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An interesting theorem is that the quotient ring &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;I&lt;&#x2F;span&gt; is a field if and only if &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; is &lt;em&gt;maximal&lt;&#x2F;em&gt;, meaning there is no ideal &lt;span class=&quot;math math-inline&quot;&gt;J&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;I ⊂ J ⊂ R&lt;&#x2F;span&gt;. In the ring &lt;span class=&quot;math math-inline&quot;&gt;\Z_{2^{64}}&lt;&#x2F;span&gt; the ideal &lt;span class=&quot;math math-inline&quot;&gt;(2)&lt;&#x2F;span&gt; is maximal, producing the field &lt;span class=&quot;math math-inline&quot;&gt;\Z_{2^{64}}&#x2F;(2) = \F_2&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ideal-taylor-expansion&quot;&gt;Ideal Taylor Expansion&lt;&#x2F;h2&gt;
&lt;p&gt;Hensel lifting is analogous to Newton&#x27;s method, and it starts with an analogue of Taylor expansion:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 1.&lt;&#x2F;strong&gt;
Given ring &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; with ideal &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; that squares to zero and polynomial &lt;span class=&quot;math math-inline&quot;&gt;f \in R[X]&lt;&#x2F;span&gt; then for &lt;span class=&quot;math math-inline&quot;&gt;x \in R&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;δ \in I&lt;&#x2F;span&gt;, we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{equation}
f(x + δ) = f(x) + f&amp;#39;(x) ⋅ δ.
\end{equation}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt; Assume &lt;span class=&quot;math math-inline&quot;&gt;f(x) = x^m&lt;&#x2F;span&gt; and consider the binomial theorem for &lt;span class=&quot;math math-inline&quot;&gt;f(x + δ)&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(x + δ)^m = \sum_{i \in [0,m]} \binom{m}{i} ⋅ x^{m-i} ⋅ δ^i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;the terms &lt;span class=&quot;math math-inline&quot;&gt;i &amp;gt; 2&lt;&#x2F;span&gt; cancel due to &lt;span class=&quot;math math-inline&quot;&gt;δ^2 = 0&lt;&#x2F;span&gt;, leaving only&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x^m + m ⋅ x^{m-1} ⋅ δ = f(x) + f&amp;#39;(x) ⋅ δ.
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This proofs the case for &lt;span class=&quot;math math-inline&quot;&gt;f(x) = x^m&lt;&#x2F;span&gt;. By linearity it thus holds for all polynomials &lt;span class=&quot;math math-inline&quot;&gt;f \in R[x]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Curiously this result is exact. Where in real numbers truncating the Taylor expansion results in an error with some bound, in the present setting the result is exact. An explanation for this can be found in the theory of &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;-adic numbers, where closeness is defined in terms of how small the ideal is that contains the difference. This can be made rigorous using a counterintuitive but entirely valid alternative norm, but such a treatment is out of scope here.&lt;&#x2F;p&gt;
&lt;p&gt;The lemma generalizes to the multi-variate case as one would expect:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 2.&lt;&#x2F;strong&gt;
Given ring &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; with ideal &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; that squares to zero and polynomial map &lt;span class=&quot;math math-inline&quot;&gt;f: R^n \rightarrow R^m&lt;&#x2F;span&gt; then for &lt;span class=&quot;math math-inline&quot;&gt;\vec x \in R^n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vd \in I^n&lt;&#x2F;span&gt;, we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{equation}
f(\vec x + \vd) = f(\vec x) + \mat J_f (\vec x) ⋅ \vd
\end{equation}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the &lt;em&gt;Jacobian&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\mat J_f: R^n \rightarrow R^{m × n}&lt;&#x2F;span&gt; is given by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{equation}
\mat J_{i j} (\vec x) = \frac{\partial f_i}{\partial x_j} (\vec x).
\end{equation}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt;
Consider coordinates &lt;span class=&quot;math math-inline&quot;&gt;f_i&lt;&#x2F;span&gt; and apply the multi-binomial theorem analogous to lemma 1.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;lifting-roots&quot;&gt;Lifting Roots&lt;&#x2F;h2&gt;
&lt;p&gt;Lifting is the process of taking a solution from a quotient ring &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;I&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; itself:&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 3.&lt;&#x2F;strong&gt; &lt;em&gt;(Lift)&lt;&#x2F;em&gt;
Given ring &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; with ideal &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt;, polynomial map &lt;span class=&quot;math math-inline&quot;&gt;f: R^n → R^m&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;\vec x \in R^n&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(\vec x) = \vec 0 \pmod I
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;then &lt;em&gt;lifts&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; are &lt;span class=&quot;math math-inline&quot;&gt;\vec x&amp;#39; \in R^n&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\vec x&amp;#39; &amp;amp;= \vec x  \pmod I \\
f(\vec x&amp;#39;) &amp;amp;= \vec 0.
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 4.&lt;&#x2F;strong&gt;  &lt;em&gt;(Hensel Lifting)&lt;&#x2F;em&gt;
Suppose the ideal &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; squares to zero, then lifts of &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; are given by &lt;span class=&quot;math math-inline&quot;&gt;\vec x&amp;#39; = \vec x + \vd&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\vd \in I^n&lt;&#x2F;span&gt; solutions of&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{equation}
-f(\vec x) = \mat J _f (\vec x) ⋅ \vd.
\end{equation}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In particular if &lt;span class=&quot;math math-inline&quot;&gt;\mat J _f (\vec x)&lt;&#x2F;span&gt; is invertible there is a unique solution given by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{equation}
\vec x&amp;#39; = \vec x - \mat J_f^{-1} (\vec x) ⋅ f(\vec x).
\end{equation}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt;
Follows directly from lemma 2 and &lt;span class=&quot;math math-inline&quot;&gt;f(\vec x + \vd) = \vec 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;As familiar from linear algebra, &lt;span class=&quot;math math-inline&quot;&gt;\mat J_f (\vec x)&lt;&#x2F;span&gt; is invertible if and only if its determinant is invertible. It follows that if the determinant is invertible &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{mod} I&lt;&#x2F;span&gt;, it is also invertible in &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;. So if we have a chain of rings &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p^k)&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;\mat J_f (\vec x)&lt;&#x2F;span&gt; is invertible in the first, it is invertible in all rings. In this case the solution can be uniquely lifted to all the rings.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation-and-optimization&quot;&gt;Implementation and Optimization&lt;&#x2F;h2&gt;
&lt;p&gt;As an optimization, we often do not need to solve equation &lt;span class=&quot;math math-inline&quot;&gt;(4)&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; but can instead pick a smaller ring:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 5.&lt;&#x2F;strong&gt;
Given principal ideal &lt;span class=&quot;math math-inline&quot;&gt;I=(p)&lt;&#x2F;span&gt; that squares to zero and ideal &lt;span class=&quot;math math-inline&quot;&gt;J&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;I ⋅ J = (0)&lt;&#x2F;span&gt;, equation &lt;span class=&quot;math math-inline&quot;&gt;(4)&lt;&#x2F;span&gt; can be solved in &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;J&lt;&#x2F;span&gt; by setting &lt;span class=&quot;math math-inline&quot;&gt;\vd = \vd&amp;#39; ⋅ p&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\vd&amp;#39;&lt;&#x2F;span&gt; is the solution of&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{equation}
-\frac{f(\vec x)}{p} = \mat J _f (\vec x) ⋅ \vd&amp;#39; \pmod J.
\end{equation}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt;
Equation 4 is linear with both sides in &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt;. As an &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-module the ideal &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; is isomorhpic to &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;J&lt;&#x2F;span&gt; by the map &lt;span class=&quot;math math-inline&quot;&gt;x \mapsto x &#x2F; p&lt;&#x2F;span&gt; and the result follows.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Typically we use Hensel lifting over a ring &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; with ideals &lt;span class=&quot;math math-inline&quot;&gt;(p^s)&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;s \in [0,k]&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;(p)&lt;&#x2F;span&gt; is maximal and &lt;span class=&quot;math math-inline&quot;&gt;(p^k) = (0)&lt;&#x2F;span&gt;. We first find an initial solution in the residue field &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p)&lt;&#x2F;span&gt; and then lift it to &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p^2)&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;I = J = (p)&lt;&#x2F;span&gt;. Then we can either continue lifting to &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p^4)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p^16)&lt;&#x2F;span&gt;, …, &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p^k) = R&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;I_i = J_i = \p{p^{2^i}}&lt;&#x2F;span&gt;. Or alternatively, we can fix &lt;span class=&quot;math math-inline&quot;&gt;J = R&#x2F;(p)&lt;&#x2F;span&gt; and lift to &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p^3), R&#x2F;(p^4), …&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;I_i = (p^i)&lt;&#x2F;span&gt;. The former is known as &lt;em&gt;quadratic lifting&lt;&#x2F;em&gt; and the latter &lt;em&gt;linear lifting&lt;&#x2F;em&gt;. The quadratic method grows faster, but requires arithmetic in progressively larger rings. The linear method requires more iteration, but all arithmetic is in the residue field. Which one is faster depends on the specifics, but typically the quadratic method is preferred.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-functions&quot;&gt;Other Functions&lt;&#x2F;h2&gt;
&lt;p&gt;Note that the machinery of Hensel lifting works for any function &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; for which an &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;&lt;&#x2F;span&gt; can be defined such that lemma 1 holds. In particular it holds for rational functions with the familiar derivative:&lt;&#x2F;p&gt;
&lt;div class=&quot;lemma&quot; &gt;&lt;p&gt;&lt;strong&gt;Lemma 6.&lt;&#x2F;strong&gt; Given &lt;span class=&quot;math math-inline&quot;&gt;f(x) = p(x)&#x2F;q(x)&lt;&#x2F;span&gt; such that lemma 1 holds for &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;, then lemma 1 holds for &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; with derivative&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{equation}
f&amp;#39;(x) = \frac{p&amp;#39;(x) ⋅ q(x) - p(x) ⋅ q&amp;#39;(x)}{(q(x))^2}.
\end{equation}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;div class=&quot;proof&quot; &gt;&lt;p&gt;&lt;em&gt;Proof:&lt;&#x2F;em&gt;
Expand definitions,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(x + δ) = \frac{p(x + δ)}{q(x + δ)} = \frac{p(x) + p&amp;#39;(x) ⋅ δ}{q(x) + q&amp;#39;(x) ⋅ δ}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;drop the argument &lt;span class=&quot;math math-inline&quot;&gt;(x)&lt;&#x2F;span&gt; for brevity,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{p + p&amp;#39; ⋅ δ}{q + q&amp;#39; ⋅ δ}
= \frac{(p + p&amp;#39; ⋅ δ)⋅ (q - q&amp;#39; ⋅ δ)}{(q + q&amp;#39; ⋅ δ) ⋅ (q - q&amp;#39; ⋅ δ)}
= \frac{p⋅q + (p&amp;#39;⋅q - p⋅q&amp;#39;)⋅δ}{q^2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and thus&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(x + δ) = \frac{p}{q} + \frac{p&amp;#39;⋅q - p⋅q&amp;#39;}{q^2} ⋅ δ = f(x) + f&amp;#39;(x) ⋅ δ.
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;With this we can construct an efficient method for computing inverses in &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; by lifting the root &lt;span class=&quot;math math-inline&quot;&gt;a^{-1}&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;f(x) = x^{-1} - a&lt;&#x2F;span&gt;. This results in lifting equation &lt;span class=&quot;math math-inline&quot;&gt;x&amp;#39; = x ⋅ (2 - a ⋅ x)&lt;&#x2F;span&gt;, which is the basis of the fastest know inversion methods for &lt;span class=&quot;math math-inline&quot;&gt;\Z_{2^{64}}&lt;&#x2F;span&gt; (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marc-b-reynolds.github.io&#x2F;math&#x2F;2017&#x2F;09&#x2F;18&#x2F;ModInverse.html&quot;&gt;Rey22&lt;&#x2F;a&gt; for an overview). Implemented in Rust with further optimizations this looks like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ring_inv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Initial guess correct to 5 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Successively lift to 10, 20 and 40 bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrappining_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrappining_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Final lift to 80 bits (only 64 computed)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;therisingsea.org&#x2F;notes&#x2F;HenselsLemma.pdf&quot;&gt;Mur05&lt;&#x2F;a&gt; Daniel Murfet (2005). Hensel’s Lemma.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;marc-b-reynolds.github.io&#x2F;math&#x2F;2017&#x2F;09&#x2F;18&#x2F;ModInverse.html&quot;&gt;Rey22&lt;&#x2F;a&gt; Marc B Reynolds (2022). Integer multiplicative inverse via Newton&#x27;s method.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;home.cs.colorado.edu&#x2F;~jgrochow&#x2F;hensel-notes.pdf&quot;&gt;Gro24&lt;&#x2F;a&gt; Joshua A. Grochow (2024). A note on multivariate Hensel lifting.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kconrad.math.uconn.edu&#x2F;blurbs&#x2F;gradnumthy&#x2F;multivarhensel.pdf&quot;&gt;Con24&lt;&#x2F;a&gt; Keith Conrad (2024). A multivariable Hensel&#x27;s Lemma.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Winograd NTT</title>
        <published>2025-01-08T00:00:00+00:00</published>
        <updated>2025-01-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/25/winograd-ntt/"/>
        <id>https://2π.com/25/winograd-ntt/</id>
        
        <content type="html" xml:base="https://2π.com/25/winograd-ntt/">&lt;h1 id=&quot;winograd-ntt&quot;&gt;Winograd NTT&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\vec#1{\mathbf{#1}}
\gdef\F{\mathbb{F}}
\gdef\ω{\mathrm{ω}}
\gdef\A{\mathsf{\small A}}
\gdef\Mc{\mathsf{\small M^c}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;div class=&quot;definition&quot; &gt;&lt;p&gt;&lt;strong&gt;Definition 1.&lt;&#x2F;strong&gt; &lt;em&gt;(Number Theoretic Transform)&lt;&#x2F;em&gt;.
Given a finite field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; with primitive &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th root of unity &lt;span class=&quot;math math-inline&quot;&gt;\omega_n&lt;&#x2F;span&gt;
and a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec a \in \F^n&lt;&#x2F;span&gt; the &lt;em&gt;number theoretic transform&lt;&#x2F;em&gt; (NTT) &lt;span class=&quot;math math-inline&quot;&gt;\vec b \in \F^n&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; is
&lt;span class=&quot;math math-display&quot;&gt;
\begin{equation}
b_j = \sum_{i \in [n]} \ω_n^{i ⋅ j} ⋅ a_i.
\end{equation}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;As stated, equation &lt;span class=&quot;math math-inline&quot;&gt;(1)&lt;&#x2F;span&gt; requires &lt;span class=&quot;math math-inline&quot;&gt;n^2 ⋅ \Mc + n⋅(n-1) ⋅ \A&lt;&#x2F;span&gt; operations in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\Mc&lt;&#x2F;span&gt; is the cost of a multiplication by constant and &lt;span class=&quot;math math-inline&quot;&gt;\A&lt;&#x2F;span&gt; is the cost of an addition in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ntt-is-a-polynomial-evaluation&quot;&gt;NTT is a Polynomial Evaluation&lt;&#x2F;h2&gt;
&lt;p&gt;Construct a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P(x) = a_n ⋅ x^n + a_{n-1} ⋅ x^{n-1} + \ldots + a_1 ⋅ x + a_0&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;b_j = P(\omega_n^j)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;references&quot;&gt;References&lt;&#x2F;h1&gt;
&lt;p&gt;https:&#x2F;&#x2F;cr.yp.to&#x2F;arith&#x2F;tangentfft-20070919.pdf&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>WHIR</title>
        <published>2024-11-20T00:00:00+00:00</published>
        <updated>2024-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/whir/"/>
        <id>https://2π.com/24/whir/</id>
        
        <content type="html" xml:base="https://2π.com/24/whir/">&lt;h1 id=&quot;whir-multilinear-polynomial-commitments&quot;&gt;WHIR Multilinear Polynomial Commitments.&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\ps#1{\delim\{{#1}\}}
\gdef\F{\mathbb F}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\eq{\operatorname{eq}}
\gdef\∀{\mathop{\huge ∀}\limits}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;WHIR combines the ideas from STIR with those from Basefold to achieve a very performant polynomial commitment scheme for multilinear polynomials.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;iops&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;\Sigma&lt;&#x2F;span&gt;-IOPs&lt;&#x2F;h2&gt;
&lt;p&gt;Given a multilinear polynomial &lt;span class=&quot;math math-inline&quot;&gt;f ∈ \F[\vec X]&lt;&#x2F;span&gt; commited to by the prover and a &lt;em&gt;weight polynomial&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;w \in \F[Z, \vec X]&lt;&#x2F;span&gt; known to the prover and verifier, WHIR allows the verifier to check the following sum:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\sum_{\vec b \in \ps{0,1}^m} w\p{f(\vec b), \vec b} = σ
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This includes multivariate evaluation &lt;span class=&quot;math math-inline&quot;&gt;f(\vec r) = h&lt;&#x2F;span&gt; by setting weights &lt;span class=&quot;math math-inline&quot;&gt;w(z, \vec x) = z ⋅ \eq(\vec x, \vec r)&lt;&#x2F;span&gt;, which in turn contains univariate evaluation as a special case by evaluating &lt;span class=&quot;math math-inline&quot;&gt;f(\bar x)&lt;&#x2F;span&gt; using the map&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\bar x : \F &amp;amp;\rightarrow \F^m \\
x &amp;amp;\mapsto (x, x^2, x^4, x^8, …, x^{2^{m - 1}})\text{.}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we have multiple such claims &lt;span class=&quot;math math-inline&quot;&gt;w_i, σ_i&lt;&#x2F;span&gt; they can be batched together using a random challenge &lt;span class=&quot;math math-inline&quot;&gt;\gamma&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
w(z, \vec x) =  \sum_i γ^i ⋅ w_i\p{z, \vec x} &amp;amp;&amp;amp;
σ = \sum_i γ^i ⋅ σ_i\text{.}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;commitment&quot;&gt;Commitment&lt;&#x2F;h2&gt;
&lt;p&gt;To commit &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; it is Reed-Solomon encoded, i.e. evaluated over a foldable domain &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{L}&lt;&#x2F;span&gt; with rate &lt;span class=&quot;math math-inline&quot;&gt;\rho = \frac{2^m}{|\mathcal{L}|} &amp;lt; 1&lt;&#x2F;span&gt;. These values are commited in a Merkle tree. Denote with &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{L}^{(2^k)}&lt;&#x2F;span&gt; the &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-folded domain.&lt;&#x2F;p&gt;
&lt;p&gt;To boost soundness, the verifier can provide random challenges &lt;span class=&quot;math math-inline&quot;&gt;z_i \in \F&lt;&#x2F;span&gt; where the prover responds with &lt;span class=&quot;math math-inline&quot;&gt;f(\bar z_i)&lt;&#x2F;span&gt;. These evaluations are then included in the initial weight polynomial in an opening.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;opening&quot;&gt;Opening&lt;&#x2F;h2&gt;
&lt;p&gt;Given a commitment to &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;, the prover can proof a claim of the form &lt;span class=&quot;math math-inline&quot;&gt;(1)&lt;&#x2F;span&gt; using the protocol:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;While &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; is large:
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; run &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; rounds of sumcheck to reduce &lt;span class=&quot;math math-inline&quot;&gt;(1)&lt;&#x2F;span&gt; to a claim of the form
&lt;span class=&quot;math math-display&quot;&gt;
\sum_{\vec b \in \ps{0,1}^{m-k}} w\p{f(\vec r, \vec b), \vec r, \vec b} = h
&lt;&#x2F;span&gt;
where &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F^k&lt;&#x2F;span&gt; is a random vector.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; commits to &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;(\vec x) = f(\vec r, \vec x)&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{L}^{(2)}&lt;&#x2F;span&gt;. Note that this reduces the rate by &lt;span class=&quot;math math-inline&quot;&gt;2^{k-1}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; send a random challenge &lt;span class=&quot;math math-inline&quot;&gt;z_0 \in \F&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends the evaluation &lt;span class=&quot;math math-inline&quot;&gt;y_0 = f&amp;#39;(\bar z_0)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;For &lt;span class=&quot;math math-inline&quot;&gt;i \in [1,t]&lt;&#x2F;span&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends a random challenge &lt;span class=&quot;math math-inline&quot;&gt;z_i \in \mathcal{L}^{(2^k)}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; and &lt;strong&gt;prover&lt;&#x2F;strong&gt; evaluate &lt;span class=&quot;math math-inline&quot;&gt;y_i=f&amp;#39;(\bar z_i)&lt;&#x2F;span&gt; by querying &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; do &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; bits of proof-of-work.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; repeat with the updated claim with &lt;span class=&quot;math math-inline&quot;&gt;m&amp;#39; = m - k&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-display&quot;&gt;
\sum_{\vec b \in \ps{0,1}^{m&amp;#39;}} w&amp;#39;\p{f&amp;#39;(\vec b), \vec b} = h + \sum_{i \in [t]} \gamma^{i+1} ⋅ y_i
&lt;&#x2F;span&gt;
where the weight polynomial is updated as
&lt;span class=&quot;math math-display&quot;&gt;
w&amp;#39;\p{z, \vec x} = w\p{z, \vec r, \vec x} + z ⋅ \sum_{i \in [t]} \gamma^{i + 1} ⋅ \eq(\bar z_i, \vec x)\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; (now small) in full.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; run sumcheck to reduce &lt;span class=&quot;math math-inline&quot;&gt;(1)&lt;&#x2F;span&gt; to a claim of the form
&lt;span class=&quot;math math-display&quot;&gt;
w\p{f(\vec r), \vec r} = h
&lt;&#x2F;span&gt;
for random &lt;span class=&quot;math math-inline&quot;&gt;\vec r \in \F^m&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; checks the claim by evaluating &lt;span class=&quot;math math-inline&quot;&gt;z=f(\vec r)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;w(z, \vec r)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For evaluation proofs the final &lt;span class=&quot;math math-inline&quot;&gt;w&lt;&#x2F;span&gt; contains only a small number of &lt;span class=&quot;math math-inline&quot;&gt;\eq&lt;&#x2F;span&gt; terms and can be efficiently computed by the verifier. If &lt;span class=&quot;math math-inline&quot;&gt;w&lt;&#x2F;span&gt; is more complex (as is the case for GR1CS below) the prover can provide a proof of evaluation of &lt;span class=&quot;math math-inline&quot;&gt;w(z, \vec r)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gr1cs&quot;&gt;GR1CS&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;em&gt;generalized R1CS&lt;&#x2F;em&gt; relation for a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec z = (\vec z_{\text{public}}, \vec z_{\text{private}})&lt;&#x2F;span&gt; is a collection of constraints of the form&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i\p{\mat M_{i0}⋅\vec z, \mat M_{i1}⋅\vec z, …, \mat M_{in}⋅\vec z} = \vec 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;L_i&lt;&#x2F;span&gt; is a multivariate polynomial evaluated element-wise over the input vectors and &lt;span class=&quot;math math-inline&quot;&gt;\mat M_{ij}&lt;&#x2F;span&gt; are matrices. For example an R1CS instance has a single constraint &lt;span class=&quot;math math-inline&quot;&gt;L(a,b,c) = a ⋅ b - c&lt;&#x2F;span&gt; with three corresponding matrices.&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; to be the MLE of &lt;span class=&quot;math math-inline&quot;&gt;\vec z&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;f(0, ⋯)&lt;&#x2F;span&gt; is the MLE of &lt;span class=&quot;math math-inline&quot;&gt;\vec z_{\text{public}}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f(1, ⋯)&lt;&#x2F;span&gt; is the MLE of &lt;span class=&quot;math math-inline&quot;&gt;\vec z_{\text{private}}&lt;&#x2F;span&gt; and take &lt;span class=&quot;math math-inline&quot;&gt;M(\vec x, \vec y)&lt;&#x2F;span&gt; to be the MLE of &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt;. Define &lt;span class=&quot;math math-inline&quot;&gt;f_{ij}&lt;&#x2F;span&gt; to be&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_{ij}(\vec x) = \sum_{\vec y \in \ps{0,1}^m} M_{ij}(\vec x, \vec y) ⋅ f(\vec y)\text{.}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Observe that &lt;span class=&quot;math math-inline&quot;&gt;f_{ij}&lt;&#x2F;span&gt; is a quadratic polynomial that evaluates to the vector &lt;span class=&quot;math math-inline&quot;&gt;\mat M_{ij}⋅\vec z&lt;&#x2F;span&gt; on  &lt;span class=&quot;math math-inline&quot;&gt;\ps{0,1}^m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;f(0, ⋯)&lt;&#x2F;span&gt; in full and a commitment to &lt;span class=&quot;math math-inline&quot;&gt;f(1, ⋯)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends a random challenge &lt;span class=&quot;math math-inline&quot;&gt;\gamma \in \F&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; run zero-check on the claim
&lt;span class=&quot;math math-display&quot;&gt;
  \∀_{\vec x \in \ps{0,1}^m} \quad \sum_i \gamma^i ⋅ L_i\p{…, f_{ij}(\vec x),  …} = 0
&lt;&#x2F;span&gt;
to reduce it to
&lt;span class=&quot;math math-display&quot;&gt;
  \begin{align}
  \sum_i \gamma^i ⋅ L_i\p{…,f_{ij}(\vec r_1),  …} ⋅\eq(\vec r_1, \vec r_2) = h
  \end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; use WHIR to provide values for
&lt;span class=&quot;math math-display&quot;&gt;
  \sum_{\vec b \in \ps{0,1}^{m-1}} M_{ij}(\vec r_1, 1, \vec b) ⋅ f(1, \vec b)
&lt;&#x2F;span&gt;
by providing values computing the weighted sums
&lt;span class=&quot;math math-display&quot;&gt;
  w_{ij}(z, \vec x) = z ⋅ M_{ij}(\vec r_1, 1, \vec x)
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; computes values &lt;span class=&quot;math math-inline&quot;&gt;f_{ij}(\vec r_1)&lt;&#x2F;span&gt; and checks &lt;span class=&quot;math math-inline&quot;&gt;(2)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;WizardOfMenlo&#x2F;whir&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;WizardOfMenlo&#x2F;whir&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;1586&quot;&gt;ACFY24&lt;&#x2F;a&gt; Gal Arnon, Alessandro Chiesa, Giacomo Fenzi, Eylon Yogev (2024). WHIR: Reed–Solomon Proximity Testing with Super-Fast Verification.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Multivariate Lookup</title>
        <published>2024-11-18T00:00:00+00:00</published>
        <updated>2024-11-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/multi-lookup/"/>
        <id>https://2π.com/24/multi-lookup/</id>
        
        <content type="html" xml:base="https://2π.com/24/multi-lookup/">&lt;h1 id=&quot;multivariate-lookup-arguments&quot;&gt;Multivariate Lookup Arguments&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\ps#1{\delim\{{#1}\}}
\gdef\vec#1{\mathbf{#1}}
\gdef\eq{\operatorname{eq}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Most &lt;a href=&quot;&#x2F;24&#x2F;lookup&quot;&gt;lookup&lt;&#x2F;a&gt; protocols are based on univariate polynomials. In the multivariate &lt;a href=&quot;&#x2F;24&#x2F;sumcheck&quot;&gt;sumcheck&lt;&#x2F;a&gt; setting can use different techniques from the Lasso line of work.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Lookup arguments&lt;&#x2F;em&gt; and &lt;em&gt;indexed lookup arguments&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;grand-products&quot;&gt;Grand Products&lt;&#x2F;h2&gt;
&lt;p&gt;A grand product reduces a claim of the form &lt;span class=&quot;math math-inline&quot;&gt;a = \prod_{\vec x} p(\vec x)&lt;&#x2F;span&gt; to a claim of the form &lt;span class=&quot;math math-inline&quot;&gt;p(\vec r) = h&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;\vec r, h&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;351&quot;&gt;Tha13&lt;&#x2F;a&gt; Proposition 2 proposes a GKR-like protocol specialized for the grand product case.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_{i+1}(z) = \sum_{p \in \ps{0,1}^{n_i}} \eq (z,p) \cdot p_i(p, 0) \cdot p_i(p, 1)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1275&quot;&gt;SL20&lt;&#x2F;a&gt; Lemma 5.1&lt;&#x2F;p&gt;
&lt;p&gt;To prove&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p = \prod_{x \in \ps{0,1}^n} v(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
g(\vec z) = \sum_{\vec x \in \ps{0,1}^n} \eq (\vec z, \vec x) ⋅ \p{ f(1, \vec x) - f(\vec x, 0) ⋅ f(\vec x, 1) }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;g(\vec r_0) = 0&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;f(0, \vec r_1) =  v(\vec r_1)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;f(\vec 1, 0) = p&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Batching of grand products.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1216&quot;&gt;STW23&lt;&#x2F;a&gt; appendix E.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multiset-equality&quot;&gt;Multiset Equality&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;offline-memory-checking&quot;&gt;Offline Memory Checking&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;spark-surge&quot;&gt;Spark &#x2F; Surge&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;lasso&quot;&gt;Lasso&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;logup-gkr&quot;&gt;LogUp-GKR&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;generalized-lasso&quot;&gt;Generalized Lasso&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;351&quot;&gt;Tha13&lt;&#x2F;a&gt; Justin Thaler (2013). &quot;Time-Optimal Interactive Proofs for Circuit Evaluation&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;550&quot;&gt;Set19&lt;&#x2F;a&gt; Srinath Setty (2019). Spartan: Efficient and general-purpose zkSNARKs without trusted setup.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1216&quot;&gt;STW23&lt;&#x2F;a&gt; Srinath Setty, Justin Thaler, Riad Wahby (2023). Unlocking the lookup singularity with Lasso.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1284&quot;&gt;PH23&lt;&#x2F;a&gt; Shahar Papini, Ulrich Haböck (2023). Improving logarithmic derivative lookups using GKR.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1611&quot;&gt;Sou23&lt;&#x2F;a&gt; Lev Soukhanov (2023). Power circuits: a new arithmetization for
GKR-styled sumcheck.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Brakedown and Shockwave</title>
        <published>2024-07-23T00:00:00+00:00</published>
        <updated>2024-07-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/brakedown/"/>
        <id>https://2π.com/24/brakedown/</id>
        
        <content type="html" xml:base="https://2π.com/24/brakedown/">&lt;h1 id=&quot;brakedown-and-shockwave&quot;&gt;Brakedown and Shockwave&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\setn#1{\mathcal{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\vec#1{\mathbf{#1}}
\gdef\enc{\mathsf{enc}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;1043&quot;&gt;GLS⁺21&lt;&#x2F;a&gt;. Like in Hyrax, we will create a commitment to a matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat M ∈ 𝔽^{n×m}&lt;&#x2F;span&gt; such that we can later compute double contractions
&lt;span class=&quot;math math-display&quot;&gt;
s = \vec p ⋅ \mat M ⋅ \vec q =  \sum_{ij} \mat M_{ij}⋅p_i⋅q_j 
&lt;&#x2F;span&gt;
for some arbitrary vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec p, \vec q&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Take a linear code &lt;span class=&quot;math math-inline&quot;&gt;\enc: 𝔽^m→𝔽^M&lt;&#x2F;span&gt; with rate &lt;span class=&quot;math math-inline&quot;&gt;ρ = m&#x2F;M&lt;&#x2F;span&gt;.  When instantiated with a linear-time encoding codes, it is known as Brakedown Polynomial Commitments. When instantiated with Reed-Solomon codes, it is known as Ligero Polynomial Commitments &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1608&quot;&gt;AHIV17&lt;&#x2F;a&gt;. (And when used to instantiate Spartan they are known as Brakedown and Shockwave respectively.)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;commitment&quot;&gt;Commitment&lt;&#x2F;h3&gt;
&lt;p&gt;Prover has &lt;span class=&quot;math math-inline&quot;&gt;\mat M ∈ 𝔽^{n×m}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends the column-wise Merkle-hash of &lt;span class=&quot;math math-inline&quot;&gt;\mat E = [\enc(\mat M_i)]_{i∈[n]}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;evaluation&quot;&gt;Evaluation&lt;&#x2F;h3&gt;
&lt;p&gt;In addtion to above, prover and verifier have &lt;span class=&quot;math math-inline&quot;&gt;\vec p ∈ 𝔽^n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec q ∈ 𝔽^m&lt;&#x2F;span&gt; and want to compute the double contraction &lt;span class=&quot;math math-inline&quot;&gt;s = \vec p ⋅ \mat M ⋅ \vec q&lt;&#x2F;span&gt;. The protocol is as above, with &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; substituted by &lt;span class=&quot;math math-inline&quot;&gt;\vec p&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends random &lt;span class=&quot;math math-inline&quot;&gt;\mat R ∈ 𝔽^{k×n}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;\mat U = [\vec p; \mat R]⋅ \mat M&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verfier&lt;&#x2F;strong&gt; computes &lt;span class=&quot;math math-inline&quot;&gt;\mat C = [\enc(\mat U_i)]_{i∈[k]}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;\setn C ⊂ [m]&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; decommits columns &lt;span class=&quot;math math-inline&quot;&gt;\mat E_{\setn C}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; checks &lt;span class=&quot;math math-inline&quot;&gt;\mat C_{\setn C} = [\vec p; \mat R] ⋅ \mat E_{\setn C}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; checks &lt;span class=&quot;math math-inline&quot;&gt;s = \mat U_0 ⋅ \vec q&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;parameter-choices-for-reed-solomon-codes&quot;&gt;Parameter Choices for Reed-Solomon Codes&lt;&#x2F;h3&gt;
&lt;p&gt;Given security target &lt;span class=&quot;math math-inline&quot;&gt;λ&lt;&#x2F;span&gt; in bits. Assuming the matrix dimensions and encoding rate are fixed, the main protocol parameters are the number of random combinations &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; and queries &lt;span class=&quot;math math-inline&quot;&gt;|\setn C|&lt;&#x2F;span&gt;. Following &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;1043&quot;&gt;GLS⁺21&lt;&#x2F;a&gt; theorem B.7 (see also reference implementation &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;conroi&#x2F;lcpc&#x2F;blob&#x2F;f0e2116001af5a1bbf39481535f837d6a25772e8&#x2F;lcpc-2d&#x2F;src&#x2F;lib.rs#L613C1-L617C1&quot;&gt;1&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;conroi&#x2F;lcpc&#x2F;blob&#x2F;f0e2116001af5a1bbf39481535f837d6a25772e8&#x2F;lcpc-ligero-pc&#x2F;src&#x2F;lib.rs#L61C1-L62C1&quot;&gt;2&lt;&#x2F;a&gt;), these are set to:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
k = 1 + \left\lfloor \frac{λ - 1}{\log_2 |𝔽| - \log_2 M} \right\rfloor &amp;amp;&amp;amp;
|\setn C| = \left\lceil \frac{λ}{1 - \log_2 (1 +  \frac{m}{M})} \right\rceil
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;span class=&quot;math math-inline&quot;&gt;λ = 128&lt;&#x2F;span&gt; and large field &lt;span class=&quot;math math-inline&quot;&gt;|𝔽| ≥ 2^{200}&lt;&#x2F;span&gt; with reasonably sized &lt;span class=&quot;math math-inline&quot;&gt;M &amp;lt; 2^{64}&lt;&#x2F;span&gt;  we will always have &lt;span class=&quot;math math-inline&quot;&gt;k = 1&lt;&#x2F;span&gt;. The number of queries &lt;span class=&quot;math math-inline&quot;&gt;|\setn C|&lt;&#x2F;span&gt; decays exponentially from about &lt;span class=&quot;math math-inline&quot;&gt;2.5 ⋅ λ&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;M = 2⋅m&lt;&#x2F;span&gt; down to &lt;span class=&quot;math math-inline&quot;&gt;λ&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt; increases.&lt;&#x2F;p&gt;
&lt;p&gt;The randomized checks created by &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; serve to verify that the commitment is constructed correctly. This only has to be done once, so for repeated evaluations or when the commitment is trusted we can set &lt;span class=&quot;math math-inline&quot;&gt;k=0&lt;&#x2F;span&gt; (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;1043&quot;&gt;GLS⁺21&lt;&#x2F;a&gt; p. 12).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Does the process of grinding as used in FRI help to boost soundness and reduce &lt;span class=&quot;math math-inline&quot;&gt;|\setn C|&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1608&quot;&gt;AHIV17&lt;&#x2F;a&gt; Scott Ames, Carmit Hazay, Yuval Ishai &amp;amp; Muthuramakrishnan Venkitasubramaniam (2017). Ligero: Lightweight Sublinear Arguments Without a Trusted Setup.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1426&quot;&gt;BCG20&lt;&#x2F;a&gt; Jonathan Bootle, Alessandro Chiesa, and Jens Groth (2020). Linear-Time Arguments with Sublinear Verification from Tensor Codes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;1043&quot;&gt;GLS⁺21&lt;&#x2F;a&gt; Alexander Golovnev, Jonathan Lee, Srinath Setty, Justin Thaler, Riad S. Wahby (2021). Brakedown: Linear-time and field-agnostic SNARKs for R1CS.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hyrax Commitments</title>
        <published>2024-07-16T00:00:00+00:00</published>
        <updated>2024-07-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/hyrax-pcs/"/>
        <id>https://2π.com/24/hyrax-pcs/</id>
        
        <content type="html" xml:base="https://2π.com/24/hyrax-pcs/">&lt;h1 id=&quot;hyrax-commitments&quot;&gt;Hyrax Commitments&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\vec#1{\mathbf{#1}}
\gdef\eq{\mathrm{eq}}
\gdef\setn#1{\mathcal #1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Hyrax commitments are introduced in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1132.pdf&quot;&gt;WTS⁺17&lt;&#x2F;a&gt;. They are a polynomial commitment scheme designed for &lt;a href=&quot;&#x2F;24&#x2F;sumcheck#multi-linear-extensions--MLEs-&quot;&gt;multi-linear extenstions&lt;&#x2F;a&gt; (MLEs).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;certain-multivariate-sums-as-tensor-contractions&quot;&gt;Certain Multivariate Sums as Tensor Contractions&lt;&#x2F;h2&gt;
&lt;p&gt;Given a finite multi-variate basis &lt;span class=&quot;math math-inline&quot;&gt;\setn B = \setn B_1 × \setn B_2 × ⋯ × \setn B_n&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\setn B_i ⊂ 𝔽&lt;&#x2F;span&gt; and a sum of the form
&lt;span class=&quot;math math-display&quot;&gt;
\sum_{\vec b ∈ \setn B} g(\vec b) ⋅ \prod_{k ∈ [n]} e_k(b_k)
&lt;&#x2F;span&gt;
where &lt;span class=&quot;math math-inline&quot;&gt;g : 𝔽^n → 𝔽&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;e_k: 𝔽 → 𝔽&lt;&#x2F;span&gt; are arbitrary and &lt;span class=&quot;math math-inline&quot;&gt;b_k&lt;&#x2F;span&gt; denotes the &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-th component of &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt;. Given any binary partitioning &lt;span class=&quot;math math-inline&quot;&gt;[n] = \setn A ∪ \setn B&lt;&#x2F;span&gt; we can rewrite this as
&lt;span class=&quot;math math-display&quot;&gt;
\sum_{\vec a ∈ \setn B_{\setn A}}\sum_{\vec b ∈ \setn B_{\setn B}} g(\vec a, \vec b) ⋅ \p{\prod_{k ∈ \setn A}  e_k(a_k)} ⋅ \p{\prod_{k ∈ \setn B} e_k(b_k)}
&lt;&#x2F;span&gt;
Observe that the products only depend on &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; respectively. Since &lt;span class=&quot;math math-inline&quot;&gt;\setn B_{\setn A}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\setn B_{\setn B}&lt;&#x2F;span&gt; are finite we can enumerate their values as &lt;span class=&quot;math math-inline&quot;&gt;\{\vec a_i\} = \setn B_{\setn A}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\{\vec b_j\} = \setn B_{\setn B}&lt;&#x2F;span&gt; and define
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
g_{ij} &amp;amp;= g(\vec a_i, \vec b_j) &amp;amp;
u_i &amp;amp;= \prod_{k ∈ \setn A}  e_k((\vec a_i)_k) &amp;amp;
v_j &amp;amp;= \prod_{k ∈ \setn B}  e_k((\vec b_j)_k)
\end{aligned}
&lt;&#x2F;span&gt;
we can then rewrite the sum as a vector-matrix-vector product, also known as a rank-&lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt; tensor contraction
&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i ∈ [|\setn B_{\setn A}|]}\sum_{j ∈ [|\setn B_{\setn B}|]} g_{ij} ⋅ u_i ⋅ v_j
&lt;&#x2F;span&gt;
This generalizes to &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;-ary partitionings resulting in rank-&lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; tensors &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; vectors to contract with. Higher rank tensors do not appear to give an advantage in the Hyrax commitments described below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mle-evaluation-as-rank-2-tensor-contraction&quot;&gt;MLE Evaluation as Rank-2 Tensor Contraction&lt;&#x2F;h2&gt;
&lt;p&gt;Recall a &lt;a href=&quot;&#x2F;24&#x2F;sumcheck&#x2F;#multilinear-extensions-mles&quot;&gt;multi-linear extenion&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\tilde f: 𝔽^n → 𝔽&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\vec b ∈ \{0, 1\}^n&lt;&#x2F;span&gt; has &lt;span class=&quot;math math-inline&quot;&gt;2^n&lt;&#x2F;span&gt; coefficients &lt;span class=&quot;math math-inline&quot;&gt;f_{\vec b} ∈ 𝔽&lt;&#x2F;span&gt; and is defined as
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\tilde{f}(\vec x) &amp;amp;= \sum_{\vec b ∈ [2^n]} f_{\vec b} ⋅ \eq(\vec b_, \vec x) \\
\end{aligned}
&lt;&#x2F;span&gt;
where &lt;span class=&quot;math math-inline&quot;&gt;\eq&lt;&#x2F;span&gt; is the &lt;a href=&quot;&#x2F;24&#x2F;sumcheck&#x2F;#the-equality-function&quot;&gt;&lt;em&gt;equality function&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; that indicates &lt;span class=&quot;math math-inline&quot;&gt;\vec b = \vec x&lt;&#x2F;span&gt; on the basis &lt;span class=&quot;math math-inline&quot;&gt;\{0, 1\}^n&lt;&#x2F;span&gt;. It is given explicitely by
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\eq(\vec x, \vec y) &amp;amp;= \prod_{i∈[n]} \eq(x_i, y_i) \\
\eq(x, y) &amp;amp;= x⋅y  + (1-x)⋅(1-y)\\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Observe that for a given &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; the sum &lt;span class=&quot;math math-inline&quot;&gt;\tilde{f}(\vec x)&lt;&#x2F;span&gt; satisfies the form required to rewrite as a rank-2 tensor contraction &lt;span class=&quot;math math-inline&quot;&gt;\sum_{\vec a \vec b} f_{\vec a \vec b} ⋅ u_{\vec a}(\vec x) ⋅ v_{\vec b}(\vec x)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;polynomial-evaluation-as-rank-2-tensor-contraction&quot;&gt;Polynomial Evaluation as Rank-2 Tensor Contraction&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;span class=&quot;math math-inline&quot;&gt;2^n&lt;&#x2F;span&gt;-term polynomial &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; evaluated in &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(x) = \sum_{i ∈ [2^n]} f_i ⋅ \prod_{k∈[n]} \p{x^{2^k}}^{i_k}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;i_k&lt;&#x2F;span&gt; denotes the &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-th bit of the number &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hyrax-commitments-1&quot;&gt;Hyrax Commitments&lt;&#x2F;h2&gt;
&lt;p&gt;Given a tensor contraction &lt;span class=&quot;math math-inline&quot;&gt;\tilde f(\vec x) = \sum_{\vec a \vec b} f_{\vec a \vec b} ⋅ u_{\vec a}(\vec x) ⋅ v_{\vec b}(\vec x)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;f_{\vec a \vec b}&lt;&#x2F;span&gt; known to the prover and &lt;span class=&quot;math math-inline&quot;&gt;u_{\vec a}(\vec x)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;v_{\vec b}(\vec x)&lt;&#x2F;span&gt; known to prover and verifier. The prover wants to commit to &lt;span class=&quot;math math-inline&quot;&gt;f_{\vec a \vec b}&lt;&#x2F;span&gt; so that it can later open &lt;span class=&quot;math math-inline&quot;&gt;\tilde f(\vec x)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Take a linear vector commitment scheme &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{commit}: 𝔽^m → \setn C&lt;&#x2F;span&gt; that supports dot-product proofs. To commit to &lt;span class=&quot;math math-inline&quot;&gt;f_{\vec a \vec b}&lt;&#x2F;span&gt; the prover computes &lt;span class=&quot;math math-inline&quot;&gt;c_{\vec a} = \operatorname{commit}(f_{\vec a-})&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;f_{\vec a-}&lt;&#x2F;span&gt; is the vector with &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; held fixed. The prover sends &lt;span class=&quot;math math-inline&quot;&gt;\{c_{\vec a} \}_{\vec a ∈ \setn B_{\setn A}}&lt;&#x2F;span&gt; to the verifier.&lt;&#x2F;p&gt;
&lt;p&gt;To open at &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; the prover send &lt;span class=&quot;math math-inline&quot;&gt;\tilde{f}(\vec x)&lt;&#x2F;span&gt;, the prover and verifier compute vectors &lt;span class=&quot;math math-inline&quot;&gt;u_{\vec a} = u_{\vec a}(\vec x)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;v_{\vec b} = v_{\vec b}(\vec x)&lt;&#x2F;span&gt; and combine the commitments &lt;span class=&quot;math math-inline&quot;&gt;c = \sum_{\vec a ∈ \setn B_{\setn A}} u_{\vec a} ⋅ c_{\vec a}&lt;&#x2F;span&gt;. The prover and verifier then engage the dot-product-proof protocol to prove that &lt;span class=&quot;math math-inline&quot;&gt;\tilde{f}(\vec x)&lt;&#x2F;span&gt; is the dot produt of &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;v_{\vec b}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The size of the commitment is &lt;span class=&quot;math math-inline&quot;&gt;|\setn B_{\vec A}|&lt;&#x2F;span&gt; times the size of a vector commitment. The size of the opening argument is a single dot-product-opening argument. The prover work to commit is &lt;span class=&quot;math math-inline&quot;&gt;|\setn B_{\vec A}|&lt;&#x2F;span&gt; times a size &lt;span class=&quot;math math-inline&quot;&gt;|\setn B_{\vec B}|&lt;&#x2F;span&gt; vector commitment. The prover and verifier work on opening is computing the vectors &lt;span class=&quot;math math-inline&quot;&gt;u_{\vec a}, v_{\vec b}&lt;&#x2F;span&gt;, the linear combination &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; and the dot-product-argument.&lt;&#x2F;p&gt;
&lt;p&gt;The case where &lt;span class=&quot;math math-inline&quot;&gt;|\setn B_{\vec A}| = |\setn B_{\vec B}| = \sqrt{|\setn B|}&lt;&#x2F;span&gt; is called the &lt;em&gt;square-root&lt;&#x2F;em&gt; Hyrax commitment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pederson-vector-commitments&quot;&gt;Pederson vector commitments&lt;&#x2F;h2&gt;
&lt;p&gt;To construct a linear vector commitment scheme for &lt;span class=&quot;math math-inline&quot;&gt;𝔽^m&lt;&#x2F;span&gt; pick a discrete-log hard cyclic group of order &lt;span class=&quot;math math-inline&quot;&gt;|𝔽|&lt;&#x2F;span&gt; (note that this is also a &lt;span class=&quot;math math-inline&quot;&gt;𝔽&lt;&#x2F;span&gt;-vector space). Pick random generators &lt;span class=&quot;math math-inline&quot;&gt;\mathrm h, \{\mathrm g_i\}_{i∈ [m]}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To commit to &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ 𝔽^m&lt;&#x2F;span&gt;, the prover picks random &lt;span class=&quot;math math-inline&quot;&gt;s ∈ 𝔽^×&lt;&#x2F;span&gt; and sends &lt;span class=&quot;math math-inline&quot;&gt;\mathrm c = s⋅\mathrm h + \sum_{i} x_i ⋅ \mathrm g_i&lt;&#x2F;span&gt;. The prover and verifier can compute linear combinations of the commitments, the prover also linearly combines the &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; values. To open the prover sends &lt;span class=&quot;math math-inline&quot;&gt;s, \vec x&lt;&#x2F;span&gt; and the verifier checks the commitment.&lt;&#x2F;p&gt;
&lt;p&gt;When &lt;span class=&quot;math math-inline&quot;&gt;m=1&lt;&#x2F;span&gt; we call this a &lt;em&gt;scalar commitment scheme&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proof-of-equality&quot;&gt;Proof of Equality&lt;&#x2F;h3&gt;
&lt;p&gt;Given two commitments &lt;span class=&quot;math math-inline&quot;&gt;\mathrm c_1, \mathrm c_2&lt;&#x2F;span&gt; with secrets &lt;span class=&quot;math math-inline&quot;&gt;s_1, s_2&lt;&#x2F;span&gt;. To proof they commit to the same vector without revealing,&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; picks random &lt;span class=&quot;math math-inline&quot;&gt;s ∈ 𝔽^×&lt;&#x2F;span&gt; and sends &lt;span class=&quot;math math-inline&quot;&gt;\mathrm c = s⋅\mathrm h&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends random &lt;span class=&quot;math math-inline&quot;&gt;r ∈ 𝔽^×&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;z = r ⋅ (s_1 - s_2) + s&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; checks &lt;span class=&quot;math math-inline&quot;&gt;z⋅\mathrm h = r ⋅ (\mathrm c_1 - \mathrm c_2) + \mathrm c&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;proof-of-product&quot;&gt;Proof of Product&lt;&#x2F;h3&gt;
&lt;p&gt;Given scalars &lt;span class=&quot;math math-inline&quot;&gt;a, b, c&lt;&#x2F;span&gt;, and their commitments &lt;span class=&quot;math math-inline&quot;&gt;\mathrm c_a, \mathrm c_b, \mathrm c_c&lt;&#x2F;span&gt;, with secrets &lt;span class=&quot;math math-inline&quot;&gt;s_a, s_b, s_c&lt;&#x2F;span&gt;. To proof that &lt;span class=&quot;math math-inline&quot;&gt;a ⋅ b = c&lt;&#x2F;span&gt;,&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; picks random &lt;span class=&quot;math math-inline&quot;&gt;u, v, s_u, s_v, s_w ∈ 𝔽^×&lt;&#x2F;span&gt; and sends
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm u &amp;amp;= s_u ⋅ \mathrm h + u ⋅ \mathrm g \\
\mathrm v &amp;amp;= s_v ⋅ \mathrm h + v ⋅ \mathrm g \\
\mathrm w &amp;amp;= s_w ⋅ \mathrm h + v ⋅ \mathrm c_a \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends random &lt;span class=&quot;math math-inline&quot;&gt;r ∈ 𝔽^×&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
z_{s_a} &amp;amp;= s_u + r ⋅ s_a &amp;amp;
z_a &amp;amp;= u + r ⋅ a \\
z_{s_b} &amp;amp;= s_v + r ⋅ s_b &amp;amp;
z_b &amp;amp;= v + r ⋅ b \\
z &amp;amp;= s_w + r ⋅ (s_c - s_a ⋅ b) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; checks that
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm u + r ⋅ \mathrm c_a &amp;amp;= z_{s_a} ⋅ \mathrm h + z_a ⋅ \mathrm g \\
\mathrm v + r ⋅ \mathrm c_b &amp;amp;= z_{s_b} ⋅ \mathrm h + z_b ⋅ \mathrm g \\
\mathrm w + r ⋅ \mathrm c_c &amp;amp;= z ⋅ \mathrm h + z_b ⋅ \mathrm c_a \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first two equalities are straight forward, the last one&#x27;s left and right side expand to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm w + r ⋅ \mathrm c_c
&amp;amp;= s_w ⋅ \mathrm h + v ⋅ (s_a ⋅ \mathrm h + a ⋅\mathrm g) + r ⋅ (s_c ⋅ \mathrm h + c ⋅\mathrm g) \\
&amp;amp;= (s_w + v⋅s_a +r⋅s_c) ⋅ \mathrm h + (v ⋅ a + r⋅c)⋅\mathrm g \\
z ⋅ \mathrm h + z_b ⋅ \mathrm c_a
&amp;amp;= (s_w + r ⋅ (s_c - s_a ⋅ b)) ⋅ \mathrm h + (v + r ⋅ b) ⋅ (s_a ⋅ \mathrm h + a ⋅\mathrm g) \\
&amp;amp;= (s_w + v ⋅ s_a + r ⋅ s_c) ⋅ \mathrm h +  (v ⋅ a + r ⋅ b ⋅ a) ⋅ \mathrm g \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proof-of-dot-product&quot;&gt;Proof of Dot Product&lt;&#x2F;h3&gt;
&lt;p&gt;Given vector &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; with commitment &lt;span class=&quot;math math-inline&quot;&gt;\mathrm c_a&lt;&#x2F;span&gt; and secret &lt;span class=&quot;math math-inline&quot;&gt;s_a&lt;&#x2F;span&gt;, a scalara &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; with commitment &lt;span class=&quot;math math-inline&quot;&gt;\mathrm c_c&lt;&#x2F;span&gt; and secret &lt;span class=&quot;math math-inline&quot;&gt;s_c&lt;&#x2F;span&gt; and public vector &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt;. To proof that &lt;span class=&quot;math math-inline&quot;&gt;c = \vec a ⋅ \vec b&lt;&#x2F;span&gt;,&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; picks random &lt;span class=&quot;math math-inline&quot;&gt;\vec s ∈ (𝔽^×)^m&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;s_u, s_v ∈ 𝔽^×&lt;&#x2F;span&gt; and sends
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm u &amp;amp;= s_u ⋅ \mathrm h + \sum_i s_i ⋅ \mathrm g_i \\
\mathrm v &amp;amp;= s_v ⋅ \mathrm h + (\vec s ⋅ \vec b) ⋅ \mathrm g \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends random  &lt;span class=&quot;math math-inline&quot;&gt;r ∈ 𝔽^×&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
z_u &amp;amp;= s_u + r ⋅ s_a \\
z_v &amp;amp;= s_v + r ⋅ s_c \\
\vec z &amp;amp;= \vec s  + r ⋅ \vec a \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; checks
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm u + r ⋅ \mathrm c_a &amp;amp;= z_u ⋅ \mathrm h + \sum_i z_i ⋅ \mathrm g_i \\
\mathrm v + r ⋅ \mathrm c_c &amp;amp;= z_v ⋅ \mathrm h + (\vec z ⋅ \vec b) ⋅ \mathrm g \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first equation is straightforward, the second one expands to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm v + r ⋅ \mathrm c_c
&amp;amp;= s_v ⋅ \mathrm h + (\vec s ⋅ \vec b) ⋅ \mathrm g + r⋅(s_c⋅\mathrm h + c ⋅ \mathrm g) \\
&amp;amp;= (s_v  + r ⋅ s_c)⋅ \mathrm h + (\vec s ⋅ \vec b + r ⋅ c) ⋅ \mathrm g \\
z_v ⋅ \mathrm h + (\vec z ⋅ \vec b) ⋅ \mathrm g 
&amp;amp;= (s_v + r ⋅ s_c) ⋅ \mathrm h + ((\vec s  + r ⋅ \vec a) ⋅ \vec b) ⋅ \mathrm g \\
&amp;amp;= (s_v + r ⋅ s_c) ⋅ \mathrm h + (\vec s ⋅ \vec b  + r ⋅ \vec a ⋅ \vec b) ⋅ \mathrm g \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bulletproofs&quot;&gt;Bulletproofs&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; The above proof-of-dot-product has proof size linear in the vector length. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1132.pdf&quot;&gt;WTS⁺17&lt;&#x2F;a&gt; a Bulletproof based argument is presented that is logarithmic in vector length.&lt;&#x2F;p&gt;
&lt;p&gt;However, remember that in Hyrax the commited vector length is not &lt;span class=&quot;math math-inline&quot;&gt;|\setn B|&lt;&#x2F;span&gt; but tuneable and proof sizes &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{O}(\sqrt{|\setn B|})&lt;&#x2F;span&gt; can be achieved without Bulletproofs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1132.pdf&quot;&gt;WTS⁺17&lt;&#x2F;a&gt; Riad S. Wahby, Ioanna Tzialla, Abhi Shelat, Justin. Thaler, and Michael Walfish (2017). Doubly-efficient zkSNARKs without trusted setup. In S&amp;amp;P, 2018.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>GKR</title>
        <published>2024-07-06T00:00:00+00:00</published>
        <updated>2024-07-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/gkr/"/>
        <id>https://2π.com/24/gkr/</id>
        
        <content type="html" xml:base="https://2π.com/24/gkr/">&lt;h1 id=&quot;gkr&quot;&gt;GKR&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\ps#1{\delim\{{#1}\}}
\gdef\F{\mathbb F}
\gdef\set#1{\mathcal #1}
\gdef\vec#1{\bm #1}
\gdef\eq{\mathrm{eq}}
\gdef\mul{\mathsf{mul}}
\gdef\add{\mathsf{add}}
\gdef\addc{\mathsf{add^C}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Last year saw the publication of many interesting new proof systems that deviate from the pattern of doing plonkish-starkish arithmetization on top of a (univariate) polynomial commitment protocol. These new systems are broadly based on two mechanism: folding schemes and sumcheck+GKR. In this note I&#x27;ll explore sumcheck and GKR.&lt;&#x2F;p&gt;
&lt;p&gt;GKR, introduced in 2008 respectively, is an relatively old protocol. I am not sure why it has thusfar received little attention from implementers, but I suspect it is because the proof sizes are not particularly small and the protocols are arguably more complicated. Proof size was the main metric to benchmark protocols on and here &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;24&#x2F;gkr&#x2F;22&#x2F;groth16&quot;&gt;Groth16&lt;&#x2F;a&gt; is still king, with plonkish-starkish over KZG close behind. Now that it has become practical to recursively verify proofs this is less of a concern, a larger proof can be recursively verified in, say, a Groth16 proof and become small.&lt;&#x2F;p&gt;
&lt;p&gt;The main reason there is renewed interest in GKR protocols is prover complexity. Both Groth16 and plonkish arithmetization require the prover to do &lt;span class=&quot;math math-inline&quot;&gt;O(n⋅\log n)&lt;&#x2F;span&gt; work in the size of the computation. Through clever use of multivariate polynomials the GKR based methods can achieve &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; prover complexity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gkr-1&quot;&gt;GKR&lt;&#x2F;h2&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;wp-content&#x2F;uploads&#x2F;2008&#x2F;01&#x2F;GoldwasserKR08a.pdf&quot;&gt;GKR08&lt;&#x2F;a&gt; we have a &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-layered circuit with the first layer being the input and each further layer computed from the previous one by adding or multiplying two values. For simplicity let&#x27;s assume each layer has the same number of values &lt;span class=&quot;math math-inline&quot;&gt;2^n&lt;&#x2F;span&gt;. We encode each layers values on a &lt;span class=&quot;math math-inline&quot;&gt;\ps{0,1}^n&lt;&#x2F;span&gt; hypercube, creating multi-linear extensions &lt;span class=&quot;math math-inline&quot;&gt;w_i(\vec x)&lt;&#x2F;span&gt; for each layer &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;. The inputs are encoded in &lt;span class=&quot;math math-inline&quot;&gt;w_0(\vec x)&lt;&#x2F;span&gt; and the output will be in &lt;span class=&quot;math math-inline&quot;&gt;w_k(\vec x)&lt;&#x2F;span&gt;. The circuit is encoded using two indicator functions, they are MLEs with the following values on the hypercube &lt;span class=&quot;math math-inline&quot;&gt;\ps{0,1}^{3⋅n}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{add}_i\p{\vec x, \vec y, \vec z} &amp;amp;= \begin{cases}
1 &amp;amp; w_{i+1}(\vec x) = w_i(\vec y) + w_i(\vec z)\\
0 &amp;amp; \text{otherwise}
\end{cases} \\
\mathrm{mul}_i\p{\vec x, \vec y, \vec z} &amp;amp;= \begin{cases}
1 &amp;amp; w_{i+1}(\vec x) = w_i(\vec y) ⋅ w_i(\vec z)\\
0 &amp;amp; \text{otherwise}
\end{cases} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that the order of &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec z&lt;&#x2F;span&gt; is important to avoid double counting, there should be only one &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; per output node, i.e. for each value of &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt;. With these circuit-encoding functions the values on the layers are related by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w_{i+1}(\vec x) = \sum_{\vec y, \vec z ∈ \{0,1\}^n} \p{\hspace{.1em}
\begin{aligned}
    &amp;amp;\phantom{+}\mathrm{add}_i\p{\vec x, \vec y, \vec z} ⋅ \p{w_i(\vec y) + w_i(\vec z)}\\
    &amp;amp;+\mathrm{mul}_i\p{\vec x, \vec y, \vec z} ⋅ \p{w_i(\vec y) ⋅ w_i(\vec z)}
\end{aligned}
\hspace{.5em}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;By constuction this holds for &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \ps{0,1}^n&lt;&#x2F;span&gt;. To see that it holds for all &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \F^n&lt;&#x2F;span&gt; observe that &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{add}_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{mul}_i&lt;&#x2F;span&gt; are MLEs in &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; and a linear combination of MLEs is also an MLE. Since MLEs are uniquely identified by their values on &lt;span class=&quot;math math-inline&quot;&gt;\ps{0,1}^n&lt;&#x2F;span&gt; they must be identical. Note that &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{add}_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{mul}_i&lt;&#x2F;span&gt; do not need to be multilinear in &lt;span class=&quot;math math-inline&quot;&gt;\vec y, \vec z&lt;&#x2F;span&gt;. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;wp-content&#x2F;uploads&#x2F;2008&#x2F;01&#x2F;GoldwasserKR08a.pdf&quot;&gt;GKR08&lt;&#x2F;a&gt; a slightly more complex expression is used that does not require multilinearity in &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; either. The above expression is due to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;GKRNote.pdf&quot;&gt;T15&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends the output values &lt;span class=&quot;math math-inline&quot;&gt;w_k(\vec x)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends random &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\vec x} ∈ \F^n&lt;&#x2F;span&gt; and computes &lt;span class=&quot;math math-inline&quot;&gt;w_k(\vec r_{\vec x})&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; run sumcheck on the relation between &lt;span class=&quot;math math-inline&quot;&gt;w_{k}(\vec r_{\vec x})&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;w_{k-1}(\vec x)&lt;&#x2F;span&gt; as above (using &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; for the summand)
&lt;span class=&quot;math math-display&quot;&gt;
     w_k(\vec r_{\vec x}) = \sum_{\vec y, \vec z ∈ \ps{0,1}^n} f(\vec r_{\vec x}, \vec y, \vec z)
&lt;&#x2F;span&gt;
this results in &lt;span class=&quot;math math-inline&quot;&gt;\vec c ∈ \F&lt;&#x2F;span&gt;, random &lt;span class=&quot;math math-inline&quot;&gt;\vec r_{\vec y}, \vec r_{\vec z} ∈ \F^n&lt;&#x2F;span&gt; and a claim &lt;span class=&quot;math math-inline&quot;&gt;c = f\p{\vec r_{\vec x}, \vec r_{\vec y}, \vec r_{\vec z}}&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;w_{k-1}(\vec r_{\vec y})&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;w_{k-1}(\vec r_{\vec z})&lt;&#x2F;span&gt;, to be proven in a moment.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; computes &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{add}_{k-1}\p{\vec r_{\vec x}, \vec r_{\vec y}, \vec r_{\vec z}}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{mul}_{k-1}\p{\vec r_{\vec x}, \vec r_{\vec y}, \vec r_{\vec z}}&lt;&#x2F;span&gt; locally and checks &lt;span class=&quot;math math-inline&quot;&gt;c = f\p{\vec r_{\vec x}, \vec r_{\vec y}, \vec r_{\vec z}}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; reduce the two queries &lt;span class=&quot;math math-inline&quot;&gt;w_{k-1}(\vec r_{\vec y})&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;w_{k-1}(\vec r_{\vec z})&lt;&#x2F;span&gt; to one query &lt;span class=&quot;math math-inline&quot;&gt;w_{k-1}(\vec r_{\vec x}&amp;#39;)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; run repeat steps 3-6 for &lt;span class=&quot;math math-inline&quot;&gt;k-1&lt;&#x2F;span&gt; more times.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; use further methods to checks &lt;span class=&quot;math math-inline&quot;&gt;w_0(\vec r_{\vec x})&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This reduces a claim on the output values &lt;span class=&quot;math math-inline&quot;&gt;w_k(\vec x)&lt;&#x2F;span&gt; to a claim on the input values &lt;span class=&quot;math math-inline&quot;&gt;w_0(\vec r_{\vec x})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that it is assumed the verifier knows &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{add}_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{mul}_i&lt;&#x2F;span&gt; and it is economical for the verifier to evaluate it. Alternatively the prover can use a polynomial commitment scheme or other means to convey those values to the verifier.&lt;&#x2F;p&gt;
&lt;p&gt;This protocol can be straightforward generalized to support unequal sized layers &lt;span class=&quot;math math-inline&quot;&gt;n_i&lt;&#x2F;span&gt;, leading to potential further reductions in proof size and compute cost.&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Analysis, especially complexity and proof size. Especially efficient evaluation of &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{add}_i&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{mul}_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Q: The choice of addition and multiplication gates is natural, but also arbitrary. What other gates can be supported? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1611.pdf&quot;&gt;S23&lt;&#x2F;a&gt; presents a clever scheme using an exponentiation operator.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;quickly-evaluating-and-in-random&quot;&gt;Quickly evaluating &lt;span class=&quot;math math-inline&quot;&gt;\add_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mul_i&lt;&#x2F;span&gt; in random &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Observe that in a fully defined circuit each output node has either &lt;span class=&quot;math math-inline&quot;&gt;\add&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;\mul&lt;&#x2F;span&gt; return &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; for it. So together they have one-hot on each corner of the &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; hypercube. We can construct this basis in&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{2^{n+1} - 4}⋅\mul + n⋅\addc
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;operations.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mul_i(\vec r_x, \vec r_y, \vec r_z) = \sum_{\vec x ∈ \set M}
\eq(\vec x, \vec r_x)⋅
\eq(\vec y(\vec x),\vec r_y)⋅
\eq(\vec z(\vec x),\vec r_z)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;What remains is computing the various &lt;span class=&quot;math math-inline&quot;&gt;\eq(\vec c_x, □)&lt;&#x2F;span&gt; values. Here &lt;span class=&quot;math math-inline&quot;&gt;\vec c_x&lt;&#x2F;span&gt; encodes the connectivity and is sparse: only &lt;span class=&quot;math math-inline&quot;&gt;2^n&lt;&#x2F;span&gt; out of &lt;span class=&quot;math math-inline&quot;&gt;2^{2⋅n}&lt;&#x2F;span&gt; values are used. We can however again assume that each node is an input at least once. So all values appear. We get
&lt;span class=&quot;math math-display&quot;&gt;
3⋅\p{2^{n+1} - 4}⋅\mul + 3⋅n⋅\addc
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To compute the three lookup tables for the &lt;span class=&quot;math math-inline&quot;&gt;\eq&lt;&#x2F;span&gt;&#x27;s. Then to combine them into &lt;span class=&quot;math math-inline&quot;&gt;\add&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mul&lt;&#x2F;span&gt; we need a further
&lt;span class=&quot;math math-display&quot;&gt;
2^{n + 1}⋅\mul
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute the hypercube basis for &lt;span class=&quot;math math-inline&quot;&gt;\eq(\vec c, \vec r_x)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\eq(\vec c, \vec r_y)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\eq(\vec c, \vec r_z)&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;3⋅2^n&lt;&#x2F;span&gt; space.&lt;&#x2F;li&gt;
&lt;li&gt;Use two acumulators &lt;span class=&quot;math math-inline&quot;&gt;\add&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mul&lt;&#x2F;span&gt;. For each entry in&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;317.pdf&quot;&gt;XZZ+19&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;wp-content&#x2F;uploads&#x2F;2008&#x2F;01&#x2F;GoldwasserKR08a.pdf&quot;&gt;GKR08&lt;&#x2F;a&gt; Shafi Goldwasser, Yael Tauman Kalai, Guy N. Rothblum (2008). Delegating Computation: Interactive Proofs for Muggles.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1109.6882.pdf&quot;&gt;CTY11&lt;&#x2F;a&gt; Graham Cormode, Justin Thaler, Ke Yi (2011). Verifying Computations with Streaming Interactive Proofs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1105.2003.pdf&quot;&gt;CMT12&lt;&#x2F;a&gt; Graham Cormode, Michael Mitzenmacher, Justin Thaler (2012). Practical Verified Computation with Streaming Interactive Proofs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;351.pdf&quot;&gt;T13&lt;&#x2F;a&gt; Justin Thaler (2013). &quot;Time-Optimal Interactive Proofs for Circuit Evaluation&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;GKRNote.pdf&quot;&gt;T15&lt;&#x2F;a&gt; Justin Thaler (2015). &quot;A Note on the GKR Protocol&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1704.02086.pdf&quot;&gt;CFS17&lt;&#x2F;a&gt; Alessandro Chiesa, Michael A. Forbes, Nicholas Spooner (2017). A Zero Knowledge Sumcheck and its Applications.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;317.pdf&quot;&gt;XZZ+19&lt;&#x2F;a&gt;: Tiancheng Xie et al. (2019). &quot;Libra: Succinct Zero-Knowledge Proofs with Optimal Prover
Computation&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;blogpost.pdf&quot;&gt;T20a&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zkproof.org&#x2F;2020&#x2F;03&#x2F;16&#x2F;sum-checkprotocol&quot;&gt;T20b&lt;&#x2F;a&gt;: Justin Thaler (2020). &quot;The Unreasonable Power of the Sum-Check
Protocol&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;users.cs.duke.edu&#x2F;~elk27&#x2F;bibliography&#x2F;22&#x2F;Ka22gkr.pdf&quot;&gt;K22&lt;&#x2F;a&gt; Erich Kaltofen (2022). &quot;The GKR Protocol Revisited&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1284.pdf&quot;&gt;PH23&lt;&#x2F;a&gt; Shahar Papini, Ulrich Haböck (2023). &quot;Improving logarithmic derivative lookups using
GKR&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1611.pdf&quot;&gt;S23&lt;&#x2F;a&gt; Lev Soukhanov (2023). &quot;Power circuits: a new arithmetization for
GKR-styled sumcheck&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;ProofsArgsAndZK.pdf&quot;&gt;T23a&lt;&#x2F;a&gt; Justin Thaler (2023). &quot;Proofs, Arguments, and Zero-Knowledge&quot;. See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;COSC544.html&quot;&gt;lecture notes&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;gkrnotes.pdf&quot;&gt;older lecture notes&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;small-sumcheck.pdf&quot;&gt;T23b&lt;&#x2F;a&gt; Justin Thaler (2023). The sumcheck protocol over fields of small characteristic.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arielgabizon&#x2F;Lectures&#x2F;blob&#x2F;master&#x2F;zkWarsawJan24.pdf&quot;&gt;G24&lt;&#x2F;a&gt; Ariel Gabizon (2024). zkWarsaw talk &quot;The GKR method&quot;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;ingonyama-zk&#x2F;papers&#x2F;blob&#x2F;main&#x2F;sumcheck_201_chapter_1.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;1046&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;1046&quot;&gt;BDT24&lt;&#x2F;a&gt; Suyash Bagad, Yuval Domb, Justin Thaler (2024). The Sum-Check Protocol over Fields of Small Characteristic.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Jolt</title>
        <published>2024-07-02T00:00:00+00:00</published>
        <updated>2024-07-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/jolt/"/>
        <id>https://2π.com/24/jolt/</id>
        
        <content type="html" xml:base="https://2π.com/24/jolt/">&lt;h1 id=&quot;jolt&quot;&gt;Jolt&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\mat#1{\mathrm{#1}}
\gdef\p#1{\left({#1}\right)}
\gdef\ceil#1{\left\lceil{#1}\right\rceil}
\gdef\forall{\mathop{\huge ∀}\limits}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notes studying Jolt. Per Michael Zhu&#x27;s suggestion I will follow the lineage from Spice &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;907&quot;&gt;SAGL18&lt;&#x2F;a&gt;, Spartan &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;550&quot;&gt;S19&lt;&#x2F;a&gt;, Lasso &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1216&quot;&gt;STW23&lt;&#x2F;a&gt;, Jolt &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1217&quot;&gt;AST23&lt;&#x2F;a&gt;, Binius &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1784&quot;&gt;DP23&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;spice&quot;&gt;Spice&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;spartan&quot;&gt;Spartan&lt;&#x2F;h2&gt;
&lt;p&gt;Spartan (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;550&quot;&gt;S19&lt;&#x2F;a&gt;) is a transparant zkSNARK for R1CS. Recal an R1CS instance over a field &lt;span class=&quot;math math-inline&quot;&gt;𝔽&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-sparse &lt;span class=&quot;math math-inline&quot;&gt;m×m&lt;&#x2F;span&gt; matrices &lt;span class=&quot;math math-inline&quot;&gt;\mat A, \mat B, \mat C&lt;&#x2F;span&gt; such that a &lt;span class=&quot;math math-inline&quot;&gt;z=(1,\mathsf{pub},\mathsf{priv})&lt;&#x2F;span&gt; satisfies iff
&lt;span class=&quot;math math-inline&quot;&gt;(\mat A⋅ z) ∘(\mat B ⋅ z) = \mat C ⋅ z&lt;&#x2F;span&gt;.
We convert this to a &lt;a href=&quot;&#x2F;24&#x2F;sumcheck-gkr#zero-testing&quot;&gt;sumcheck zero testing&lt;&#x2F;a&gt; statement
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\forall_{x∈\{0,1\}^s}0={}&amp;amp;
\p{\sum_{y∈\{0,1\}^s}\widetilde A(x,y)⋅\widetilde z(y)}⋅
\p{\sum_{y∈\{0,1\}^s}\widetilde B(x,y)⋅\widetilde z(y)}\\
&amp;amp;-
\sum_{y∈\{0,1\}^s}\widetilde C(x,y)⋅\widetilde z(y)
\end{aligned}
&lt;&#x2F;span&gt;
where &lt;span class=&quot;math math-inline&quot;&gt;\widetilde\square&lt;&#x2F;span&gt; denotes a multilinear extension and &lt;span class=&quot;math math-inline&quot;&gt;s=\ceil{\log_2 m}&lt;&#x2F;span&gt;.Batching the inner sumchecks, it takes two sumchecks to reduce this to
&lt;span class=&quot;math math-display&quot;&gt;
(r_A⋅\widetilde A(r_x, r_y) +
r_B⋅\widetilde B(r_x, r_y) +
r_C⋅\widetilde C(r_x, r_y)) ⋅
\widetilde z(r_y)
&lt;&#x2F;span&gt;
For &lt;span class=&quot;math math-inline&quot;&gt;\widetilde z&lt;&#x2F;span&gt; the prover provides a hiding polynomial commitment to &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{priv}&lt;&#x2F;span&gt; up front and reveals it at &lt;span class=&quot;math math-inline&quot;&gt;r_y&lt;&#x2F;span&gt; so that the verifier can compute &lt;span class=&quot;math math-inline&quot;&gt;\widetilde z(r_y)&lt;&#x2F;span&gt;. The verifier knows &lt;span class=&quot;math math-inline&quot;&gt;\widetilde A, \widetilde B, \widetilde C&lt;&#x2F;span&gt; and can evaluate it directly.&lt;&#x2F;p&gt;
&lt;p&gt;Evaluating the &lt;span class=&quot;math math-inline&quot;&gt;\widetilde A, \widetilde B, \widetilde C&lt;&#x2F;span&gt; takes &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; work. To solve this the verifier pre-computes commitments to them and the prover computes openings. To be efficient, this requires a polynomial commitements scheme that is efficient for sparse polynomials. Consider &lt;span class=&quot;math math-inline&quot;&gt;\widetilde A&lt;&#x2F;span&gt; (the other cases are identical) we have the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; term sum
&lt;span class=&quot;math math-display&quot;&gt;
\widetilde A(r_x, r_y) = \sum_{\begin{subarray}{c} i,j ∈ \{0,1\}^s \\[.3em] \mat A_{ij} ≠ 0 \end{subarray}} \mat A_{ij} ⋅ \widetilde{\operatorname{eq}}(i, r_x)⋅\widetilde{\operatorname{eq}}(j, r_y)
&lt;&#x2F;span&gt;
where &lt;span class=&quot;math math-inline&quot;&gt;\widetilde{\operatorname{eq}}&lt;&#x2F;span&gt; is the &lt;a href=&quot;&#x2F;24&#x2F;sumcheck-gkr#the-equality-function&quot;&gt;multilinear equality function&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To evaluate this we create lookup tables for &lt;span class=&quot;math math-inline&quot;&gt;\widetilde{\operatorname{eq}}(i, r_x)&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\widetilde{\operatorname{eq}}(j, r_y)&lt;&#x2F;span&gt; and the sequence of &lt;span class=&quot;math math-inline&quot;&gt;(i,j, \mat M_{ij})&lt;&#x2F;span&gt; tuples to sum over.&lt;&#x2F;p&gt;
&lt;p&gt;Create three vectors, &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;M_{ij}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;907&quot;&gt;SAGL18&lt;&#x2F;a&gt; Srinath Setty, Sebastian Angel, Trinabh Gupta, and Jonathan Lee (2018). Proving the correct execution of concurrent services in zero-knowledge.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;550&quot;&gt;S19&lt;&#x2F;a&gt; Srinath Setty (2019). Spartan: Efficient and general-purpose zkSNARKs without trusted setup.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1216&quot;&gt;STW23&lt;&#x2F;a&gt; Srinath Setty, Justin Thaler, Riad Wahby (2023). Unlocking the lookup singularity with Lasso.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1217&quot;&gt;AST23&lt;&#x2F;a&gt; Arasu Arun, Srinath Setty, Justin Thaler (2023). Jolt: SNARKs for Virtual Machines via Lookups.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1799&quot;&gt;ST23&lt;&#x2F;a&gt; Srinath Setty, Justin Thaler (2023). BabySpartan: Lasso-based SNARK for non-uniform computation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1784&quot;&gt;DP23&lt;&#x2F;a&gt; Benjamin E. Diamond, Jim Posen (2023). Succinct Arguments over Towers of Binary Fields.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introduction to ZK-STARKs</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/stark-intro/"/>
        <id>https://2π.com/20/stark-intro/</id>
        
        <content type="html" xml:base="https://2π.com/20/stark-intro/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\Z{\mathbb{Z}}
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;introduction-to-zk-starks&quot;&gt;Introduction to ZK-STARKs&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathtt{F}}
\gdef\X{\mathtt{X}}
\gdef\Y{\mathtt{Y}}
\gdef\Z{\mathtt{Z}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;disclaimer-contains-math&quot;&gt;Disclaimer: contains math&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;If you don&#x27;t understand something
&lt;ul&gt;
&lt;li&gt;Not your fault, this stuff is hard&lt;&#x2F;li&gt;
&lt;li&gt;Nobody understands it fully&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If you don&#x27;t understand anything
&lt;ul&gt;
&lt;li&gt;My fault, anything can be explained at some level&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;If you &lt;em&gt;do&lt;&#x2F;em&gt; understand everything
&lt;ul&gt;
&lt;li&gt;Collect your Turing Award &amp;amp; Fields Medal&lt;&#x2F;li&gt;
&lt;li&gt;Many open questions&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;zero-knowledge-proofs&quot;&gt;Zero knowledge proofs&lt;&#x2F;h2&gt;
&lt;p&gt;We know some algorithm &lt;span class=&quot;math math-inline&quot;&gt;\F(\X, \Y)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I give you &lt;span class=&quot;math math-inline&quot;&gt;\X&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\Z&lt;&#x2F;span&gt; and proof that “I know an &lt;span class=&quot;math math-inline&quot;&gt;\Y&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\F(\X, \Y) = \Z&lt;&#x2F;span&gt;” without revealing &lt;span class=&quot;math math-inline&quot;&gt;\Y&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\X&lt;&#x2F;span&gt; public input, old balances.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\Y&lt;&#x2F;span&gt; secret input, trades.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\Z&lt;&#x2F;span&gt; public output, new balances.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;scalable-dex&quot;&gt;Scalable DEX&lt;&#x2F;h3&gt;
&lt;p&gt;“I know an &lt;span class=&quot;math math-inline&quot;&gt;\Y&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\F(\X, \Y) = \Z&lt;&#x2F;span&gt;”&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;public input &lt;span class=&quot;math math-inline&quot;&gt;\X&lt;&#x2F;span&gt;: (merkle root of) old balances.&lt;&#x2F;li&gt;
&lt;li&gt;secret input &lt;span class=&quot;math math-inline&quot;&gt;\Y&lt;&#x2F;span&gt;: trades.&lt;&#x2F;li&gt;
&lt;li&gt;public output &lt;span class=&quot;math math-inline&quot;&gt;\Z&lt;&#x2F;span&gt;: (merkle root of) new balances.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; verifies maker and taker signatures on the trades and updates the balances.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;naive-solution&quot;&gt;Naive solution&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;I give you &lt;span class=&quot;math math-inline&quot;&gt;\X&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\Y&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\Z&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;You compute &lt;span class=&quot;math math-inline&quot;&gt;\F(\X, \Y)&lt;&#x2F;span&gt; and verify that it is &lt;span class=&quot;math math-inline&quot;&gt;\Z&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Problems&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;📀 I need to send data size &lt;span class=&quot;math math-inline&quot;&gt;O(\X + \Y + \Z)&lt;&#x2F;span&gt;, i.e. all the trades.&lt;br &#x2F;&gt;
💾 We want &lt;span class=&quot;math math-inline&quot;&gt;O(\X + \Z + \F)&lt;&#x2F;span&gt;, only merkle roots.&lt;&#x2F;li&gt;
&lt;li&gt;⏳ You need to do computations &lt;span class=&quot;math math-inline&quot;&gt;O(\F)&lt;&#x2F;span&gt;.&lt;br &#x2F;&gt;
⌛ We want constant gas.&lt;&#x2F;li&gt;
&lt;li&gt;🤫 You now know &lt;span class=&quot;math math-inline&quot;&gt;\Y&lt;&#x2F;span&gt;, the secret input.&lt;br &#x2F;&gt;
🤷 We don&#x27;t care.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;math-refresher-polynomials&quot;&gt;Math refresher: Polynomials&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Constant&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_0&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Linear&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_0 + a_1 x&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Parabola&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_0 + a_1 x + a_2 x^2&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Cubic&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_0 + a_1 x + a_2 x^2 + a_3 x^3&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Quartic&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_0 + a_1 x + a_2 x^2 + a_3 x^3 + a_4 x^4&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_0 + a_1 x + a_2 x^2 + \cdots + a_n x^n&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Can be uniquely described in three ways:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;n + 1&lt;&#x2F;span&gt; Coefficients&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;n + 1&lt;&#x2F;span&gt; Points&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; Zeros* and a scaling factor&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;(* Zeros might be imaginary.)&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Can do math with them:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Add &lt;span class=&quot;math math-inline&quot;&gt;\deg (P + Q) = \max (\deg P, \deg Q)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Multiply &lt;span class=&quot;math math-inline&quot;&gt;\deg (P \times Q) = \deg P + \deg Q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Divide &lt;span class=&quot;math math-inline&quot;&gt;\deg \frac{P}{Q} = \deg P - \deg Q&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Division works when zeros match.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;toy-example-fibonnacci&quot;&gt;Toy example: Fibonnacci&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;We want to prove the 1000-th Fibonacci number starting from a public and a secret value. Take &lt;span class=&quot;math math-inline&quot;&gt;\F(\X, \Y) = \Z&lt;&#x2F;span&gt; to mean the following:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
F_0 &amp;amp;:= \X &amp;amp;
F_i &amp;amp;:= F_{i - 2} + F_{i - 1} \\
F_1 &amp;amp;:= \Y &amp;amp;
\Z  &amp;amp;:= F_{1000} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;computational-trace&quot;&gt;Computational trace&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Computation with &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; steps and &lt;span class=&quot;math math-inline&quot;&gt;w&lt;&#x2F;span&gt; &lt;em&gt;registers&lt;&#x2F;em&gt;. The trace &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; is a &lt;span class=&quot;math math-inline&quot;&gt;n × w&lt;&#x2F;span&gt; table.
Here &lt;span class=&quot;math math-inline&quot;&gt;n = 1000&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;w = 2&lt;&#x2F;span&gt;. Restate algorithm as constraints on &lt;span class=&quot;math math-inline&quot;&gt;T_{i}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Example: &lt;span class=&quot;math math-inline&quot;&gt;\X = 3&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\Y = 4&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;n&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;T_{n, 0}&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;T_{n, 1}&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;td&gt;...&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;999&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;F_{999}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;F_{1000}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Encode the algorithm as a set of &lt;em&gt;transition constraints&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
T_{i + 1, 0} &amp;amp;= T_{i, 1} &amp;amp;
T_{i + 1, 1} &amp;amp;= T_{i, 0} + T_{i, 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and &lt;em&gt;boundary constraints&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
T_{0, 0} &amp;amp;= \X &amp;amp;
T_{999, 1} &amp;amp;= \Z &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;‟I know &lt;span class=&quot;math math-inline&quot;&gt;y&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;f(x,y)=z&lt;&#x2F;span&gt;.”&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;⇔&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;‟I know a trace &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; such that the constraints hold.”&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;trace-polynomials&quot;&gt;Trace polynomials&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;For each register &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt;, create a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P_j(x)&lt;&#x2F;span&gt; of degree &lt;span class=&quot;math math-inline&quot;&gt;999&lt;&#x2F;span&gt; such that
&lt;span class=&quot;math math-inline&quot;&gt;P_j(i) = T_{i, j}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;i = 0 … 999&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;(Actual implementation uses &lt;span class=&quot;math math-inline&quot;&gt;P_j(ω^i) = T_{i, j}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;ω&lt;&#x2F;span&gt; a &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-root of unity to allow &lt;span class=&quot;math math-inline&quot;&gt;O(n \log n)&lt;&#x2F;span&gt; FFT and FRI. Also rounds &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; up to the next power of two. Ignore for now.)&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Consider the constraint &lt;span class=&quot;math math-inline&quot;&gt;T_{i + 1, 1} = T_{i, 0} + T_{i, 1}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;i = 0 … 999&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;⇔ P_1(i + 1) = P_0(i) + P_1(i)&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;i = 0 … 999&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;⇔ P_1(i + 1) - (P_0(i) + P_1(i)) = 0&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;i = 0 … 999&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;⇔ Q(x) = P_1(x + 1) - (P_0(x) + P_1(x))&lt;&#x2F;span&gt; is zero when &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; is an integer &lt;span class=&quot;math math-inline&quot;&gt;0 … 999&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;R(x) = (x - 0) ⋅ (x - 1)⋅ (x - 2) ⋯ (x - 999)&lt;&#x2F;span&gt; is a polynomial and is zero &lt;em&gt;only&lt;&#x2F;em&gt; when &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; is an integer &lt;span class=&quot;math math-inline&quot;&gt;0 … 999&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This means&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C(x) = \frac{Q(x)}{R(x)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;is also a polynomial.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Create functions that are polynomial &lt;em&gt;only&lt;&#x2F;em&gt; when the constraints are satisfied:&lt;&#x2F;p&gt;
&lt;p&gt;Transition constraints:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
T_{i + 1, 0} &amp;amp;= T_{i, 1}
&amp;amp;⇒&amp;amp;&amp;amp;
C_0(x) &amp;amp;= \frac
    {P_0(x + 1) - P_1(x)}
    {\prod^i_{[0 … 998]}\left( x - i\right)}
\\
T_{i + 1, 1} &amp;amp;= T_{i, 0} + T_{i, 1}
&amp;amp;⇒&amp;amp;&amp;amp;
C_1(x) &amp;amp;= \frac
    {P_1(x + 1) - (P_0(x) + P_1(x))}
    {\prod^i_{[0\dots998]}\, (x - i)}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Boundary constraints:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
T_{0, 0} &amp;amp;= X
&amp;amp;⇒&amp;amp;&amp;amp;
C_2(x) &amp;amp;= \frac
    {P_0(x) - X}
    {x - 0}
\\
T_{999, 1} &amp;amp;= Z
&amp;amp;⇒&amp;amp;&amp;amp;
C_3(x) &amp;amp;= \frac
    {P_1(x) - Z}
    {x - 999} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;‟I know &lt;span class=&quot;math math-inline&quot;&gt;y&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;f(x,y)=z&lt;&#x2F;span&gt;.”&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;⇔&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;‟I know a trace &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; such that the constraints hold.”&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;⇔&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;‟I know polynomials &lt;span class=&quot;math math-inline&quot;&gt;P_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;P_1&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;C_0&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;C_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;C_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;C_3&lt;&#x2F;span&gt; are polynomial.”&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;interactive-proof&quot;&gt;Interactive proof&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I give you &lt;span class=&quot;math math-inline&quot;&gt;\X&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\Z&lt;&#x2F;span&gt; and a merkle roots of &lt;span class=&quot;math math-inline&quot;&gt;P_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;P_1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You give me random values &lt;span class=&quot;math math-inline&quot;&gt;α_0&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;α_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;α_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;α_3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;fast-reed-solomon-interactive-oracle-proof-ii&quot;&gt;Fast Reed-Solomon Interactive Oracle Proof II&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x) = a_0 + a_1 x + a_2 x^2 + a_3 x ^3 \cdots + a_n x^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a random number &lt;span class=&quot;math math-inline&quot;&gt;β&lt;&#x2F;span&gt;, we can fold the coefficients and get a polynomial of degree &lt;span class=&quot;math math-inline&quot;&gt;\frac{n}{2}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P&amp;#39;(x) = (a_0 + a_1 β) + (a_2 + a_3 β) x + \cdots + ( a_{n-1} + a_n β) x^{\frac n2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This can be computed using:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P&amp;#39;(x) = P(x) + \left( \frac{β}{2x} - \frac{1}{2}\right) \left(P(x) - P(-x) \right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x) = a_0 + a_1 x + a_2 x^2 + a_3 x ^3 \cdots + a_n x^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a random number &lt;span class=&quot;math math-inline&quot;&gt;β&lt;&#x2F;span&gt;, we can fold the coefficients and get a polynomial of degree &lt;span class=&quot;math math-inline&quot;&gt;\frac{n}{2}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P&amp;#39;(x) = (a_0 + a_1 β) + (a_2 + a_3 β) x + \cdots + ( a_{n-1} a_n β) x^{\frac n2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P&amp;#39;(x) = P(x) + \left( \frac{β}{2x} - \frac{1}{2}\right) \left(P(x) - P(-x) \right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(x)  ={}&amp;amp;
a_0 &amp;amp;{}+{}&amp;amp; a_1 x &amp;amp;{}+{}&amp;amp; a_2 x^2 &amp;amp;{}+{}&amp;amp; a_3 x ^3 &amp;amp;{}+{}&amp;amp; \cdots &amp;amp;{}+{}&amp;amp; a_{n-1} x^{n-1} &amp;amp;{}+{}&amp;amp; a_n x^n
\\
P(-x)  ={}&amp;amp;
a_0 &amp;amp;{}-{}&amp;amp; a_1 x &amp;amp;{}+{}&amp;amp; a_2 x^2 &amp;amp;{}-{}&amp;amp; a_3 x ^3 &amp;amp;{}+{}&amp;amp; \cdots &amp;amp;{}-{}&amp;amp; a_{n-1} x^{n-1} &amp;amp;{}+{}&amp;amp; a_n x^n
\\
P(x) - P(-x) ={}&amp;amp;
&amp;amp;&amp;amp; 2a_1 x &amp;amp;&amp;amp; &amp;amp;{}+{}&amp;amp; 2a_3 x ^3 &amp;amp;{}+{}&amp;amp; \cdots &amp;amp;{}+{}&amp;amp; 2 a_{n-1} x^{n-1} \\
\\
\frac{β}{2x} \left(P(x) - P(-x)\right) ={}&amp;amp;
 a_1 β &amp;amp;&amp;amp; &amp;amp;{}+{}&amp;amp; a_3 β x^2 &amp;amp;&amp;amp; &amp;amp;{}+{}&amp;amp; \cdots &amp;amp;{}+{}&amp;amp; a_{n-1} β x^{n-2} \\
 \\
\frac{1}{2} \left(P(x) - P(-x)\right) ={}&amp;amp;
 a_1 x &amp;amp;&amp;amp; &amp;amp;{}+{}&amp;amp; a_3 x^3 &amp;amp;&amp;amp; &amp;amp;{}+{}&amp;amp; \cdots &amp;amp;{}+{}&amp;amp; a_{n-1} β x^{n-1} \\
  \\
(\frac{β}{2x}-\frac{1}{2}) \left(P(x) - P(-x)\right) ={}&amp;amp;
 a_1 β &amp;amp;{}-{}&amp;amp; a_1 x &amp;amp;{}+{}&amp;amp; a_3 β x^2 &amp;amp;{}-{}&amp;amp; a_3 x^3 &amp;amp;{}+{}&amp;amp; \cdots &amp;amp;{}+{}&amp;amp; a_{n-1} β x^{n-1} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P&amp;#39;(x) = (a_0 + a_1 β) + (a_2 + a_3 β) x + \cdots + ( a_{n-1} + a_n β) x^{\frac n2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I compute &lt;span class=&quot;math math-inline&quot;&gt;C(x) = α_0 ⋅ C_0(x) + α_1 ⋅ C_1(x) + α_2 ⋅ C_2(x) + α_3 ⋅ C_3(x)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I give you the merkle root of &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; and claim &lt;span class=&quot;math math-inline&quot;&gt;\deg C = 1024&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You give me a random value &lt;span class=&quot;math math-inline&quot;&gt;𝛽_0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;I give you the merkle root of &lt;span class=&quot;math math-inline&quot;&gt;C&amp;#39;&lt;&#x2F;span&gt; and claim &lt;span class=&quot;math math-inline&quot;&gt;\deg C&amp;#39; = 512&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You give me a random value &lt;span class=&quot;math math-inline&quot;&gt;𝛽_1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;...&lt;&#x2F;p&gt;
&lt;p&gt;I give you the constant &lt;span class=&quot;math math-inline&quot;&gt;C&amp;#39;&amp;#39;&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;You verify &lt;span class=&quot;math math-inline&quot;&gt;C&amp;#39;&amp;#39;&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;\X&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\Y&lt;&#x2F;span&gt;, the &lt;span class=&quot;math math-inline&quot;&gt;α&lt;&#x2F;span&gt;s and the &lt;span class=&quot;math math-inline&quot;&gt;𝛽&lt;&#x2F;span&gt;s.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;fiat-shamir-transform&quot;&gt;Fiat-Shamir transform&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;All you do is give me random numbers. Why don&#x27;t I replace you by a pseudo random number generator!&lt;&#x2F;p&gt;
&lt;p&gt;Seed PRNG with all prover messages, extract random &#x27;verfier&#x27; messages.&lt;&#x2F;p&gt;
&lt;p&gt;Send all the proof at once.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Locality-Sensitive Hashing</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/21/lsh/"/>
        <id>https://2π.com/21/lsh/</id>
        
        <content type="html" xml:base="https://2π.com/21/lsh/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\R{\mathbb{R}}
\gdef\p#1{({#1})}
\gdef\norm#1{\lVert{#1}\rVert}
\gdef\setb#1#2{\{{#1} \mid {#2}\}}
\gdef\Pr#1{\operatorname{Pr}\p{#1}}
\gdef\sign{\operatorname{sign}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;locality-sensitive-hashing&quot;&gt;Locality-Sensitive Hashing&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\S{\mathrm{S}}
\gdef\darc{d_{\mathrm{arc}}}
\gdef\sign#1{\mathrm{sign}\p{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;\S_n&lt;&#x2F;span&gt; be an &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-dimensional unit &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-sphere&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\mathrm{S}_n = \setb{\vec x ∈ \R^n}{\norm{\vec x}_2 = 1}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and let &lt;span class=&quot;math math-inline&quot;&gt;\darc&lt;&#x2F;span&gt; be the arc length distance&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\darc\p{\vec a, \vec b} = \cos^{-1}\p{\vec a ⋅ \vec b}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;random-projections&quot;&gt;Random projections&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt; The uniform distribution on &lt;span class=&quot;math math-inline&quot;&gt;\S^n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathcal F&lt;&#x2F;span&gt; The distribution by constructing.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; The number of dimensions.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; The number of hyperplanes in a vector.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; The number of vectors.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Hyperplanes are defined by a normal unit vector &lt;span class=&quot;math math-inline&quot;&gt;\vec h ∈ \S^n&lt;&#x2F;span&gt;. For a given vector &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; we can determine on which side of the plane it lies by the sign of the dot product &lt;span class=&quot;math math-inline&quot;&gt;\vec x ⋅ \vec h&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\mathrm{Pr}_{\vec h ∈ \mathcal S}\left[\sign{\vec h ⋅ \vec a} = \sign{\vec h ⋅ \vec b} \right]
= 1 - \frac{\darc\p{\vec a, \vec b}}{π}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we pick &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; random hyperplanes &lt;span class=&quot;math math-inline&quot;&gt;\vec h_i ∈ \S^n&lt;&#x2F;span&gt; we can map each vector &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \S^n&lt;&#x2F;span&gt; into a &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;-bit vector &lt;span class=&quot;math math-inline&quot;&gt;b(\vec x)&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
b_i\p{\vec x} = \begin{cases}
    0 &amp;amp; \vec h_i ⋅ \vec x ≤ 0 \\
    1 &amp;amp; \vec h_i ⋅ \vec x &amp;gt; 0
\end{cases}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Assuming the hyperplanes are uniformly random, the probability of two bitvectors being equal is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\Pr{b\p{\vec a} = b\p{\vec b}}
= \p{1 - \frac{\darc\p{\vec a, \vec b}}{π} }^m
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The hyperplanes form a tesselation of &lt;span class=&quot;math math-inline&quot;&gt;\S^n&lt;&#x2F;span&gt; where each region has a unique bitvector and each boundary represents a single bit change. Interestingly this implies that a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hamiltonian_path&quot;&gt;Hamiltonian path&lt;&#x2F;a&gt; through regions (if one exists) creates a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gray_code&quot;&gt;Gray code&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We have two distributions on &lt;span class=&quot;math math-inline&quot;&gt;\S^n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{U}_{match}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{U}_{non-match}&lt;&#x2F;span&gt;. Given a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; we want to classify it&#x27;s distribution.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Assumption.&lt;&#x2F;strong&gt; Iris embeddings of different irises are uniformly distributed on &lt;span class=&quot;math math-inline&quot;&gt;\S^n&lt;&#x2F;span&gt; so the &lt;span class=&quot;math math-inline&quot;&gt;\darc&lt;&#x2F;span&gt; of non-matching irises follows the formula.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\Pr{b\p{\vec a} = b\p{\vec b}}
= \p{1 - \frac{\darc\p{\vec a, \vec b}}{π} }^m
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;amplification&quot;&gt;Amplification&lt;&#x2F;h2&gt;
&lt;p&gt;What is the probability of a match if &lt;span class=&quot;math math-inline&quot;&gt;\darc &amp;lt; T&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We are a looking for a family of hash functions &lt;span class=&quot;math math-inline&quot;&gt;\mathcal H&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;h: \S^n → H&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;∀_{\vec a, \vec b ∈ \S^n}\, \darc\p{\vec a, \vec b} &amp;lt; T → \mathrm{Pr}_{h ∈ \mathcal H}\left[h\p{\vec a} = h\p{\vec b} \right] ≥ P_1&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;∀_{\vec a \S^n}\, \mathrm{Pr}_{h ∈ \mathcal H}\left[h\p{\vec a} = h\p{\vec b} \right] ≥ P_1&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;irreversibility&quot;&gt;Irreversibility&lt;&#x2F;h2&gt;
&lt;p&gt;Assume we are given &lt;span class=&quot;math math-inline&quot;&gt;H\p{\vec a}&lt;&#x2F;span&gt;, what can we learn about &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;We can at best hope to learn all of the hyper-plane signs. This is &lt;span class=&quot;math math-inline&quot;&gt;m⋅k&lt;&#x2F;span&gt; bits of information. The subset of &lt;span class=&quot;math math-inline&quot;&gt;S^n&lt;&#x2F;span&gt; that has the same signs is a convex polygon with an (assumed) expected area of &lt;span class=&quot;math math-inline&quot;&gt;2^{-m⋅k} A_n&lt;&#x2F;span&gt;. We would not have any more information than this, so our posterior would at best be the uniform distribution over this region.&lt;&#x2F;p&gt;
&lt;p&gt;We can start by drawing many samples from &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt;. and find matching vectors &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;TODO &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.notion.so&#x2F;Draft-Outline-99ecafcd45384d58a06bc1003fe1088b&quot;&gt;https:&#x2F;&#x2F;www.notion.so&#x2F;Draft-Outline-99ecafcd45384d58a06bc1003fe1088b&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Locality-sensitive_hashing&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Locality-sensitive_hashing&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cs.princeton.edu&#x2F;courses&#x2F;archive&#x2F;spring04&#x2F;cos598B&#x2F;bib&#x2F;CharikarEstim.pdf&quot;&gt;https:&#x2F;&#x2F;www.cs.princeton.edu&#x2F;courses&#x2F;archive&#x2F;spring04&#x2F;cos598B&#x2F;bib&#x2F;CharikarEstim.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2010.09393&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2010.09393&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;randorithms.com&#x2F;2019&#x2F;09&#x2F;19&#x2F;Visual-LSH.html&quot;&gt;https:&#x2F;&#x2F;randorithms.com&#x2F;2019&#x2F;09&#x2F;19&#x2F;Visual-LSH.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2010.09393.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2010.09393.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1901.09769.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1901.09769.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Syntax</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/21/syntax/"/>
        <id>https://2π.com/21/syntax/</id>
        
        <content type="html" xml:base="https://2π.com/21/syntax/">&lt;h1 id=&quot;syntax&quot;&gt;Syntax&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;functions&quot;&gt;Functions&lt;&#x2F;h2&gt;
&lt;p&gt;History of functions.&lt;&#x2F;p&gt;
&lt;p&gt;Definition set of ordered pairs such that the first elements occurs at most once.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\set{(x,y)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Multiple return values are natural, see the division algorithm. Nearly all programming language support multiple input value, some also multiple return values. Both are not strictly more expressive. Multiple return values can be implemented using tuples. Multiple inputs using currying.&lt;&#x2F;p&gt;
&lt;p&gt;Lambda calculus&lt;&#x2F;p&gt;
&lt;h2 id=&quot;representation&quot;&gt;Representation&lt;&#x2F;h2&gt;
&lt;p&gt;Tree based syntax for proof system:&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;digama0&#x2F;mm0&#x2F;blob&#x2F;master&#x2F;mm0.md&lt;&#x2F;p&gt;
&lt;p&gt;Graphs as more fundamental&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;tiarkrompf.github.io&#x2F;notes&#x2F;?&#x2F;graph-ir&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;ProgrammingLanguages&#x2F;comments&#x2F;l0m5fn&#x2F;graph_irs_for_expressive_languages_taming&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;Coq&#x27;s extensible syntax&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;coq.inria.fr&#x2F;refman&#x2F;user-extensions&#x2F;syntax-extensions.html#&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Optimal filters</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/filters/"/>
        <id>https://2π.com/22/filters/</id>
        
        <content type="html" xml:base="https://2π.com/22/filters/">&lt;h1 id=&quot;optimal-filters&quot;&gt;Optimal filters&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dsp.stackexchange.com&#x2F;questions&#x2F;9745&#x2F;which-iir-filters-approximate-a-gaussian-filter&quot;&gt;https:&#x2F;&#x2F;dsp.stackexchange.com&#x2F;questions&#x2F;9745&#x2F;which-iir-filters-approximate-a-gaussian-filter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Gaussian blur can be approximated by a (fixed size) IIR filter:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.intel.com&#x2F;content&#x2F;dam&#x2F;develop&#x2F;external&#x2F;us&#x2F;en&#x2F;documents&#x2F;gaussian-filter-181134.pdf&quot;&gt;https:&#x2F;&#x2F;www.intel.com&#x2F;content&#x2F;dam&#x2F;develop&#x2F;external&#x2F;us&#x2F;en&#x2F;documents&#x2F;gaussian-filter-181134.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;FIR are polynomials and IIR are rational functions:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Infinite_impulse_response&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Infinite_impulse_response&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ZKP Gadgets</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/gadgets/"/>
        <id>https://2π.com/22/gadgets/</id>
        
        <content type="html" xml:base="https://2π.com/22/gadgets/">&lt;h1 id=&quot;zkp-gadgets&quot;&gt;ZKP Gadgets&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\set#1{\mathcal{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;binary-check&quot;&gt;Binary check&lt;&#x2F;h2&gt;
&lt;p&gt;Constrain &lt;span class=&quot;math math-inline&quot;&gt;a ∈ {0, 1}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Constraints:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a ⋅(1 - a) = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a special case of constraining &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; to a small set of values &lt;span class=&quot;math math-inline&quot;&gt;\{c_0, c_1, \dots \}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(a - c_0) ⋅(a - c_1) \cdots  = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zero-check&quot;&gt;Zero check&lt;&#x2F;h2&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; construct&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
b = \begin{cases}
0 &amp;amp; a \ne 0 \\
1 &amp;amp; a = 0 &amp;amp;
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Constraints:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
b &amp;amp;= 1 - a ⋅ w &amp;amp;
a ⋅ b &amp;amp;= 0
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Witness: &lt;span class=&quot;math math-inline&quot;&gt;w = a^{-1}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively can inline the definition of &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(1 - a ⋅ w) ⋅ a = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.hermez.io&#x2F;zkEVM&#x2F;architecture&#x2F;simple-state-machine&#x2F;#managing-conditional-jumps&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sign-check&quot;&gt;Sign check&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;multiset-equality&quot;&gt;Multiset equality&lt;&#x2F;h2&gt;
&lt;p&gt;Given trace columns of values &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; represented as polynomials &lt;span class=&quot;math math-inline&quot;&gt;V(ω^i) = v_i&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;W(ω^i) = w_i&lt;&#x2F;span&gt;. We can proof that the multi-set of values in &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt; equals &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\prod_{a ∈ \vec v} ( a + γ ) =
\prod_{b ∈ \vec w} ( b + γ )
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;rgLVv7nOQ0miXZ3dxxu2zQ&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;range-check&quot;&gt;Range check&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;D-vjBYtHQB2BuOB-HMUG5Q&quot;&gt;https:&#x2F;&#x2F;hackmd.io&#x2F;D-vjBYtHQB2BuOB-HMUG5Q&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;permutation-check&quot;&gt;Permutation check&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;@arielg&#x2F;ByFgSDA7D&quot;&gt;https:&#x2F;&#x2F;hackmd.io&#x2F;@arielg&#x2F;ByFgSDA7D&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953.pdf&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;plookup&quot;&gt;Plookup&lt;&#x2F;h2&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; constrain &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \set A&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;315.pdf&quot;&gt;source&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;read-only-memory&quot;&gt;Read only memory&lt;&#x2F;h2&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; constrain &lt;span class=&quot;math math-inline&quot;&gt;a = v_i&lt;&#x2F;span&gt; for constant vector &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Use Plookup with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A = \{ i ⋅ c + v_i\}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;c &amp;gt; \max \vec v&lt;&#x2F;span&gt; and constrain &lt;span class=&quot;math math-inline&quot;&gt;a + i ⋅ c ∈ A&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively take &lt;span class=&quot;math math-inline&quot;&gt;v_i ⋅c&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;c &amp;gt; |v|&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;a ⋅ c + i ∈ A&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;random-access-memory&quot;&gt;Random access memory&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;a = \mathtt{get}(i)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{set}(i, a)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The trace is augmented by a &lt;span class=&quot;math math-inline&quot;&gt;v&lt;&#x2F;span&gt; counter that increases (at least) for every RAM operation.&lt;&#x2F;p&gt;
&lt;p&gt;In addition to trace, provide permuted copy of RAM operations such that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; (location) is monotonically increasing.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;v&lt;&#x2F;span&gt; (version) is monotonically increasing while &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; is constant.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; (contents) is constant unless a &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{set}&lt;&#x2F;span&gt; changes it or &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; changes.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;@bobbinth&#x2F;HJr56BKKt&quot;&gt;https:&#x2F;&#x2F;hackmd.io&#x2F;@bobbinth&#x2F;HJr56BKKt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Implementation tricks &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zips.z.cash&#x2F;protocol&#x2F;canopy.pdf#circuitdesign&quot;&gt;https:&#x2F;&#x2F;zips.z.cash&#x2F;protocol&#x2F;canopy.pdf#circuitdesign&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zcash.github.io&#x2F;halo2&#x2F;user&#x2F;tips-and-tricks.html&quot;&gt;https:&#x2F;&#x2F;zcash.github.io&#x2F;halo2&#x2F;user&#x2F;tips-and-tricks.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Groth16 Tweaks</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/groth16-tweaks/"/>
        <id>https://2π.com/22/groth16-tweaks/</id>
        
        <content type="html" xml:base="https://2π.com/22/groth16-tweaks/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{({#1})}
\gdef\ceil#1{\lceil{#1}\rceil}
\gdef\e{\mathrm{e}}
\gdef\g{\mathrm{g}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;groth16-tweaks&quot;&gt;Groth16 Tweaks&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\G{\mathbb{G}}
\gdef\g{\mathrm{G}}
\gdef\e{\mathrm{e}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ethereum-cost-model&quot;&gt;Ethereum cost model&lt;&#x2F;h2&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;evm.codes&quot;&gt;evm.codes&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum.github.io&#x2F;yellowpaper&#x2F;paper.pdf&quot;&gt;yellow paper&lt;&#x2F;a&gt;. Calldata costs &lt;span class=&quot;math math-inline&quot;&gt;16&lt;&#x2F;span&gt; gas per zero bytes with a discounted price of &lt;span class=&quot;math math-inline&quot;&gt;4&lt;&#x2F;span&gt; for zero bytes. So the expected cost of a uniformly random byte is &lt;span class=&quot;math math-inline&quot;&gt;15.95&lt;&#x2F;span&gt; gas. On L1 calldata-gas and gas are the same, on L2s the latter is substantially cheaper.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; element is 64 bytes uncompressed and costs &lt;span class=&quot;math math-inline&quot;&gt;1024&lt;&#x2F;span&gt; calldata-gas.&lt;&#x2F;li&gt;
&lt;li&gt;Cost of &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; point decompression is TBD.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; element is 128 bytes uncompressed and costs &lt;span class=&quot;math math-inline&quot;&gt;2048&lt;&#x2F;span&gt; calldata-gas.&lt;&#x2F;li&gt;
&lt;li&gt;Cost of &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; point decompression is TBD.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; addition costs &lt;span class=&quot;math math-inline&quot;&gt;150&lt;&#x2F;span&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; scalar multiplication costs &lt;span class=&quot;math math-inline&quot;&gt;6000&lt;&#x2F;span&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-pairing check costs &lt;span class=&quot;math math-inline&quot;&gt;45\,000 + n ⋅ 34\,000&lt;&#x2F;span&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;Keccak hash of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; bytes costs &lt;span class=&quot;math math-inline&quot;&gt;30 + 6 ⋅ \ceil{\frac{n}{32}}&lt;&#x2F;span&gt; gas.&lt;&#x2F;li&gt;
&lt;li&gt;SHA256 hash of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; bytes costs &lt;span class=&quot;math math-inline&quot;&gt;60 + 12 ⋅ \ceil{\frac{n}{32}}&lt;&#x2F;span&gt; gas.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A Groth16 verification with &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; public inputs (excluding constant &lt;span class=&quot;math math-inline&quot;&gt;w_0 = 1&lt;&#x2F;span&gt;) costs&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
181\,150 + p ⋅ 6150 \text{ gas} + 4096 \text{ calldata gas}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This excludes overhead and cost of transferring&#x2F;computing the public input. This includes the &lt;span class=&quot;math math-inline&quot;&gt;4&lt;&#x2F;span&gt; pairings currently required.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-196&quot;&gt;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-196&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-197&quot;&gt;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-197&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1108&quot;&gt;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1108&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2565&quot;&gt;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2565&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;does-it-make-sense-to-use-point-compression-on-l2s&quot;&gt;Does it make sense to use point compression on L2s?&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;hash-public-inputs&quot;&gt;Hash public inputs?&lt;&#x2F;h2&gt;
&lt;p&gt;What if we use Keccak or SHA256 to hash all public inputs to a single field element, basically fixing &lt;span class=&quot;math math-inline&quot;&gt;p = 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;3-p&quot;&gt;3 P&lt;&#x2F;h2&gt;
&lt;p&gt;Groth16 is well-known to only require 3 pairings, yet Ethereum implementations require 4, this costs an extra &lt;span class=&quot;math math-inline&quot;&gt;34\,000&lt;&#x2F;span&gt; gas that seems avoidable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;iden3&#x2F;snarkjs&#x2F;blob&#x2F;29be61e70da9a1819c71777b835552dfc5603237&#x2F;templates&#x2F;verifier_groth16.sol.ejs&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;iden3&#x2F;snarkjs&#x2F;blob&#x2F;29be61e70da9a1819c71777b835552dfc5603237&#x2F;templates&#x2F;verifier_groth16.sol.ejs&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;iden3&#x2F;snarkjs&#x2F;blob&#x2F;29be61e70da9a1819c71777b835552dfc5603237&#x2F;templates&#x2F;verifier_groth16.sol.ejs#L221&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;iden3&#x2F;snarkjs&#x2F;blob&#x2F;29be61e70da9a1819c71777b835552dfc5603237&#x2F;templates&#x2F;verifier_groth16.sol.ejs#L221&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            Pairing.negate(proof.A), proof.B,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            vk.alfa1, vk.beta2,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            vk_x, vk.gamma2,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            proof.C, vk.delta2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Instead of negating variable &lt;code&gt;proof.A&lt;&#x2F;code&gt;, can negate compile time constants
&lt;code&gt;vk.beta2&lt;&#x2F;code&gt;, &lt;code&gt;vk.gamma2&lt;&#x2F;code&gt; and &lt;code&gt;vk.delta2&lt;&#x2F;code&gt;. (But negating G1 is very cheap)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Can we instead get the &lt;span class=&quot;math math-inline&quot;&gt;α⋅β⋅\g_3&lt;&#x2F;span&gt; term (and add &lt;span class=&quot;math math-inline&quot;&gt;L_0&lt;&#x2F;span&gt;) through trusted setup?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L&amp;#39; = γ^{-1} ⋅ \p{α ⋅ β + L_0(τ)} ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
{\overline L} &amp;amp;= \sum_{i ∊ [1, p)} w_i ⋅ \p{γ^{-1} ⋅ L_i(τ) ⋅ \g_1} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;then check&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(A, B) = \e(L&amp;#39; + {\overline L}, γ ⋅ \g_2) + \e(C, δ ⋅ \g_2)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shorter-proofs&quot;&gt;Shorter proofs?&lt;&#x2F;h2&gt;
&lt;p&gt;Groth16 contains an argument setting lower bounds on proof sizes and structure, but these all assume non-interactive proofs. If we allow for Fiat-Shamir constructions, can we create cheaper proofs?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hard Problems</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/hard-problems/"/>
        <id>https://2π.com/22/hard-problems/</id>
        
        <content type="html" xml:base="https://2π.com/22/hard-problems/">&lt;h1 id=&quot;hard-problems&quot;&gt;Hard Problems&lt;&#x2F;h1&gt;
&lt;p&gt;A list of CS problems for which great heuristics exists, but no optimal algorithm is known.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Matrix multiplication&lt;&#x2F;li&gt;
&lt;li&gt;Pre-processed polynomial evaluation&lt;&#x2F;li&gt;
&lt;li&gt;Sorting networks&lt;&#x2F;li&gt;
&lt;li&gt;Addition matrices&lt;&#x2F;li&gt;
&lt;li&gt;FFT kernels&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Polynomial commitment schemes</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/polynomial-commitment/"/>
        <id>https://2π.com/22/polynomial-commitment/</id>
        
        <content type="html" xml:base="https://2π.com/22/polynomial-commitment/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\p#1{\left({#1}\right)}
\gdef\set#1{\mathcal{#1}}
\gdef\Union{\bigcup}
\gdef\inprod#1#2{\langle{#1, #2}\rangle}
\gdef\e{\mathrm{e}}
\gdef\g{\mathrm{g}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;polynomial-commitment-schemes&quot;&gt;Polynomial commitment schemes&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\g{\mathrm{G}}
\gdef\h{\mathtt{H}}
\gdef\e{\mathrm{e}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I will discuss polynomial commitment schemes for &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-term polynomials, so polynomials of degree at most &lt;span class=&quot;math math-inline&quot;&gt;n-1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A polynomial commitment scheme for &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-term polynomials two scheme has two operations. Given &lt;span class=&quot;math math-inline&quot;&gt;f ∈ \F_{&amp;lt;n}[X]&lt;&#x2F;span&gt; the operation &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{commit}(f)&lt;&#x2F;span&gt; produces a commitment &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;. Given commitments &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt; and evaluation points &lt;span class=&quot;math math-inline&quot;&gt;(x_{i,j}, y_{i,j})&lt;&#x2F;span&gt; the &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{open}&lt;&#x2F;span&gt; operation proofs that &lt;span class=&quot;math math-inline&quot;&gt;f_i(x_{i,j}) = y_{i,j}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kzg&quot;&gt;KZG&lt;&#x2F;h2&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_3&lt;&#x2F;span&gt; be elliptic curve groups with the same scalar field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, generators &lt;span class=&quot;math math-inline&quot;&gt;\g_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\g_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\g_3&lt;&#x2F;span&gt; and a &lt;em&gt;pairing&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\e: \G_1 × \G_2 → \G_3&lt;&#x2F;span&gt;. For more background see &lt;a href=&quot;&#x2F;22&#x2F;bls-signatures#backround&quot;&gt;here&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Kate-Zaverucha-Goldberg&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cacr.uwaterloo.ca&#x2F;techreports&#x2F;2010&#x2F;cacr2010-10.pdf&quot;&gt;https:&#x2F;&#x2F;cacr.uwaterloo.ca&#x2F;techreports&#x2F;2010&#x2F;cacr2010-10.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;081.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;081.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1536.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1536.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;trusted-set-up&quot;&gt;Trusted set up&lt;&#x2F;h3&gt;
&lt;p&gt;During the trusted setup ceremony a secret value &lt;span class=&quot;math math-inline&quot;&gt;τ ∈ \F&lt;&#x2F;span&gt; is selected and the following &quot;powers of tau&quot; are computed for &lt;span class=&quot;math math-inline&quot;&gt;i ∈ [0,n)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec X = \begin{bmatrix}
τ^0 &amp;amp; τ^1 &amp;amp; τ^2 &amp;amp; ⋯
\end{bmatrix} ⋅ \g_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These values &lt;span class=&quot;math math-inline&quot;&gt;X_i&lt;&#x2F;span&gt; are known as the &lt;em&gt;common reference string&lt;&#x2F;em&gt; (CRS). These can get quite large, for &lt;span class=&quot;math math-inline&quot;&gt;n = 2^{20}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The CRS is update able. Given a new secret value &lt;span class=&quot;math math-inline&quot;&gt;s ∈ \F&lt;&#x2F;span&gt; the updated values are &lt;span class=&quot;math math-inline&quot;&gt;X_i&amp;#39; = s^i ⋅ X_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The &lt;span class=&quot;math math-inline&quot;&gt;X_i&lt;&#x2F;span&gt; act as a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Monomial_basis&quot;&gt;monomial basis&lt;&#x2F;a&gt; for polynomials which is convenient if the polynomial we want to commit to is in coefficient form. Often, we instead have the the polynomial in point form &lt;span class=&quot;math math-inline&quot;&gt;(x_i, y_i)&lt;&#x2F;span&gt;. We can then construct a basis of Langrange functions over the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X_i&amp;#39; = todo
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zfnd.org&#x2F;conclusion-of-the-powers-of-tau-ceremony&#x2F;&quot;&gt;https:&#x2F;&#x2F;zfnd.org&#x2F;conclusion-of-the-powers-of-tau-ceremony&#x2F;&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;aztec-protocol&#x2F;aztec-how-the-ceremony-works-9f021cf190d0&quot;&gt;https:&#x2F;&#x2F;medium.com&#x2F;aztec-protocol&#x2F;aztec-how-the-ceremony-works-9f021cf190d0&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To commit to a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P(X)&lt;&#x2F;span&gt; we compute &lt;span class=&quot;math math-inline&quot;&gt;P = P(τ) ⋅ \g_2&lt;&#x2F;span&gt; using the basis.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;one-commitment-one-value&quot;&gt;One commitment, one value&lt;&#x2F;h3&gt;
&lt;p&gt;To proof &lt;span class=&quot;math math-inline&quot;&gt;P(x) = y&lt;&#x2F;span&gt; we compute following is polynomial&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(X) = \frac{P(X) - y}{X - x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The proof is &lt;span class=&quot;math math-inline&quot;&gt;Q = Q(τ) ⋅ \g_2&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To verify, compute &lt;span class=&quot;math math-inline&quot;&gt;Z = (τ - x) ⋅ \g_2&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;R = y ⋅ \g_2&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(P - R, \g_2) = \e(Q, Z)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e(P - R, \g_2) &amp;amp;= \e(Q, Z) \\
\e(P(τ) ⋅ \g_2 - y ⋅ \g_2, \g_2) &amp;amp;= \e(Q(τ) ⋅ \g_2, (τ - x) ⋅ \g_2) \\
(P(τ) - y) ⋅ \e(\g_2, \g_2) &amp;amp;= Q(τ) ⋅ (τ - x) ⋅ \e(\g_2, \g_2) \\
P(τ) - y &amp;amp;= Q(τ) ⋅ (τ - x) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then due to the Schwarz-Sippl lemma it is cryptographically likely that &lt;span class=&quot;math math-inline&quot;&gt;P(X) - y = Q(X) ⋅ (X - x)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;many-commitments-many-values&quot;&gt;Many commitments, many values&lt;&#x2F;h3&gt;
&lt;p&gt;Given many commitments &lt;span class=&quot;math math-inline&quot;&gt;P_i&lt;&#x2F;span&gt; as above, for each we want to proof a set of values &lt;span class=&quot;math math-inline&quot;&gt;P_i(x_{ij}) = y_{ij}&lt;&#x2F;span&gt;. Define &lt;span class=&quot;math math-inline&quot;&gt;S_i = \set{x_{ij}}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;S = \Union S_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Zero polynomials&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Z_{\mathcal S}(X) = \prod_{s ∈ S} \p{X - s}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Lagrange polynomials&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_{ij}(X) = \frac{Z_{S_i \setminus \set{x_j}}(X)}{Z_{S_i \setminus \set{x_j}}(x_j)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Interpolating polynomials&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
R_i(X) = \sum_j y_{ij} ⋅ L_{ij}(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The verifiers sends a random &lt;span class=&quot;math math-inline&quot;&gt;u ∈ \F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The prover computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(X) = \sum_i u^i ⋅\frac{P_i(X) - R_i(X)}{Z_{S_i}(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The prover sends &lt;span class=&quot;math math-inline&quot;&gt;Q(τ) ⋅ \G_2&lt;&#x2F;span&gt; The verifier checks&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_i \e(u^i ⋅ (P_i - R_i), Z_{S \setminus S_i}(τ) ⋅ \g_2) = \e(Q, Z_S(τ) ⋅ \g_2)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;variant&quot;&gt;Variant&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\bar S_i = S \setminus S_i&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The verifiers sends a random &lt;span class=&quot;math math-inline&quot;&gt;u ∈ \F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Prover computers&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = \frac{1}{Z_{S}(X)} ⋅ \sum_i u^i ⋅ (P_i(X) - R_i(X)) ⋅ Z_{\bar S_i}(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;this equals&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = \sum_i u^i ⋅ \frac{P_i(X) - R_i(X)}{Z_{S_i}(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The prover sends &lt;span class=&quot;math math-inline&quot;&gt;P(τ) ⋅ \G_2&lt;&#x2F;span&gt;. The verifier sends random &lt;span class=&quot;math math-inline&quot;&gt;z ∈ \F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L(X) = \sum_i u^i ⋅ (P_i(X) - R_i(z)) ⋅ Z_{\bar S_i}(z) - Z_S(z) ⋅ P(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
W(X) = \frac{L(X)}{Z_{\set z}(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
W(X) = \frac{Z_S(z)}{Z_{\set z}(X)} ⋅\p{ \sum_i u^i ⋅ \frac{P_i(X) - R_i(z)}{Z_{S_i}(z)} - P(X) }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
W(X) = \frac{Z_S(z)}{Z_{\set z}(X)} ⋅ \sum_i u^i ⋅ \p{ \frac{P_i(X) - R_i(z)}{Z_{S_i}(z)} - \frac{P_i(X) - R_i(X)}{Z_{S_i}(X)} }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and sends &lt;span class=&quot;math math-inline&quot;&gt;W(τ) ⋅ \G_2&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The verifier computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
F = \sum_i u^i ⋅ Z_{\bar S_i}(z) ⋅ \p{P_i - r_i(z) ⋅ \G_2}  - Z_S(z) ⋅ W
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and checks&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e\p{F + z ⋅ W, \G_2} = \e\p{W, τ ⋅ \G_2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
\e\p{F + z ⋅ W, \G_2} &amp;amp;= \e\p{W, τ ⋅ \G_2} \
\sum_i u^i ⋅ Z_{\bar S_i}(z) ⋅ \p{P_i(τ) - r_i(z)}  - Z_S(z) ⋅ W(τ)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;z ⋅ W(τ) &amp;amp;= W(τ) ⋅ τ \
\sum_i u^i ⋅ Z_{\bar S_i}(z) ⋅ \p{P_i(τ) - r_i(z)} &amp;amp;= W(τ) ⋅ τ + Z_S(z) ⋅ W(τ) - z ⋅ W(τ) \
\sum_i u^i ⋅ Z_{\bar S_i}(z) ⋅ \p{P_i(τ) - r_i(z)} &amp;amp;= \p{τ - z + Z_S(z)} ⋅ W(τ) \
\end{aligned}
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;fri&quot;&gt;FRI&lt;&#x2F;h2&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;\h_{\mathcal S} : \mathcal I → \mathcal S&lt;&#x2F;span&gt; be a hash function mapping some input set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal I&lt;&#x2F;span&gt; to the output set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt;. A superscript like &lt;span class=&quot;math math-inline&quot;&gt;\h&amp;#39;&lt;&#x2F;span&gt; is used to indicate two domain separated hash functions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inner-product-arguments&quot;&gt;Inner product arguments&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vitalik.ca&#x2F;general&#x2F;2021&#x2F;11&#x2F;05&#x2F;halo.html&quot;&gt;https:&#x2F;&#x2F;vitalik.ca&#x2F;general&#x2F;2021&#x2F;11&#x2F;05&#x2F;halo.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Halo turns the inner product argument from Bulletproofs into a polynomial commitment scheme.&lt;&#x2F;p&gt;
&lt;p&gt;Basically if we can commit to a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec p&lt;&#x2F;span&gt; and proof &lt;span class=&quot;math math-inline&quot;&gt;y = \inprod{\vec p}{\vec x}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\vec x = \begin{bmatrix} 1, x, x^2, \dots \end{bmatrix}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;set-up&quot;&gt;Set up&lt;&#x2F;h3&gt;
&lt;p&gt;Given elliptic curve group &lt;span class=&quot;math math-inline&quot;&gt;\G&lt;&#x2F;span&gt; with scalar field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;. Generate a common reference string of &lt;span class=&quot;math math-inline&quot;&gt;G_i, H ∈ \G&lt;&#x2F;span&gt; random elements.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;commit&quot;&gt;Commit&lt;&#x2F;h3&gt;
&lt;p&gt;Given a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P(X) = \sum_i c_i ⋅ X^i&lt;&#x2F;span&gt;, generate a random blinding factor &lt;span class=&quot;math math-inline&quot;&gt;r ∈ \F&lt;&#x2F;span&gt;. The commitment is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
r ⋅ H + \sum_i c_i ⋅ G_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proof&quot;&gt;Proof&lt;&#x2F;h3&gt;
&lt;p&gt;To proof that &lt;span class=&quot;math math-inline&quot;&gt;P(x) = v&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;The verifier sends a random &lt;span class=&quot;math math-inline&quot;&gt;U ∈ \G&lt;&#x2F;span&gt;. Start with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\vec a &amp;amp;= \begin{bmatrix} c_0, c_1, c_2, \dots \end{bmatrix} &amp;amp;
\vec b &amp;amp;= \begin{bmatrix} 1, x, x^2, \dots \end{bmatrix} &amp;amp;
\vec G &amp;amp;= \begin{bmatrix} G_0, G_1, G_2, \dots \end{bmatrix} 
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The prover sends &lt;span class=&quot;math math-inline&quot;&gt;L, R&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
L &amp;amp;= \inprod{\vec a_{\mathrm{lo}}}{\vec G_{\mathrm{hi}}} + l ⋅ H + \inprod{\vec a_{\mathrm{lo}}}{ \vec b_{\mathrm{hi}}} ⋅ U \\
R &amp;amp;= \inprod{\vec a_{\mathrm{hi}}}{\vec G_{\mathrm{lo}}} + r ⋅ H + \inprod{\vec a_{\mathrm{hi}}}{ \vec b_{\mathrm{lo}}} ⋅ U \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The verifier issues a random &lt;span class=&quot;math math-inline&quot;&gt;u ∈ \F&lt;&#x2F;span&gt;. The prover computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\vec a&amp;#39; &amp;amp;= \vec a_{\mathrm{hi}} ⋅ u^{-1} + \vec a_{\mathrm{lo}} ⋅ u \\
\vec b&amp;#39; &amp;amp;= \vec b_{\mathrm{hi}} ⋅ u^{-1} + \vec b_{\mathrm{lo}} ⋅ u \\
\vec G&amp;#39; &amp;amp;= \vec G_{\mathrm{hi}} ⋅ u^{-1} + \vec G_{\mathrm{lo}} ⋅ u \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Halo paper has hi, lo reversed for b, G.&lt;&#x2F;p&gt;
&lt;p&gt;Repeat until &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec G&lt;&#x2F;span&gt; are a single element. The prover sends these over and the verifier computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q = \sum_i u_i^2 ⋅L_i + P&amp;#39; + \sum_i u_i^{-2} ⋅ R_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
r&amp;#39; = \sum_i u_i^2 ⋅ l_i + P&amp;#39; + \sum_i u_i^{-2} ⋅ r_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and checks&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q = a ⋅ G + r&amp;#39; ⋅ H + a ⋅ b ⋅ U
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zcash.github.io&#x2F;halo2&#x2F;background&#x2F;pc-ipa.html&quot;&gt;https:&#x2F;&#x2F;zcash.github.io&#x2F;halo2&#x2F;background&#x2F;pc-ipa.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zcash.github.io&#x2F;halo2&#x2F;design&#x2F;proving-system&#x2F;inner-product.html&quot;&gt;https:&#x2F;&#x2F;zcash.github.io&#x2F;halo2&#x2F;design&#x2F;proving-system&#x2F;inner-product.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1066.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1066.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1132.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1132.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;1021.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;1021.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Aurora &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;828.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;828.pdf&lt;&#x2F;a&gt; Section 8&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-schemes&quot;&gt;Other schemes&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dory&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Dark&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vitalik.ca&#x2F;general&#x2F;2017&#x2F;01&#x2F;14&#x2F;exploring_ecp.html&quot;&gt;https:&#x2F;&#x2F;vitalik.ca&#x2F;general&#x2F;2017&#x2F;01&#x2F;14&#x2F;exploring_ecp.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dankradfeist.de&#x2F;ethereum&#x2F;2020&#x2F;06&#x2F;16&#x2F;kate-polynomial-commitments.html&quot;&gt;https:&#x2F;&#x2F;dankradfeist.de&#x2F;ethereum&#x2F;2020&#x2F;06&#x2F;16&#x2F;kate-polynomial-commitments.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;alinush.github.io&#x2F;2020&#x2F;05&#x2F;06&#x2F;kzg-polynomial-commitments.html#fn:KZG10e&quot;&gt;https:&#x2F;&#x2F;alinush.github.io&#x2F;2020&#x2F;05&#x2F;06&#x2F;kzg-polynomial-commitments.html#fn:KZG10e&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arnaucube.com&#x2F;blog&#x2F;kzg-commitments.html&quot;&gt;https:&#x2F;&#x2F;arnaucube.com&#x2F;blog&#x2F;kzg-commitments.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arnaucube.com&#x2F;blog&#x2F;kzg-batch-proof.html&quot;&gt;https:&#x2F;&#x2F;arnaucube.com&#x2F;blog&#x2F;kzg-batch-proof.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;ProofsArgsAndZK.pdf&quot;&gt;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;ProofsArgsAndZK.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1132.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1132.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zcash.github.io&#x2F;halo2&#x2F;concepts&#x2F;chips.html&quot;&gt;https:&#x2F;&#x2F;zcash.github.io&#x2F;halo2&#x2F;concepts&#x2F;chips.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Polynomials</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/polynomials/"/>
        <id>https://2π.com/22/polynomials/</id>
        
        <content type="html" xml:base="https://2π.com/22/polynomials/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\Z{\mathbb{Z}}
\gdef\F{\mathbb{F}}
\gdef\p#1{\left({#1}\right)}
\gdef\set#1{\mathcal{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;polynomials&quot;&gt;Polynomials&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\Z{\mathrm{Z}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;polynomial-basis&quot;&gt;Polynomial basis&lt;&#x2F;h3&gt;
&lt;p&gt;We convert this to a polynomial problem by picking a basis &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \F^n&lt;&#x2F;span&gt;. Define zero polynomials to mean&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\mathcal S}(X) = \prod_{s ∈ \mathcal S} \p{X - s}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When not otherwise specified, take &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt; to be &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt;. Take &lt;span class=&quot;math math-inline&quot;&gt;\overline s&lt;&#x2F;span&gt; to mean the set &lt;span class=&quot;math math-inline&quot;&gt;\vec x \setminus \set{x}&lt;&#x2F;span&gt;. Define Lagrange basis functions&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_{s}(X) = \frac{\Z_{\overline s}(X)}{\Z_{\overline s}(s)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This function is zero on the set &lt;span class=&quot;math math-inline&quot;&gt;\overline s&lt;&#x2F;span&gt; and one on &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt;. Take &lt;span class=&quot;math math-inline&quot;&gt;L_i&lt;&#x2F;span&gt; to mean &lt;span class=&quot;math math-inline&quot;&gt;L_{x_i}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Q: Are all the multiplicative subgroups of a field roots of unity?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-convenient-polynomial-basis&quot;&gt;A convenient polynomial basis&lt;&#x2F;h3&gt;
&lt;p&gt;A computationally convenient choice for basis &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; are the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th roots of unity &lt;span class=&quot;math math-inline&quot;&gt;x_i = \mathrm{ω}_n^i&lt;&#x2F;span&gt;. In particular this leads to the simplification &lt;span class=&quot;math math-inline&quot;&gt;Z(X) = X^n - 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Z_{\overline s}(X) = \begin{cases}
    \frac{X^n - 1}{X - s} &amp;amp;  X ≠ s \\
    n ⋅ s^{n - 2} &amp;amp; X = s
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where the &lt;span class=&quot;math math-inline&quot;&gt;X=s&lt;&#x2F;span&gt; case is derived using &lt;a href=&quot;&#x2F;19&#x2F;lhospital-rules-in-finite-fields&quot;&gt;L&#x27;Hôpital&#x27;s rule&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Check the &lt;span class=&quot;math math-inline&quot;&gt;X = s&lt;&#x2F;span&gt; case.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_{i}(X) = \begin{cases}
\frac{\mathrm{ω}_n^{2·i}}{n} · \frac{X^n - 1}{X - ω_n^i}  &amp;amp;  X ≠ ω_n^i \\
1 &amp;amp; X = ω_n^i
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vanishing-on-a-square&quot;&gt;Vanishing on a square&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\set{α ⋅ ω_n^i}}(X) = X^n - α^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ben+19b from Marlin:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;which is a polynomial of individual degree |S| − 1 because X − Y divides X^i − Y^i for any positive integer i.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It is zero on &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S × \mathcal S&lt;&#x2F;span&gt; except for the diagonal.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Proof systems</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/proof-systems/"/>
        <id>https://2π.com/22/proof-systems/</id>
        
        <content type="html" xml:base="https://2π.com/22/proof-systems/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;proof-systems&quot;&gt;Proof systems&lt;&#x2F;h1&gt;
&lt;p&gt;This post is a reframing of the evolution of proof systems from the contemporary perspective of LDE polynomial commitment protocols.&lt;&#x2F;p&gt;
&lt;p&gt;While proof systems have thus far always been presented end-to-end, they often break down into two parts: an arithmetization technique and a polynomial commitment scheme. Despite being presented integral, these are mostly interchangeable and it is perfectly reasonable to for example use Plonk arithmetization on the FRI commitment protocol.&lt;&#x2F;p&gt;
&lt;div class=&quot;mermaid&quot;&gt;
flowchart LR;
    pr([Claim])
    subgraph Arithmetization
    Pinocchio
    Groth16
    Sonic
    Marlin
    Plonk
    Stark
    end
    pr --&gt; Pinocchio --&gt; lp
    pr --&gt; Groth16 --&gt; lp
    pr --&gt; Sonic --&gt; lp
    pr --&gt; Marlin --&gt; lp
    pr --&gt; Plonk --&gt; lp
    pr --&gt; Stark --&gt; lp
    lp([Polynomial\ncommitment\nprotocol])
    subgraph &quot;Scheme&quot;
    KZG
    IPA
    FRI
    DARK
    end
    lp --&gt; KZG --&gt; fs
    lp --&gt; IPA --&gt; fs
    lp --&gt; FRI --&gt; fs
    lp --&gt; DARK --&gt; fs
    fs[Fiat-Shamir] --&gt; nip([Proof])
&lt;&#x2F;div&gt;
&lt;p&gt;The choice of Polynomial Commitment scheme determines the field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; that is used
in the arithmetization layer. While it is possible to use math outside of &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; in the claim, this requires costly emulation using &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;-math. Much research has been devoted to making this emulation more efficient.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basic-architecture&quot;&gt;Basic Architecture&lt;&#x2F;h2&gt;
&lt;p&gt;Claims&lt;&#x2F;p&gt;
&lt;p&gt;Arithmetization&lt;&#x2F;p&gt;
&lt;p&gt;Polynomial Commitment Protocols&lt;&#x2F;p&gt;
&lt;p&gt;Commitment Schemes&lt;&#x2F;p&gt;
&lt;p&gt;Interactive proofs&lt;&#x2F;p&gt;
&lt;p&gt;Fiat-Shamir&lt;&#x2F;p&gt;
&lt;p&gt;Non-interactive proofs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;arithmetization&quot;&gt;Arithmetization&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pinocchio&quot;&gt;Pinocchio&lt;&#x2F;h3&gt;
&lt;p&gt;This is the system used by Circom, Zorkates, Groth16 and most Ethereum projects that do not develop their own proof system.&lt;&#x2F;p&gt;
&lt;p&gt;The computation is first reduced to an algebraic circuit of basic operations over a field. The circuit is represented by a triplet of matrices &lt;span class=&quot;math math-inline&quot;&gt;(A, B, C) ∈ \F^{n × m}&lt;&#x2F;span&gt; such that a valid witness &lt;span class=&quot;math math-inline&quot;&gt;\vec s ∈ \F^n&lt;&#x2F;span&gt; satisfies.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is the number of variables in the system, &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; is the number of gate relationships.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec s ⋅ A \circ \vec s ⋅ B - \vec s ⋅ C = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We pick a basis &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \F^m&lt;&#x2F;span&gt; and compute &lt;span class=&quot;math math-inline&quot;&gt;3⋅n + 1&lt;&#x2F;span&gt; polynomials &lt;span class=&quot;math math-inline&quot;&gt;A_i, B_i, C_i, Z ∈ \F[X_{&amp;lt;m}]&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_i(x_j) &amp;amp;= A_{ij} &amp;amp;
B_i(x_j) &amp;amp;= B_{ij} &amp;amp;
C_i(x_j) &amp;amp;= C_{ij} &amp;amp;
Z(x_i) &amp;amp;= 0
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a witness &lt;span class=&quot;math math-inline&quot;&gt;\vec s&lt;&#x2F;span&gt;, we then compute &lt;span class=&quot;math math-inline&quot;&gt;A, B, C ∈ \F[X_{&amp;lt;m}]&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A(X) &amp;amp;= \sum_i s_i ⋅A_i(X) &amp;amp;
B(X) &amp;amp;= \sum_i s_i ⋅B_i(X) &amp;amp;
C(X) &amp;amp;= \sum_i s_i ⋅C_i(X)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The circuit is satisfied iff there exists a &lt;span class=&quot;math math-inline&quot;&gt;H ∈ \F[X_{&amp;lt;m}]&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A(X) ⋅ B(X) - C(X) = H(X) ⋅ Z(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Bryan Parno, Craig Gentry, Jon Howell, and Mariana Raykova (2013).
&quot;Pinocchio: Nearly Practical Verifiable Computation&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;279&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.zeroknowledgeblog.com&#x2F;index.php&#x2F;the-pinocchio-protocol&quot;&gt;http:&#x2F;&#x2F;www.zeroknowledgeblog.com&#x2F;index.php&#x2F;the-pinocchio-protocol&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.vitalik.ca&#x2F;general&#x2F;2016&#x2F;12&#x2F;10&#x2F;qap.html&quot;&gt;https:&#x2F;&#x2F;www.vitalik.ca&#x2F;general&#x2F;2016&#x2F;12&#x2F;10&#x2F;qap.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;groth16&quot;&gt;Groth16&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Jens Groth (2016).
&quot;On the Size of Pairing-based Non-interactive Arguments&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;260&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;sonic&quot;&gt;Sonic&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Mary Maller,d Sean Bowe, Markulf Kohlweiss, and Sarah Meiklejohn (2019).
&quot;Sonic: Zero-Knowledge SNARKs from Linear-Size Universal and Updateable Structured Reference Strings&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;099&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;stark&quot;&gt;Stark&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Eli Ben-Sasson, Iddo Bentov, Yinon Horesh, and Michael Riabzev (2018).
&quot;Scalable, transparent, and post-quantum secure computational integrity&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;046&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;plonk&quot;&gt;Plonk&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ariel Gabizon, Zachary J. Williamson, and Oana Ciobotaru (2019).
&quot;PLONK: Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of Knowledge&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Ariel Gabizon, and Zachary J. Williamson (2020).
&quot; plookup: A simplified polynomial protocol for lookup tables&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;315&quot;&gt;link&lt;&#x2F;a&gt;``&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Ariel Gabizon and Zachary J. Williamson (2020).
&quot;&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aztec-protocol.gitbook.io&#x2F;zkproofs-proposal&#x2F;&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Ariel Gabizon and Zachary J. Williamson (2021).
&quot;fflonk: a Fast-Fourier inspired verifier efficient version of PlonK&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;1167&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;086&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;polynomial-commitment&quot;&gt;Polynomial Commitment&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackernoon.com&#x2F;kzg10-ipa-fri-and-darks-analysis-of-polynomial-commitment-schemes&quot;&gt;https:&#x2F;&#x2F;hackernoon.com&#x2F;kzg10-ipa-fri-and-darks-analysis-of-polynomial-commitment-schemes&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;kzg&quot;&gt;KZG&lt;&#x2F;h3&gt;
&lt;p&gt;We want to proof&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\forall_i F(x_i) = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;on some domain &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \F^n&lt;&#x2F;span&gt;. We construct the unique &lt;span class=&quot;math math-inline&quot;&gt;Z(X) ∈ \F[X_{&amp;lt;n}]&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;Z(x_i) = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
F(X) = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Pick a random &lt;span class=&quot;math math-inline&quot;&gt;z ∈ \F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cryptologie.net&#x2F;article&#x2F;526&#x2F;maller-optimization-to-reduce-proof-size&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.cryptologie.net&#x2F;article&#x2F;526&#x2F;maller-optimization-to-reduce-proof-size&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cryptologie.net&#x2F;article&#x2F;525&#x2F;pairing-based-polynomial-commitments-and-kate-polynomial-commitments&#x2F;&quot;&gt;https:&#x2F;&#x2F;cryptologie.net&#x2F;article&#x2F;525&#x2F;pairing-based-polynomial-commitments-and-kate-polynomial-commitments&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Aniket Kate, Gregory M. Zaverucha, and Ian Goldberg (2010).
&quot;Constant-Size Commitments to Polynomials and Their Applications&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.iacr.org&#x2F;archive&#x2F;asiacrypt2010&#x2F;6477178&#x2F;6477178.pdf&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;ipa&quot;&gt;IPA&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Benedikt Bünz, Jonathan Bootle, Dan Boneh, Andrew Poelstra, Pieter Wuille, and Greg Maxwell (2017).
&quot;Bulletproofs: Short Proofs for Confidential Transactions and More&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1066&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;fri&quot;&gt;FRI&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Eli Ben-Sasson, Iddo Bentov†, Yinon Horesh, and Michael Riabzev (2017).
&quot;Fast Reed-Solomon Interactive Oracle Proofs of Proximity&quot;
[link](&amp;lt;https:&#x2F;&#x2F;eccc.weizmann.ac.il&#x2F;report&#x2F;2017&#x2F;134&#x2F;revision&#x2F;2&#x2F;download&#x2F;)&lt;&#x2F;li&gt;
&lt;li&gt;Eli Ben-Sasson, Lior Goldberg, Swastik Kopparty, and Shubhangi Saraf (2019).
&quot;DEEP-FRI: Sampling Outside the Box Improves Soundness&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;336&quot;&gt;link&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;654&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;654&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;dark&quot;&gt;DARK&lt;&#x2F;h3&gt;
&lt;h2 id=&quot;implementations&quot;&gt;Implementations&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;minaprotocol.com&#x2F;blog&#x2F;kimchi-the-latest-update-to-minas-proof-system&quot;&gt;Mina&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;z.cash&#x2F;&quot;&gt;Zcash&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.polygon.technology&#x2F;introducing-plonky2&#x2F;&quot;&gt;Polygon Zero&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aztec.network&#x2F;&quot;&gt;Aztec network&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dusk.network&#x2F;&quot;&gt;Dusk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;matter-labs.io&#x2F;&quot;&gt;MatterLabs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;astar.network&#x2F;&quot;&gt;Astar&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;anoma.network&#x2F;&quot;&gt;Anoma&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;starkware.co&#x2F;&quot;&gt;Starkware&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;circom.io&#x2F;&quot;&gt;Circom&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zokrates.github.io&#x2F;&quot;&gt;Zokrates&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;minaprotocol.com&#x2F;blog&#x2F;kimchi-the-latest-update-to-minas-proof-system&quot;&gt;https:&#x2F;&#x2F;minaprotocol.com&#x2F;blog&#x2F;kimchi-the-latest-update-to-minas-proof-system&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;116&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;116&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;828&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;828&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cryptologie.net&#x2F;article&#x2F;527&#x2F;understanding-plonk&#x2F;&quot;&gt;https:&#x2F;&#x2F;cryptologie.net&#x2F;article&#x2F;527&#x2F;understanding-plonk&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.di.ens.fr&#x2F;~nitulesc&#x2F;files&#x2F;Survey-SNARKs.pdf&quot;&gt;https:&#x2F;&#x2F;www.di.ens.fr&#x2F;~nitulesc&#x2F;files&#x2F;Survey-SNARKs.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Produce a Stark proof</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/stark/"/>
        <id>https://2π.com/22/stark/</id>
        
        <content type="html" xml:base="https://2π.com/22/stark/">&lt;h1 id=&quot;produce-a-stark-proof&quot;&gt;Produce a Stark proof.&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;input&quot;&gt;Input&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;code&gt;ConstraintSystem&lt;&#x2F;code&gt; which captures the claim that is made.
A &lt;code&gt;TraceTable&lt;&#x2F;code&gt; which is the witness to this claim.
A &lt;code&gt;ProofParams&lt;&#x2F;code&gt; object which configures the proof.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;output&quot;&gt;Output&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;code&gt;ProverChannel&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;proof-construction&quot;&gt;Proof construction&lt;&#x2F;h2&gt;
&lt;p&gt;A new &lt;code&gt;ProverChannel&lt;&#x2F;code&gt; is initialized with the public input.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-1-low-degree-extension-of-the-trace-table&quot;&gt;Step 1: Low degree extension of the trace table.&lt;&#x2F;h3&gt;
&lt;p&gt;The trace table is interpolated to an evaluation domain that is larger by a
factor &lt;code&gt;params.blowup&lt;&#x2F;code&gt;. It is also offset by a cofactor (currently fixed to
the default generator of the field, &lt;code&gt;3&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
T_{i, j} = P_j(\omega_{\text{trace}}^i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;!-- TODO: Introduce trace table --&gt;
&lt;p&gt;A merkle tree is constructed over this evaluation domain and commited to the
channel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\text{Leaf}_i = (T_0(x_i), T_1(x_i), \dots )
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;x_i = 3 \cdot \omega_{\mathrm{lde}}^i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;!-- TODO: The indices should be bit-reversed. --&gt;
&lt;h3 id=&quot;step-2-constraint-commitment&quot;&gt;Step 2: Constraint commitment&lt;&#x2F;h3&gt;
&lt;p&gt;For each constraint, two random value &lt;span class=&quot;math math-inline&quot;&gt;\alpha_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\beta_i&lt;&#x2F;span&gt; are drawn
from the channel. The constraints are combined as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C(x) = \sum_i (\alpha_i + \beta_i \cdot x^{d_i}) \cdot C_i(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;!-- TODO: Introduce constraints --&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;d_i&lt;&#x2F;span&gt; is the adjustment degree,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
d_i = \mathrm{target\_degree} - \deg C_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The adjustment degrees are there to prevent make sure that the final
polynomial is a sum of all constraint polynomials aligned on the lowest
coefficient, and on the highest coefficient. This guarantees that constraint
degrees are enforced exactly. (Non-enforcement on the low end would mean a
term of negative degree &lt;span class=&quot;math math-inline&quot;&gt;x^{-1}&lt;&#x2F;span&gt; would be accepted).&lt;&#x2F;p&gt;
&lt;!-- TODO: Introduce target degree --&gt;
&lt;p&gt;The resulting polynomial &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; is now split in &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{d}&lt;&#x2F;span&gt; polynomials such
that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C(x) = A_0(x^{\mathrm{d}}) + x \cdot A_1(x^{\mathrm{d}}) + x^2 \cdot
A_2(x^{\mathrm{d}}) + \cdots + x^{{\mathrm{d}} -1}\cdot
A_{\mathrm{d}}(x^{\mathrm{d}})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\deg A_i ≤ \mathrm{trace\_length}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For a linear constraint system this does nothing and we have &lt;span class=&quot;math math-inline&quot;&gt;A_0 = C&lt;&#x2F;span&gt;, for
a quadratic constraint system &lt;span class=&quot;math math-inline&quot;&gt;A_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;A_1&lt;&#x2F;span&gt; contain all the odd and even
coefficients of &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; respectively.&lt;&#x2F;p&gt;
&lt;p&gt;A merkle tree is constructed over the LDE values of the &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; polynomials and
committed to the channel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\text{Leaf}_i = (A_0(x_i), A_1(x_i), \dots )
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-3-divide-out-the-deep-points-and-combine&quot;&gt;Step 3: Divide out the deep points and combine&lt;&#x2F;h3&gt;
&lt;p&gt;A random value &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt; is drawn from the channel.&lt;&#x2F;p&gt;
&lt;p&gt;For each trace polynomial, &lt;span class=&quot;math math-inline&quot;&gt;T_i(z)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;T_i(\omega \cdot z)&lt;&#x2F;span&gt; are written to
the proof. For each combined constraint polynomial, &lt;span class=&quot;math math-inline&quot;&gt;A_i(z^{\mathrm{d}})&lt;&#x2F;span&gt; is
written to the proof.&lt;&#x2F;p&gt;
&lt;p&gt;The points are then divided out of the polynomials, with each trace
polynomial being treated twice:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
T_i&amp;#39;(x) = \frac{T_i(x) - T_i(z)}{x - z}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
T_i&amp;#39;&amp;#39;(x) = \frac{T_i(x) - T_i(\omega \cdot z)}{x - \omega \cdot z}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Similarly for the constraint polynomials:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A_i&amp;#39;(x) = \frac{A_i(x) - A_i(z^{\mathrm{d}})}{x - z^{\mathrm{d}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For each trace polynomial, two random values &lt;span class=&quot;math math-inline&quot;&gt;\alpha_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\beta_i&lt;&#x2F;span&gt; are
drawn from the channel. For each constraint polynomial, one random value
&lt;span class=&quot;math math-inline&quot;&gt;\gamma_i&lt;&#x2F;span&gt; is drawn.&lt;&#x2F;p&gt;
&lt;p&gt;All polynomial are combined in a single final polynomial:&lt;&#x2F;p&gt;
&lt;p&gt;$$
P(x) = \sum_i \left( \alpha_i \cdot T_i&#x27;(x) + \beta_i \cdot T_i&#x27;&#x27;(x)\right)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;\sum_i \gamma_i \cdot A_i&#x27;(x)
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;!-- TODO: Mention degree bounds on polynomials. Wouldn&#x27;t this be -2 because
of the divided out points? --&gt;
&lt;h3 id=&quot;step-4-create-fri-layers&quot;&gt;Step 4: Create FRI layers&lt;&#x2F;h3&gt;
&lt;p&gt;The final polynomial &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; is evaluated on the LDE domain. A Merkle tree is
constructed of these values and committed to the proof.&lt;&#x2F;p&gt;
&lt;p&gt;A random value &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; is drawn from the channel. Take &lt;span class=&quot;math math-inline&quot;&gt;P_0&lt;&#x2F;span&gt; to be our
final polynomial, then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P_{i+1}(x^2) = \left( P_i(x) + P_i(-x) \right) + \frac{\alpha}{x} \left(
P_i(x) - P_i(-x) \right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is the same as taking all the odd coefficients, multiplying them by
&lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; and adding them to the even coefficients.&lt;&#x2F;p&gt;
&lt;p&gt;This reduction step can be repeated using &lt;span class=&quot;math math-inline&quot;&gt;\alpha^2, \alpha^4, \dots&lt;&#x2F;span&gt;
instead of &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt;. Once sufficient reductions are made, a new Merkle tree
is constructed, committed too, a new random value &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; is drawn and the
FRI layering process repeats.&lt;&#x2F;p&gt;
&lt;p&gt;The number of reduction steps in between each commitment is specified using
the &lt;code&gt;params.fri_layout&lt;&#x2F;code&gt; parameter. The default recommendation is to do three
reductions between each layer, as this optimizes proof size.&lt;&#x2F;p&gt;
&lt;p&gt;Once the degree of the polynomial is sufficiently low, it is written to the
channel in coefficient form.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-5-proof-of-work&quot;&gt;Step 5: Proof of work&lt;&#x2F;h3&gt;
&lt;p&gt;A random challenge is drawn from the channel and a proof of work is solved.
The solution is written to the channel. The difficulty is specified by the
&lt;code&gt;params.pow_bits&lt;&#x2F;code&gt; parameter.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-6-decommit-queries&quot;&gt;Step 6: Decommit queries&lt;&#x2F;h3&gt;
&lt;p&gt;Random values &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; from the LDE domain are drawn from the channel to form
our queries. The total number of queries is specified by &lt;code&gt;params.queries&lt;&#x2F;code&gt;.
The values are sorted.&lt;&#x2F;p&gt;
&lt;!-- TODO: Sorted by bit-reversed index --&gt;
&lt;p&gt;The trace polynomial values at the query locations are written to the
channel:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
T_0(x_0), T_1(x_0), \dots, T_0(x_1), T_1(x_1), \dots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A merkle proof is provided linking these values to the earlier commitment.&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, the combined constraint polynomial values are written to the
channel:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A_0(x_0), A_1(x_0), \dots, A_0(x_1), A_1(x_1), \dots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And again a merkle proof is provided linking these values to the earlier
commitment.&lt;&#x2F;p&gt;
&lt;p&gt;Then the values of the final polynomial are provided:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x_0), P(x_1), \dots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;the merkle proof for these values links them to the commitment at the start
of the FRI layer.&lt;&#x2F;p&gt;
&lt;p&gt;Now the set of points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; is squared while maintaining the sorted order.
Duplicate points are removed. This is repeated unit we reach the reduction
for the next FRI commitment.&lt;&#x2F;p&gt;
&lt;p&gt;Values for the next committed FRI layer are provided:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P_i(x_0), P_i(x_1), \dots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with merkle proofs to that layer. This process is repeated for all FRI layer
commitments.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Notes on Starky</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/starky/"/>
        <id>https://2π.com/22/starky/</id>
        
        <content type="html" xml:base="https://2π.com/22/starky/">&lt;h1 id=&quot;notes-on-starky&quot;&gt;Notes on Starky&lt;&#x2F;h1&gt;
&lt;p&gt;Currently it&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Forces constraints to be between two consecutive rows, except first and last, which are handled separately.&lt;&#x2F;li&gt;
&lt;li&gt;Does not have abstractions allowing for the creation of complex proofs.&lt;&#x2F;li&gt;
&lt;li&gt;Does not yet implement constant polynomials (&#x27;permutation checks&#x27;), but a lot of infra is there.&lt;&#x2F;li&gt;
&lt;li&gt;Implements multiple OODS samples (?)&lt;&#x2F;li&gt;
&lt;li&gt;Not optimized for very large traces. (no cache-oblivious algorithms FFT)&lt;&#x2F;li&gt;
&lt;li&gt;No evaluation optimization for constraint polynomials.&lt;&#x2F;li&gt;
&lt;li&gt;Has active team.&lt;&#x2F;li&gt;
&lt;li&gt;Implements blinding.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;OpenZKP&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Does not use a small field + field extension&lt;&#x2F;li&gt;
&lt;li&gt;Does not implement constant columns at all.&lt;&#x2F;li&gt;
&lt;li&gt;Optimizes constraint evaluation.&lt;&#x2F;li&gt;
&lt;li&gt;Supports constraints over arbitrary distances.&lt;&#x2F;li&gt;
&lt;li&gt;Supports constraints over arbitrary denominators.&lt;&#x2F;li&gt;
&lt;li&gt;Unmaintained.&lt;&#x2F;li&gt;
&lt;li&gt;Aarch64 asm lacking (though x86_64 is there).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Random ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Interactive proof with one forced Ethereum block after FRI commitment. How many openings are required?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Build standalone Algebraic DAG library.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Evaluate over domains larger than the largest coset: Take several random cosets. FRI can no longer reduce to a constant, but can still reduce to poly of degree equal to no cosets, which can be directly evaluated. This allows trace length up to the full size of the Goldilocks coset. (Assuming the extension doesn&#x27;t affect this somehow).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Folding Schemes</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/folding/"/>
        <id>https://2π.com/23/folding/</id>
        
        <content type="html" xml:base="https://2π.com/23/folding/">&lt;h1 id=&quot;folding-schemes&quot;&gt;Folding Schemes&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\set#1{\mathcal{#1}}
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\R{\mathrm{R}}
\gdef\P{\mathsf{cm}}
\gdef\H{\mathsf{H}}
\gdef\Z{\mathrm{Z}}
\gdef\bigop#1#2{\mathop{\Large #1}\limits_{#2}}
\gdef\zkp#1#2#3{\p{
\begin{array}{c}#1\\\hline#2\end{array}
\middle\vert
\begin{aligned}#3\end{aligned}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;nova&quot;&gt;Nova&lt;&#x2F;h2&gt;
&lt;p&gt;Given a cycle of curves &lt;span class=&quot;math math-inline&quot;&gt;\G_1, \G_2&lt;&#x2F;span&gt; with scalar fields &lt;span class=&quot;math math-inline&quot;&gt;\F_1, \F_2&lt;&#x2F;span&gt; (and thus base fields &lt;span class=&quot;math math-inline&quot;&gt;\F_2, \F_1&lt;&#x2F;span&gt;). Construct the pairs (with element-wise operations) &lt;span class=&quot;math math-inline&quot;&gt;\G = \G_1 × \G_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\R = \F_1 × \F_2&lt;&#x2F;span&gt;. Note that &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt; degrades to a ring, &lt;span class=&quot;math math-inline&quot;&gt;\G_i&lt;&#x2F;span&gt; is a vector space over &lt;span class=&quot;math math-inline&quot;&gt;\F_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G&lt;&#x2F;span&gt; is and &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt;-module.&lt;&#x2F;p&gt;
&lt;p&gt;Construct family of cryptographic hashes &lt;span class=&quot;math math-inline&quot;&gt;\H_X: Y → X&lt;&#x2F;span&gt;. Where elements of the inputs set (defined implicitly) map to pseudo-random elements in the target set &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt;. We will use the shorthand &lt;span class=&quot;math math-inline&quot;&gt;\H_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\H_1&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;\H_{\F_1}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\H_{\F_2}&lt;&#x2F;span&gt; respectively.&lt;&#x2F;p&gt;
&lt;p&gt;Construct a Pedersen commitment &lt;span class=&quot;math math-inline&quot;&gt;\P: \R^n → \G&lt;&#x2F;span&gt; by fixing a random vector in &lt;span class=&quot;math math-inline&quot;&gt;\vec g ∈ \p{\G_{\setminus \{0\}}}^n&lt;&#x2F;span&gt; and taking the linear combination: &lt;span class=&quot;math math-inline&quot;&gt;\P(\vec x) = \sum_i x_i ⋅ g_i&lt;&#x2F;span&gt;. Factor &lt;span class=&quot;math math-inline&quot;&gt;\P&lt;&#x2F;span&gt; into two commitments &lt;span class=&quot;math math-inline&quot;&gt;\P_1: \F_1 → \G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\P_1: \F_2 → \G_2&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;relaxed-r1cs&quot;&gt;Relaxed R1CS&lt;&#x2F;h3&gt;
&lt;p&gt;Given a computable partial function &lt;span class=&quot;math math-inline&quot;&gt;f: \R^u × \R^v → \R^v&lt;&#x2F;span&gt; on a ring &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec v = f(\vec u_n, … f(\vec u_1, f(\vec u_0, \vec v_0)))…)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a computable function &lt;span class=&quot;math math-inline&quot;&gt;f: \R^u → \R^v&lt;&#x2F;span&gt; on a ring &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt;. We arithmatize the function to &lt;span class=&quot;math math-inline&quot;&gt;\mat A, \mat B, \mat C ∈ \R^{m×n}&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(\vec u) = \vec v
\quad ⇔ \quad  \bigop{∃}{\begin{subarray}{l}
\vec w ∈ \R^t \\
\end{subarray}} \left\{\begin{aligned}
\vec z &amp;amp;= \begin{bmatrix}1 &amp;amp; \vec u &amp;amp; \vec v &amp;amp; \vec w\end{bmatrix}\\
\mat C ⋅ \vec z &amp;amp;= \p{\mat A ⋅ \vec z} ⊙ \p{\mat B ⋅ \vec z}\\
\end{aligned}\right.
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For convenience we will write &lt;span class=&quot;math math-inline&quot;&gt;\vec x = [\vec u\ \vec v]&lt;&#x2F;span&gt;. An instance is a tuple &lt;span class=&quot;math math-inline&quot;&gt;(e, w, s, \vec x)∈\G×\G×\R×\R^{u+v}&lt;&#x2F;span&gt; such that there exists a &lt;span class=&quot;math math-inline&quot;&gt;\vec w ∈ \R^n, \vec e ∈ \R^m&lt;&#x2F;span&gt; that satisfy&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
e &amp;amp;= \P(\vec e) &amp;amp; 
\vec z &amp;amp;= \begin{bmatrix}s &amp;amp; \vec x &amp;amp; \vec w \end{bmatrix}\\
w &amp;amp;= \P(\vec w) &amp;amp;
\p{\mat A ⋅ \vec z} ⊙ \p{\mat B ⋅ \vec z} &amp;amp;=
s ⋅ \mat C ⋅ \vec z + \vec e\\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Relaxed R1CS instances form an &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt;-module. The zero instance is &lt;span class=&quot;math math-inline&quot;&gt;(0, 0, 0, \vec 0)&lt;&#x2F;span&gt;. The scalar product of &lt;span class=&quot;math math-inline&quot;&gt;(e, w, s, \vec x)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r ∈ \R&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;(r²⋅e, r⋅w, r⋅s, r⋅\vec x)&lt;&#x2F;span&gt;. The sum of &lt;span class=&quot;math math-inline&quot;&gt;(e_1, w_1, s_1, \vec x_1)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(e_2, w_2, s_2, \vec x_2)&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;(e_1 + e_2 + \P(\vec d), w_1 + w_2, s_1 + s_2, \vec x_1 + \vec x_2)&lt;&#x2F;span&gt; where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec d = \p{\mat A ⋅ \vec z_1} ⊙ \p{\mat B ⋅ \vec z_2} + \p{\mat A ⋅ \vec z_2} ⊙ \p{\mat B ⋅ \vec z_1} - \mat C ⋅ \p{s_1 ⋅ \vec z_2 + s_2 ⋅\vec z_1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Instances of the form &lt;span class=&quot;math math-inline&quot;&gt;(0, w, 1, \vec x)&lt;&#x2F;span&gt; correspond directly to regular R1CS instances.&lt;&#x2F;p&gt;
&lt;p&gt;To update prover state:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\mat A ⋅ \vec z, \mat B ⋅ \vec z, \mat C ⋅ \vec z, s, s⋅\mat C ⋅ \vec z - \p{\mat A ⋅ \vec z} ⊙ \p{\mat B ⋅ \vec z}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{r⋅\vec a, r⋅\vec b, r⋅\vec c, r⋅s, r²⋅\vec e}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\vec a_1 + \vec a_2, \vec b_1 + \vec b_2, \vec c_1 + \vec c_2, \vec e_1 + \vec e_2 + \vec d}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec d = \vec a_1 ⊙ \vec b_2 + \vec a_2 ⊙ \vec b_1 - s_1 ⋅ \vec c_2 - s_2 ⋅\vec c_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The important thing is that linear combinations can be computed element-wise.&lt;&#x2F;p&gt;
&lt;p&gt;We can also compute &lt;span class=&quot;math math-inline&quot;&gt;\vec e&lt;&#x2F;span&gt; by recovering it from the added instance as &lt;span class=&quot;math math-inline&quot;&gt;\vec e = \vec a ⊙ \vec b - s ⋅ \vec c&lt;&#x2F;span&gt;. This may be more efficient?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; An instance can be generated for any &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; by solving for &lt;span class=&quot;math math-inline&quot;&gt;\vec e&lt;&#x2F;span&gt;. Only when &lt;span class=&quot;math math-inline&quot;&gt;s ≠ 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec e = \vec 0&lt;&#x2F;span&gt; does the instance proof a &lt;span class=&quot;math math-inline&quot;&gt;f(\vec u) = \vec v&lt;&#x2F;span&gt; claim. So we are interested in the subspace spanned by those instances.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; For every R1CS &lt;span class=&quot;math math-inline&quot;&gt;(A, B, C)&lt;&#x2F;span&gt; we can construct an R1CS &lt;span class=&quot;math math-inline&quot;&gt;(A&amp;#39;, A&amp;#39;, C&amp;#39;)&lt;&#x2F;span&gt; with at most twice the constraints. The verification relation then becomes &lt;span class=&quot;math math-inline&quot;&gt;\p{\mat A ⋅ \vec z}^{⊙2} = s⋅\mat C ⋅ \vec z + \vec e&lt;&#x2F;span&gt;. If we add two instances we get&lt;&#x2F;p&gt;
&lt;p&gt;$$
\vec d =  2⋅\p{\mat A ⋅ \vec z_1}⊙\p{\mat A ⋅ \vec z_2}&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;\mat C ⋅ \p{s_1 ⋅ \vec z_2 + s_2  ⋅ \vec z_1}
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;the main advantage is one fewer state vector to carry around. &lt;span class=&quot;math math-inline&quot;&gt;\vec e = \vec a^{⊙2} - s ⋅ \vec c&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;customizable-constraint-system-hypernova&quot;&gt;Customizable Constraint System (HyperNova)&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{\set T ∈ \set S}\ 
\bigodot_{M ∈ \set T}\ 
\mat M ⋅ \vec w
= \vec 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;protostar&quot;&gt;ProtoStar&lt;&#x2F;h3&gt;
&lt;p&gt;Generic constraints, test for &lt;span class=&quot;math math-inline&quot;&gt;f(\vec w) = \vec 0&lt;&#x2F;span&gt; for polynomial &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;. R1CS translates as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_i(\vec w) = (\mat A ⋅ \vec w)_i ⋅ (\mat B ⋅ \vec w)_i  - (\mat C ⋅ \vec w)_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Instance &lt;span class=&quot;math math-inline&quot;&gt;(w; \vec w)&lt;&#x2F;span&gt; satisfies iff &lt;span class=&quot;math math-inline&quot;&gt;w = \P(\vec w)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f(\vec w) = \vec 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Given two instances interpolate&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ω(X) = X⋅\vec w_1 + (1 - X)⋅ \vec w_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;from the initial instances we have &lt;span class=&quot;math math-inline&quot;&gt;f(ω(0)) = ω_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f(ω(1)) = ω_1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(ω(X)) = X⋅ ω_1 + (1 - X) ⋅ ω_2 + \mathrm{Z}_{{0,1}}(X)⋅ q(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{Z}_{{0,1}}(X) = X^2-X&lt;&#x2F;span&gt; is the polynomial that is zero on &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Evaluate in random &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; and have a error term &lt;span class=&quot;math math-inline&quot;&gt;\vec e = f(ω(r)) = q(r)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;New instance &lt;span class=&quot;math math-inline&quot;&gt;(w; \vec e, \vec w)&lt;&#x2F;span&gt; st. &lt;span class=&quot;math math-inline&quot;&gt;w = \P(\vec w)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f(\vec w) = \vec e&lt;&#x2F;span&gt;. Interpolate&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
ε(X) &amp;amp;= X⋅\vec e_1 + (1 - X) ⋅ \vec e_2 \\
ω(X) &amp;amp;= X⋅\vec w_1 + (1 - X) ⋅ \vec w_2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;New equation is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(ω(X)) = X ⋅ \vec e_1 + (1 - X) ⋅ \vec e_2 + \mathrm{Z}_{{0,1}}(X)⋅ \vec q(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;new instance is &lt;span class=&quot;math math-inline&quot;&gt;(\vec q(r), ω(r))&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Generalizing this, we can pick a set of basis points &lt;span class=&quot;math math-inline&quot;&gt;\mathcal A ⊆ \R&lt;&#x2F;span&gt; and interpolate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
ε(X) &amp;amp;= \sum_{i∈[0,n)} \Z_{\mathcal A\setminus\{a_i\}}(X) ⋅\vec e_i \\
ω(X) &amp;amp;= \sum_{i∈[0,n)} \Z_{\mathcal A\setminus\{a_i\}}(X) ⋅\vec w_i
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f(ω(X)) = ε(X) + \Z_{\mathcal A}(X) ⋅ \vec q(X)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nova-1&quot;&gt;Nova&lt;&#x2F;h3&gt;
&lt;p&gt;At each step the circuit produces commitments to the witness and the cross term.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
w &amp;amp;= \P(\vec w) &amp;amp; d &amp;amp;= \P(\vec d)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;R1&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\zkp{x_0,x_1}{i}{
    asd \\ asd \\ asdas
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;SuperNova generalizes this to allow multiple functions &lt;span class=&quot;math math-inline&quot;&gt;f_i&lt;&#x2F;span&gt; where the previous function selects the applicable next step.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;370&quot;&gt;KST21&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;  Nova: Recursive Zero-Knowledge Arguments from Folding Schemes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1758&quot;&gt;KS22&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; SuperNova.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;552.pdf&quot;&gt;STW23&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; Customizable constraint systems for succinct arguments.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;573&quot;&gt;KS23&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; HyperNova.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;620&quot;&gt;BC23&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; ProtoStar.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;969&quot;&gt;NBS23&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; Revisiting the Nova Proof System on a Cycle of Curves.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1106&quot;&gt;EG23&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; ProtoGalaxy.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;geometryresearch&#x2F;technical_notes&#x2F;blob&#x2F;main&#x2F;sangria_folding_plonk.pdf&quot;&gt;M23&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; Sangria.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1192&quot;&gt;KS232&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; CycleFold.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Maybe&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;333&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1576&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Polynomial Modulo Soundness</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/mod-sound/"/>
        <id>https://2π.com/23/mod-sound/</id>
        
        <content type="html" xml:base="https://2π.com/23/mod-sound/">&lt;h1 id=&quot;polynomial-modulo-soundness&quot;&gt;Polynomial Modulo Soundness&lt;&#x2F;h1&gt;
&lt;p&gt;We want to proof a polynomial modular multiplication (PMM)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A_i(X) ⋅ B_i(X) = R_i(X) \mod P(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;A,B,R&lt;&#x2F;span&gt; are low degree.&lt;&#x2F;p&gt;
&lt;p&gt;We can do this using an auxiliary low-degree polynomial &lt;span class=&quot;math math-inline&quot;&gt;Q_i(X)&lt;&#x2F;span&gt; and evaluating the following in a random point &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A_i(z) ⋅ B_i(z) = Q_i(z) ⋅ P(z) + R_i(z)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To verify many such PMMs we can take a linear combination in a random &lt;span class=&quot;math math-inline&quot;&gt;α&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_i α^i ⋅ A_i(X) ⋅ B_i(X) =  P(z) ⋅ \sum_i α^i ⋅ Q_i(z) + \sum_i α^i ⋅ R_i(z)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question&lt;&#x2F;strong&gt; Can the prover pre-sum the quotients? I.e. have an auxiliary low-degree polynomial &lt;span class=&quot;math math-inline&quot;&gt;Q(X)&lt;&#x2F;span&gt; and check:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_i α^i ⋅ A_i(X) ⋅ B_i(X) =  P(z) ⋅ Q(z) + \sum_i α^i ⋅ R_i(z)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;A_i, B_i, R_i, Q&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; low-degree polynomials that satisfy the above equation. We want to show the only solution is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(X) = \sum_i α^i ⋅ Q_i(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q_i(X) = \frac{A_i(X) ⋅ B_i(X) - R_i(X)}{P(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We know that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(X) = \frac{\sum_i α^i ⋅ (A_i(X) ⋅ B_i(X) - R_i(X) )}{P(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So this amounts to proving&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\sum_i α^i ⋅ (A_i(X) ⋅ B_i(X) - R_i(X) )}{P(X)} = \sum_i α^i ⋅ \frac{A_i(X) ⋅ B_i(X) - R_i(X)}{P(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s assume that between &lt;span class=&quot;math math-inline&quot;&gt;A_i(X) ⋅ B_i(X) - R_i(X)&lt;&#x2F;span&gt; there are enough degrees of freedom that these can be arbitrary polynomials &lt;span class=&quot;math math-inline&quot;&gt;D_i(X)&lt;&#x2F;span&gt; of degree &lt;span class=&quot;math math-inline&quot;&gt;2⋅d&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\sum_i α^i ⋅ D_i(X)}{P(X)} = \sum_i α^i ⋅ \frac{D_i(X)}{P(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Oblivious RAM</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/oblivious-ram/"/>
        <id>https://2π.com/23/oblivious-ram/</id>
        
        <content type="html" xml:base="https://2π.com/23/oblivious-ram/">&lt;h1 id=&quot;oblivious-ram&quot;&gt;Oblivious RAM&lt;&#x2F;h1&gt;
&lt;p&gt;Assume we can execute a program in a trusted environment (TEE), but we have only a limited amount of memory locally. We do have access to a lot of external memory, but this is not trusted.&lt;&#x2F;p&gt;
&lt;p&gt;As a first step, we can generate a private key in the TEE and use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Authenticated_encryption&quot;&gt;authenticating encryption&lt;&#x2F;a&gt; to make it so only the TEE can read and write external memory (in this context referred to as RAM). Encrypting the&lt;&#x2F;p&gt;
&lt;p&gt;To make this efficient we encrypt individual pages of e.g. &lt;span class=&quot;math math-inline&quot;&gt;4\ \mathrm{kB}&lt;&#x2F;span&gt;. This allows us to efficiently read and write individual pages of memory,&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Oblivious_RAM&lt;&#x2F;p&gt;
&lt;h2 id=&quot;linear-scan&quot;&gt;Linear scan&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;simple-oram&quot;&gt;Simple ORAM&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;243&quot;&gt;CP13&lt;&#x2F;a&gt; present a simple scheme&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ring-oram&quot;&gt;Ring ORAM&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;997&lt;&#x2F;p&gt;
&lt;h2 id=&quot;circuit-oram&quot;&gt;Circuit ORAM&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;path-oram&quot;&gt;Path ORAM&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;mc-oblivious-ram&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=jGr7Nj3KJ3c&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;odslib&#x2F;EnigMap&#x2F;tree&#x2F;main&#x2F;ods&#x2F;oram&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Polynomial Ring</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/poly-ring/"/>
        <id>https://2π.com/23/poly-ring/</id>
        
        <content type="html" xml:base="https://2π.com/23/poly-ring/">&lt;h1 id=&quot;polynomial-ring&quot;&gt;Polynomial Ring&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\set#1{\delim\{{#1}\}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a commutative ring with unity &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;. The polynomial ring &lt;span class=&quot;math math-inline&quot;&gt;R[X]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Characterizing the underlying set of this ring is surprisingly difficult. Start with the set of infinite sequences with elements in &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; (denoted &lt;span class=&quot;math math-inline&quot;&gt;R^ω&lt;&#x2F;span&gt;) and restrict it to sequences that have a finite non-zero prefix:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
R[X] = \set{\p{s_0, s_1, s_2, …} ∈ R^ω : \exists_{n ∈ ℕ}\ \forall_{i &amp;gt; n}\ s_i = 0}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Elements of this set are called &lt;strong&gt;polynomials&lt;&#x2F;strong&gt;. For a given polynomial &lt;span class=&quot;math math-inline&quot;&gt;p∈R[X]&lt;&#x2F;span&gt; the minimal &lt;span class=&quot;math math-inline&quot;&gt;n ∈ ℕ&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\forall_{i &amp;gt; n}\ p_i = 0&lt;&#x2F;span&gt; is called the &lt;strong&gt;degree&lt;&#x2F;strong&gt; of &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; also denoted &lt;span class=&quot;math math-inline&quot;&gt;\deg p&lt;&#x2F;span&gt;. The &lt;strong&gt;zero polynomial&lt;&#x2F;strong&gt; is &lt;span class=&quot;math math-inline&quot;&gt;\p{0,0,…}&lt;&#x2F;span&gt; has degree &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; and is the only polynomial where &lt;span class=&quot;math math-inline&quot;&gt;p_{\deg p} = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;addition&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;+:R[X]×R[X]→R[X]&lt;&#x2F;span&gt; is defined element-wise using addition from &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p + q = \p{p_0 + q_0, p_1 + q_1, …, p_i + q_i, …}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;multiplication&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;⋅:R[X]×R[X]→R[X]&lt;&#x2F;span&gt; is defined as a convolution&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p⋅q  = \p{p_0⋅q_0, p_0⋅q_1 + p_1⋅q_0, …, \sum_{j∈[0,i]} p_{j}⋅q_{i-j}, …}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Under these operations polynomials are a ring.&lt;&#x2F;p&gt;
&lt;p&gt;There is a monomorphism &lt;span class=&quot;math math-inline&quot;&gt;R→R[X]&lt;&#x2F;span&gt; that maps &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; to constants &lt;span class=&quot;math math-inline&quot;&gt;a ↦ \p{a,0,0,…}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Scalar multiplication &lt;span class=&quot;math math-inline&quot;&gt;⋅:R×R[X]→R[X]&lt;&#x2F;span&gt; is defined with the monomorphism as &lt;span class=&quot;math math-inline&quot;&gt;\p{a,p} ↦ \p{a,0,0,…}⋅p&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;With this operation polynomials are a vector space.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;evaluation&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{apply}:R[X]×R→R&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{p,a} ↦ \sum_{i∈ℕ} p_i ⋅ a^i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;composition&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;∘:R[X]×R[X]→R[X]&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{p,q} ↦ \sum_{i∈ℕ} p_i ⋅ a^i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;linear operator&lt;&#x2F;strong&gt; is a function &lt;span class=&quot;math math-inline&quot;&gt;f:M → M&lt;&#x2F;span&gt; is an endomorphism of a module.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;derivation&lt;&#x2F;strong&gt; on a ring is a linear operator on the underlying module that satisfies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a ⋅ b) = a⋅f(b) + f(a)⋅ b
&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;strong&gt;derivative&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\partial: R[X]→R[X]&lt;&#x2F;span&gt; is defined as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\partial p  = \p{p_1, 2⋅p_2, …, \p{i+1}⋅p_{i+1},…}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;todo: This requires &lt;span class=&quot;math math-inline&quot;&gt;ℕ→R&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;All derivations have the form &lt;span class=&quot;math math-inline&quot;&gt;a⋅\partial + b&lt;&#x2F;span&gt; (in operator notation).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;modular reduction&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;+:R[X]×R[X]→R[X]&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The User Experience of Transaction Confirmation</title>
        <published>2024-06-28T00:00:00+00:00</published>
        <updated>2024-06-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/user-agent/"/>
        <id>https://2π.com/23/user-agent/</id>
        
        <content type="html" xml:base="https://2π.com/23/user-agent/">&lt;h1 id=&quot;the-user-experience-of-transaction-confirmation&quot;&gt;The User Experience of Transaction Confirmation&lt;&#x2F;h1&gt;
&lt;p&gt;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=35845540&lt;&#x2F;p&gt;
&lt;p&gt;Why the web is friendly and web3 isn&#x27;t.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;&#x2F;h2&gt;
&lt;p&gt;Operations in an application generally work like this:
![[Decentralized Consent 2023-05-01 10.04.07.excalidraw|600]]
The &lt;em&gt;user&lt;&#x2F;em&gt; interacts with the digital world through a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;User_agent&quot;&gt;&lt;em&gt;user agent&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;. The user agent is typically a web browser, but could also be a native app. In the decentralized web the user agent also has a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cryptocurrency_wallet&quot;&gt;&lt;em&gt;wallet&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. The wallet is either embedded in, alongside, or instead of a web browser. The wallet is necessary to add support for certain cryptographic operations and network protocols.&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;The term &lt;em&gt;user agent&lt;&#x2F;em&gt; is imho underutilized. Official definitions can be found in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc9110.html#name-user-agents&quot;&gt;RFC 9110&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;WAI&#x2F;UA&#x2F;work&#x2F;wiki&#x2F;Definition_of_User_Agent&quot;&gt;W3C&lt;&#x2F;a&gt;, but the term predates HTTP and likely the internet itself. It refers broadly to any software the user uses to generate network requests and related utilities. This certainly covers wallets, including hardware wallets. I would argue that wallets are particular strong examples&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;A &lt;em&gt;service&lt;&#x2F;em&gt; is any external state that relates to the user. Examples are&lt;&#x2F;p&gt;
&lt;p&gt;An &lt;em&gt;application&lt;&#x2F;em&gt; is a user interface.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;web2&quot;&gt;Web2&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[!tldr]&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;tightly integrated application and services,&lt;&#x2F;li&gt;
&lt;li&gt;hierarchy of trust to authenticate,&lt;&#x2F;li&gt;
&lt;li&gt;empowered vendors.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In web2 the vendor is in charge. It&#x27;s the user-&lt;em&gt;focused&lt;&#x2F;em&gt; web.
In the web2 world the user agent is a web browser and the application and service are build by the same vendor. The application communicates with the user agent using the extensive and well known web standards. Should a third-party service be required this can be implemented by&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;linking directly to the application. This is trusted because the third-party application will interact directly with the user agent. Technically this is implemented using a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;HTTP_cookie#Session_management&quot;&gt;session cookie&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;OAuth&quot;&gt;OAuth&lt;&#x2F;a&gt; to authorize the first party service to directly interact with the the third party service on the users behalf. Note that to set up the authorization the above direct link method is used. The first party service often also needs to register and be approved by the third party service.&lt;&#x2F;li&gt;
&lt;li&gt;using hacky work-around solutions like Plaid.
Authenticity of the application and services is achieved using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Public_key_infrastructure&quot;&gt;public key infrastructure&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;web-2-trust-model&quot;&gt;Web 2 trust model&lt;&#x2F;h4&gt;
&lt;p&gt;The user trusts their browser to implement the standards correctly, and therefore to present the applications as intended by the vendor.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;web3&quot;&gt;Web3&lt;&#x2F;h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[!tldr]&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;decoupling of application and services,&lt;&#x2F;li&gt;
&lt;li&gt;removal of entry barriers, and&lt;&#x2F;li&gt;
&lt;li&gt;empowered user (agents).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In web3 the user is in charge. This puts substantially more emphasis on the user agent. It&#x27;s the user-&lt;em&gt;centered&lt;&#x2F;em&gt; web.
In the web3 world a number of things are different:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;we do not want to trust the existing public key infrastructure.
&lt;ul&gt;
&lt;li&gt;It is centralized by design, see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Public_key_infrastructure#Criticism&quot;&gt;criticism&lt;&#x2F;a&gt; and also the needless complexity of the TLS&#x2F;x509 protocols.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;anyone should be free to develop a new application on top of existing services without prior approval of the service.&lt;&#x2F;li&gt;
&lt;li&gt;services and applications can be developed by anonymous vendors.&lt;&#x2F;li&gt;
&lt;li&gt;User in control, and user as developer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Consequently&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;can not trust application or service&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Jon Stokes (2022). &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;thenetworkstate.com&#x2F;the-billion-user-table&#x2F;&quot;&gt;The Billion User Table&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In an ideal decentralized system, all these components can be permissionlessly replaced. The users ate free to use a user agent of their choice and user
Developers are free to build new applications on top of existing services.&lt;&#x2F;p&gt;
&lt;p&gt;WorldID requires users to generate a proof using their &lt;em&gt;identity key&lt;&#x2F;em&gt;, an &lt;em&gt;external nullifier&lt;&#x2F;em&gt; and a &lt;em&gt;signal&lt;&#x2F;em&gt;. The resulting proof authorizes a particular action to be taken. These actions are potentially high value and it is important that the user understands exactly what they are about to proof.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Phishing.&lt;&#x2F;strong&gt; Given a high value app ‘ImportantApp’, an attacker could phis by creating a ‘FunnyApp’ that uses the same external nullifier. The user would be tricked into generating a proof for FunnyApp that ostensibly authorizes an innocent desirable action. However, due to the set up this proof also authorizes a mallicious action in ImportantApp. The attacker can have the user send the proof directly to ImportantApp or have it send to FunnyApp, but then replay it in ImportantApp.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Analogy with Signing.&lt;&#x2F;strong&gt; This is basically the &lt;code&gt;eth_sign&lt;&#x2F;code&gt; problem as discussed in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-712&quot;&gt;EIP-712&lt;&#x2F;a&gt; but with &lt;em&gt;identity key&lt;&#x2F;em&gt;, an &lt;em&gt;external nullifier&lt;&#x2F;em&gt;, &lt;em&gt;signal&lt;&#x2F;em&gt; and &lt;em&gt;proving&lt;&#x2F;em&gt; substituted for &lt;em&gt;private key&lt;&#x2F;em&gt;, &lt;em&gt;domain separator&lt;&#x2F;em&gt;, &lt;em&gt;message&lt;&#x2F;em&gt; and &lt;em&gt;signing&lt;&#x2F;em&gt; respectively.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Human readable.&lt;&#x2F;strong&gt; Making it machine readable can be done by making the domain separator commit to a schema for the message. This can get us from a binary string to structured data. Structured data (think JSON) is not a format most users can grok.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Internationalization.&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;App implementer freedom of implementation (potentially updatable)
*&lt;&#x2F;li&gt;
&lt;li&gt;Multi media.
&lt;ul&gt;
&lt;li&gt;Support web wallets, mobile wallets and hardware wallets.
&lt;ul&gt;
&lt;li&gt;Mobile wallets can display interactive UI elements, have graphics links etc.&lt;&#x2F;li&gt;
&lt;li&gt;Web wallets&lt;&#x2F;li&gt;
&lt;li&gt;Ledger nano can only show a short single line ascii string.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Implementer freedom to optimize user experience.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;ideas&quot;&gt;Ideas&lt;&#x2F;h3&gt;
&lt;p&gt;We need a function like &lt;code&gt;(context, message: bytes, modality) -&amp;gt; user_interface&lt;&#x2F;code&gt; where&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;context&lt;&#x2F;code&gt; can be empty, contain the domain separator, or further information about the user.
&lt;ul&gt;
&lt;li&gt;Q: What kind of context information would be useful? What are the privacy implications of including it?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;message&lt;&#x2F;code&gt; is the actual data to be signed, for which we need a user-readable representation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;modality&lt;&#x2F;code&gt; which specified what kind of UI is expected, i.e. which language and wheter we want a short line of text for use in ledger nano or a full mobile&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This function is not necessarily a pure function and may do further lookups like pulling in the proposol to be voted on to get descriptive texts of the proposal and the choices. It should not mutate any state. (&lt;strong&gt;Aside:&lt;&#x2F;strong&gt; the signed messages themselves should be idempotent.)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Have the domain separator contain one of
&lt;ul&gt;
&lt;li&gt;a contract address with a function &lt;code&gt;(message: bytes, locality) -&amp;gt; string&lt;&#x2F;code&gt;.
&lt;ul&gt;
&lt;li&gt;The contract could be an upgradable proxy.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;a domain name with a record containing a contract address that implements the above.&lt;&#x2F;li&gt;
&lt;li&gt;a url to an RPC endpoint implementing &lt;code&gt;(message: bytes, locality) -&amp;gt; string&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Have th&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;issue&quot;&gt;Issue&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;worldcoin&#x2F;world-id-contracts&#x2F;security&#x2F;advisories&#x2F;GHSA-22v7-gcvp-q364&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sub-problems&quot;&gt;Sub problems&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-how-to-retrieve-required-information-securely&quot;&gt;1. How to retrieve required information securely.&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;2-how-to-encode-the-required-information&quot;&gt;2. How to encode the required information.&lt;&#x2F;h3&gt;
&lt;p&gt;This requires input&lt;&#x2F;p&gt;
&lt;h2 id=&quot;solutions-to-problem-1&quot;&gt;Solutions to problem #1.&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-hardcoded-list&quot;&gt;1. Hardcoded list&lt;&#x2F;h3&gt;
&lt;p&gt;The easiest immediate solution is for the wallet to have a hardcoded list of domain separators and their meta data. This can be fetched from a back end so we can updated it without having to go through an app-update. This is the process Metamask uses for tokens (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MetaMask&#x2F;core&#x2F;blob&#x2F;99df8b577b2931f8fda5ce4494ac5878862b2086&#x2F;packages&#x2F;assets-controllers&#x2F;src&#x2F;token-service.ts&quot;&gt;source&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;token-api.metaswap.codefi.network&#x2F;tokens&#x2F;1&quot;&gt;main net list&lt;&#x2F;a&gt;). (This is how we do it currently. https:&#x2F;&#x2F;github.com&#x2F;worldcoin&#x2F;developer-portal https:&#x2F;&#x2F;docs.worldcoin.org&#x2F;  Sync with Paolo).&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Q: How does wallet connect do this curation?
This requires us to approve each new domain separator. We can make this process more transparent by maintaining the list in a public Github repo and inviting developers to submit PRs. This is how Uniswap manages the default list of token addresses, see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Uniswap&#x2F;default-token-list&quot;&gt;uniswap&#x2F;default-token-list&lt;&#x2F;a&gt;.
Tokens are easy, all that is needed is a basic trusted metadata like a name, description and an icon everything else is standardized in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-20&quot;&gt;ERC-20&lt;&#x2F;a&gt;. The WorldID protocol is more complex. A &lt;em&gt;message&lt;&#x2F;em&gt; is nearly always required, if only for replay protection. For airdrops the message contains the token recipient. For voting applications the message would contain the choice made. Other applications will have their own requirements.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;2-curation-lists&quot;&gt;2. Curation lists&lt;&#x2F;h3&gt;
&lt;p&gt;The previous approach makes the wallet developer a gatekeeper for applications, which we&#x27;d like to avoid. Again following Uniswap&#x27;s lead, we can set a standard for curated metadata similar to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tokenlists.org&#x2F;&quot;&gt;tokenlists&lt;&#x2F;a&gt;. Anyone can then
This does raise the question of &quot;Who curates the curated lists?&quot;. Uniswap &#x27;solved&#x27; this with another public Github repo: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Uniswap&#x2F;tokenlists-org&#x2F;blob&#x2F;master&#x2F;src&#x2F;token-lists.json&quot;&gt;uniswap&#x2F;tokenlists-org&lt;&#x2F;a&gt;. Though for their swap front-end they opted to hardcode a list of lists (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Uniswap&#x2F;interface&#x2F;blob&#x2F;4c664645c6dcc45a5139c43a40a3bcf57a76ab66&#x2F;src&#x2F;constants&#x2F;lists.ts&quot;&gt;source&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;3-contract-supplied-metadata&quot;&gt;3. Contract supplied metadata&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;May want to limit which contract can receive the proof and which websites can request them.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;How many verified external nullifiers: less than a thousand.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Unverified &#x2F; experiments &#x2F; tests: more, maybe 10k.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;External nullifier use-cases.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Airdrops,&lt;&#x2F;li&gt;
&lt;li&gt;Log in (OAuth),&lt;&#x2F;li&gt;
&lt;li&gt;Proof of personhood.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Do we want alternative metadata?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;solutions-to-problem-2&quot;&gt;Solutions to problem #2&lt;&#x2F;h2&gt;
&lt;p&gt;Check out existing work.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Preprocessing Bilinear Algorithms</title>
        <published>2024-06-24T00:00:00+00:00</published>
        <updated>2024-06-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/prep-bilinear/"/>
        <id>https://2π.com/24/prep-bilinear/</id>
        
        <content type="html" xml:base="https://2π.com/24/prep-bilinear/">&lt;h1 id=&quot;preprocessing-bilinear-algorithms&quot;&gt;Preprocessing Bilinear Algorithms&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\vec#1{\mathbf#1}
\gdef\mat#1{\mathrm#1}
\gdef\p#1{\left({#1}\right)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Giver vector spaces &lt;span class=&quot;math math-inline&quot;&gt;u,V,T&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;, any bilinear map &lt;span class=&quot;math math-inline&quot;&gt;U × V → T&lt;&#x2F;span&gt; can be uniquely represented using a rank-3 tensor over &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
b(\vec u, \vec v) = \sum_{ijk} u_i ⋅ v_j ⋅ t_{ijk} ⋅ \vec e_k
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;provided a basis for all three spaces.&lt;&#x2F;p&gt;
&lt;p&gt;Examples of bilinear maps are plentiful: dot products, polynomial multiplication, convolutions, matrix multiplication, etc.&lt;&#x2F;p&gt;
&lt;p&gt;Often we want to minimize the number of non-constant multiplications needed to compute a bilinear map. We can make the required number explicit using the &lt;em&gt;bilinear algorithms&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
b(\vec a, \vec b) = \mat C ⋅ \left( (\mat A ⋅ \vec a) ⊙ (\mat B ⋅ \vec b) \right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For example for dot products &lt;span class=&quot;math math-inline&quot;&gt;A, B&lt;&#x2F;span&gt; are identity matrices and &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; is a row vector of all ones, i.e. for a 2-dimensional dot product:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec a ⋅ \vec b = 
\begin{bmatrix} 1 &amp;amp; 1 \end{bmatrix} ⋅ \p{ \p{
\begin{bmatrix} 1 &amp;amp; 0  \\ 0 &amp;amp; 1 \end{bmatrix} ⋅ \vec a }
⊙ \p{\begin{bmatrix} 1 &amp;amp; 0 \\ 0 &amp;amp; 1 \end{bmatrix} ⋅ \vec b}}
&lt;&#x2F;span&gt;
This shows that two multiplications are required. But we can actually do this in one multiplication! We just need to precompute some values depending only on &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_0 ⋅ b_0 + a_1 ⋅ b_1 = (a_0 + b_1) ⋅ (a_1 + b_0) - a_0 ⋅ a_1 - b_0 ⋅ b_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is useful, but it can not be captured in the format of bilinear algorithms. So we generalize it by allowing intra-input products:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat C ⋅ \p{ \p {
\mat A ⋅
\begin{bmatrix} \vec a \\ \vec b \end{bmatrix}
} ⊙ \p{ 
\mat B ⋅
\begin{bmatrix} \vec a \\ \vec b \end{bmatrix} } }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;By sorting the rows we can create the form&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix} 
\mat C_a &amp;amp; \mat C_b  &amp;amp; \mat C_{ab}
\end{bmatrix} ⋅ \p{ \p {
\begin{bmatrix}
    \begin{matrix}
    \mat A_a &amp;amp; 0 \\
    0 &amp;amp; \mat A_b \\
    \end{matrix} \\\hline
    \mat A_{ab}
\end{bmatrix} ⋅
\begin{bmatrix} \vec a \\ \vec b \end{bmatrix}
} ⊙ \p{ 
\begin{bmatrix}
    \begin{matrix}
    \mat B_a &amp;amp; 0 \\
    0 &amp;amp; \mat B_b \\
    \end{matrix} \\\hline
    \mat B_{ab}
\end{bmatrix} ⋅
    \begin{bmatrix} \vec a \\ \vec b \end{bmatrix} } }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where the matrix dimensions are
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mat A_a, \mat B_a &amp;amp;: r_a × n_a  &amp;amp; \mat C_a &amp;amp;: n_c × r_a \\
\mat A_b, \mat B_b &amp;amp;: r_b × n_b  &amp;amp; \mat C_b &amp;amp;: n_c × r_b \\
\mat A_{ab}, \mat B_{ab} &amp;amp;: r_{ab} × (n_a + n_b) &amp;amp; \mat C_{ab} &amp;amp;: n_c × r_{ab}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can precompute the two vectors (using &lt;span class=&quot;math math-inline&quot;&gt;r_a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r_b&lt;&#x2F;span&gt; multiplications):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\vec c_a &amp;amp;= \mat C_a ⋅ \p{ (\mat A_a ⋅ \vec a)  ⊙ (\mat B_a ⋅ \vec a) } \\
\vec c_b &amp;amp;= \mat C_b ⋅ \p{ (\mat A_b ⋅ \vec b)  ⊙ (\mat B_b ⋅ \vec b) }
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and then the bilinear map is computed with &lt;span class=&quot;math math-inline&quot;&gt;r_{ab}&lt;&#x2F;span&gt; multiplications:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
b(\vec a, \vec b) =
\vec c_a + \vec c_b +
\mat C_{ab} ⋅ \p{ \p {
\mat A_{ab} ⋅
\begin{bmatrix} \vec a \\ \vec b \end{bmatrix}
} ⊙ \p{ 
\mat B_{ab} ⋅
\begin{bmatrix} \vec a \\ \vec b \end{bmatrix} } }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The motivating example above has &lt;span class=&quot;math math-inline&quot;&gt;r_a = r_b = r_{ab} = 1&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix} -1 &amp;amp; -1 &amp;amp; 1 \end{bmatrix}
⋅ \p{ \p {
\begin{bmatrix}
    1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0  \\
    0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0  \\
    1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1  \\
\end{bmatrix} ⋅
\begin{bmatrix} a_0 \\ a_1 \\ b_0 \\ b_1 \end{bmatrix}
} ⊙ \p{ 
\begin{bmatrix}
    0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0  \\
    0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1  \\
    0 &amp;amp; 1 &amp;amp; 1 &amp;amp; 0  \\
\end{bmatrix} ⋅
\begin{bmatrix} a_0 \\ a_1 \\ b_0 \\ b_1 \end{bmatrix}
} }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This formalism is more generic than bilinear maps, it can also include quadratic forms of the input vectors. To restrict it to bilinear maps we need some further constraints on the matrices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Which constraints? We can collect coefficients of &lt;span class=&quot;math math-inline&quot;&gt;a_i⋅a_j&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b_i⋅b_j&lt;&#x2F;span&gt; and require that they sum to zero.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;square-algorithms&quot;&gt;Square algorithms&lt;&#x2F;h3&gt;
&lt;p&gt;Every Bilinear Algorithm of rank &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; can be turned into one requiring only &lt;span class=&quot;math math-inline&quot;&gt;2⋅r&lt;&#x2F;span&gt; squarings if &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt; is invertible:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
2 ⋅ a ⋅ b = (a + b)^2 - (a - b)^2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Approximate Fraction Matching</title>
        <published>2024-06-22T00:00:00+00:00</published>
        <updated>2024-06-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/farey-approx/"/>
        <id>https://2π.com/24/farey-approx/</id>
        
        <content type="html" xml:base="https://2π.com/24/farey-approx/">&lt;h1 id=&quot;approximate-fraction-matching&quot;&gt;Approximate Fraction Matching&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; We need to compare a fraction &lt;span class=&quot;math math-inline&quot;&gt;\frac{a}{b} &amp;lt; t&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;0 \leq a \leq b \leq 12\,800&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;t\in[0,1]&lt;&#x2F;span&gt;. We want to approximate &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; by a fraction &lt;span class=&quot;math math-inline&quot;&gt;\hat{t} = \frac{c}{d \cdot p}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;p = 65\,519&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;d \cdot p &amp;lt; 2^{32}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The approximation error is the maximum observable discrepancy.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\max \vert \frac{a}{b} - \hat{t} \vert
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; What are the optimal values of &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;, such that&lt;&#x2F;p&gt;
&lt;p&gt;Without loss of generality we can assume &lt;span class=&quot;math math-inline&quot;&gt;t \in F_n&lt;&#x2F;span&gt;, as we can always round &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; up to the nearest value (and handle &lt;span class=&quot;math math-inline&quot;&gt;t=1&lt;&#x2F;span&gt; as a special case) without affecting the comparison.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;farey-sequences&quot;&gt;Farey Sequences&lt;&#x2F;h2&gt;
&lt;p&gt;Consider all distinct fractions in &lt;span class=&quot;math math-inline&quot;&gt;[0,1]&lt;&#x2F;span&gt; with denominators up to &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. When ordered these form the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Farey_sequence&quot;&gt;Farey seqeunce&lt;&#x2F;a&gt; of order &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, the values of which are:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
F_n = \left\{ (a,b) \mid 0 ≤ a ≤ b ≤ n ∧ \gcd(a,b) = 1 \right\}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some interesting results are known, for example&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vert F_n \vert = 1 + \sum_{i\in[1,n]} φ(i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Euler%27s_totient_function&quot;&gt;Euler&#x27;s totient function&lt;&#x2F;a&gt;. There is also a surprisingly simple algorithm to generate the sequence:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; farey_sequence&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; descending&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; False&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; descending&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    yield&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        yield&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Dot products in Galois rings</title>
        <published>2024-06-22T00:00:00+00:00</published>
        <updated>2024-06-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/galois-dot/"/>
        <id>https://2π.com/24/galois-dot/</id>
        
        <content type="html" xml:base="https://2π.com/24/galois-dot/">&lt;h1 id=&quot;dot-products-in-galois-rings&quot;&gt;Dot products in Galois rings&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\vec#1{\mathbf#1}
\gdef\mat#1{\mathrm#1}
\gdef\setn#1{\mathcal#1}
\gdef\p#1{\left({#1}\right)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(These are my notes from studying an idea worked out by Bryan Gillespie)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;galois-rings&quot;&gt;Galois Rings&lt;&#x2F;h2&gt;
&lt;p&gt;Informally, a Galois ring is a generalisation of a Galois field &lt;span class=&quot;math math-inline&quot;&gt;𝔽_{p^m}&lt;&#x2F;span&gt; to have coefficients from the ring of integers modulo &lt;span class=&quot;math math-inline&quot;&gt;p^s&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;s ≥ 1&lt;&#x2F;span&gt;. It inherits much of the structure of the field, and many applications of Galois fields can be generalized to work on Galois rings. This is useful as &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; can be efficiently implemented on computers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;definition-existence-and-uniqueness&quot;&gt;Definition, existence and uniqueness&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.1&lt;&#x2F;strong&gt;) A &lt;em&gt;Galois ring&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is a finite commutative ring with identity such that that the set of its zero divisors with &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; added forms a principal ideal &lt;span class=&quot;math math-inline&quot;&gt;(p)&lt;&#x2F;span&gt; for some prime number &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.2&lt;&#x2F;strong&gt;) The unique maximal ideal of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;(p)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p)&lt;&#x2F;span&gt; is the Galois field &lt;span class=&quot;math math-inline&quot;&gt;𝔽_{p^m}&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;m≥1&lt;&#x2F;span&gt;. The characteristic of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;p^s&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;s ≥ 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.7&lt;&#x2F;strong&gt;) &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is uniquely determined (up to isomorphism) by &lt;span class=&quot;math math-inline&quot;&gt;(p,s,m)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.4&lt;&#x2F;strong&gt;) The cardinality &lt;span class=&quot;math math-inline&quot;&gt;|R|=p^{s⋅m}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;13.9&lt;&#x2F;strong&gt;) For any prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;s ≥ 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m ≥ 1&lt;&#x2F;span&gt; there exists a Galois ring.&lt;&#x2F;p&gt;
&lt;p&gt;We can therefore speak of &lt;em&gt;the&lt;&#x2F;em&gt; Galois ring &lt;span class=&quot;math math-inline&quot;&gt;GR(p^s, m)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;multiplicative-group&quot;&gt;Multiplicative group&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.9&lt;&#x2F;strong&gt;) The group of units &lt;span class=&quot;math math-inline&quot;&gt;R^×&lt;&#x2F;span&gt; has order &lt;span class=&quot;math math-inline&quot;&gt;|R^×| = (p^m - 1)⋅p^{(s-1)⋅m}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; An element &lt;span class=&quot;math math-inline&quot;&gt;a ∈ R&lt;&#x2F;span&gt; is a unit if and only if its equivalence class in &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p)=𝔽_{p^s}&lt;&#x2F;span&gt; does not equal &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;From this follows a simple method to compute inverses by first testing the reduction mod &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; against zero and exponentiating the element by &lt;span class=&quot;math math-inline&quot;&gt;|R^×|-1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; has order &lt;span class=&quot;math math-inline&quot;&gt;(p^m - 1)⋅p^{s-1}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;structure&quot;&gt;Structure&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.6&lt;&#x2F;strong&gt;) &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is isomorphic to the ring &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}[x] &#x2F; (h(x))&lt;&#x2F;span&gt; for any monic basic polynomial &lt;span class=&quot;math math-inline&quot;&gt;h(x)&lt;&#x2F;span&gt; of degree &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In particular if &lt;span class=&quot;math math-inline&quot;&gt;s=1&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;R ≃ 𝔽_{p^m}&lt;&#x2F;span&gt; and if &lt;span class=&quot;math math-inline&quot;&gt;m = 1&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;R ≃ ℤ_{p^s}&lt;&#x2F;span&gt;. As such Galois rings generalize over finite fields and integers modulo a prime power. Of particular interest are cases where &lt;span class=&quot;math math-inline&quot;&gt;p=2&lt;&#x2F;span&gt; which have efficient implementations.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.1&lt;&#x2F;strong&gt;) &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is a free &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}&lt;&#x2F;span&gt;-module of rank &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; ex. 14.1 p. 367) For &lt;span class=&quot;math math-inline&quot;&gt;1 ≤ r &amp;lt; s&lt;&#x2F;span&gt; the quotient ring &lt;span class=&quot;math math-inline&quot;&gt;R&#x2F;(p^r)&lt;&#x2F;span&gt; is isomorphic to &lt;span class=&quot;math math-inline&quot;&gt;GR(p^r, m)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.24&lt;&#x2F;strong&gt;) For a positive divisor &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; contains a unique subring &lt;span class=&quot;math math-inline&quot;&gt;GR(p^s, n)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;addic-representation&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;-addic representation&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Theorem&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.8&lt;&#x2F;strong&gt;) There exist a &lt;span class=&quot;math math-inline&quot;&gt;ω ∈ R&lt;&#x2F;span&gt; of order &lt;span class=&quot;math math-inline&quot;&gt;p^m -1&lt;&#x2F;span&gt; which is a root of a monic basic primitive polynomial &lt;span class=&quot;math math-inline&quot;&gt;h(x)&lt;&#x2F;span&gt; of degree &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}&lt;&#x2F;span&gt; and dividing &lt;span class=&quot;math math-inline&quot;&gt;x^{p^m -1}-1&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}[x]&lt;&#x2F;span&gt;. Let
&lt;span class=&quot;math math-display&quot;&gt;
\setn T = \{0, 1, ω, ω^2, …, ω^{p^m - 2}\}
&lt;&#x2F;span&gt;
be the set of then every element of &lt;span class=&quot;math math-inline&quot;&gt;c ∈ R&lt;&#x2F;span&gt; can be written uniquely in the form
&lt;span class=&quot;math math-display&quot;&gt;
c = c_0 + c_1 ⋅ p + c_2 ⋅p^2 + ⋯ + c_{s-1} ⋅ p^{s-1}
&lt;&#x2F;span&gt;
where &lt;span class=&quot;math math-inline&quot;&gt;c_i ∈ \setn T&lt;&#x2F;span&gt;. Moreover &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; is a unit if and only if &lt;span class=&quot;math math-inline&quot;&gt;c_0 ≠ 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; is a zero divisor or &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; if and only if &lt;span class=&quot;math math-inline&quot;&gt;c_0 = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;\setn T&lt;&#x2F;span&gt;, known as the Teichmüller representatives, are a lift from &lt;span class=&quot;math math-inline&quot;&gt;𝔽_{p^m}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;&#x2F;strong&gt; The &lt;em&gt;generalized Frobenius map&lt;&#x2F;em&gt;  takes an element in &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;-addic representations an raises every coefficient to the &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;-th power:
&lt;span class=&quot;math math-display&quot;&gt;
ϕ: c_0 + c_1 ⋅ p + ⋯ + c_{s-1} ⋅ p^{s-1} ↦ c_0^{p} + c_1^{p} ⋅ p + ⋯ + c_{s-1}^{p} ⋅ p^{s-1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.31&lt;&#x2F;strong&gt;) The automorphism group of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is cyclic of order &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and generated by the Frobenius automorphism:
&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{Aut}_{ℤ_{p^s}}(R) = ⟨ϕ⟩
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bases&quot;&gt;Bases&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; The &lt;em&gt;trace&lt;&#x2F;em&gt; of an element &lt;span class=&quot;math math-inline&quot;&gt;a ∈ R&lt;&#x2F;span&gt;, denoted &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Tr}(a)&lt;&#x2F;span&gt; and &lt;em&gt;norm&lt;&#x2F;em&gt;, denoted &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{N}(a)&lt;&#x2F;span&gt; are
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\operatorname{Tr}(a) &amp;amp;= \!\!\!\!\!\sum_{i∈[0,m-1]}\!\!\! ϕ^i(a) &amp;amp;\quad
\operatorname{N}(a) &amp;amp;= \!\!\!\!\!\prod_{i∈[0,m-1]}\!\!\!\! ϕ^i(a) &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.34&lt;&#x2F;strong&gt;)
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\operatorname{Tr}(a) &amp;amp;∈ ℤ_{p^m} \\
\operatorname{Tr}(a + b) &amp;amp;= \operatorname{Tr}(a) + \operatorname{Tr}(b) \\
\operatorname{Tr}(c ⋅ a) &amp;amp;= c⋅\operatorname{Tr}(a) \\
\operatorname{Tr}(c) &amp;amp;= m ⋅ c \\
\operatorname{Tr}(ϕ(a)) &amp;amp;= \operatorname{Tr}(a) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Is &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Tr}(a⋅b)&lt;&#x2F;span&gt; an inner product?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;8.2&lt;&#x2F;strong&gt;) Two bases &lt;span class=&quot;math math-inline&quot;&gt;\set{a_1, a_2, …, a_n}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\set{b_1, b_2, …, b_n}&lt;&#x2F;span&gt; are said to be &lt;em&gt;equivalent&lt;&#x2F;em&gt; if there exist an &lt;span class=&quot;math math-inline&quot;&gt;e ∈ 𝔽_p&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a_i = e⋅b_i&lt;&#x2F;span&gt; and &lt;em&gt;weakly equivalent&lt;&#x2F;em&gt; if there exist and &lt;span class=&quot;math math-inline&quot;&gt;e ∈ R&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a_i = e⋅b_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; What are all the bases of a Galois ring up to permutation and weak equivalence?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;products-in-galois-ring-representations&quot;&gt;Products in Galois Ring Representations&lt;&#x2F;h2&gt;
&lt;p&gt;(See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; p. 164)&lt;&#x2F;p&gt;
&lt;p&gt;Represent &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}[x] &#x2F; h(x)&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;\setn X = \set{ x^i }&lt;&#x2F;span&gt; is the monomial basis that creates an isomorphism with &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}^m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The Frobenius automorphism group &lt;span class=&quot;math math-inline&quot;&gt;ϕ&lt;&#x2F;span&gt; becomes a linear operator and can be represented by a matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat F&lt;&#x2F;span&gt; of order &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; What are all the isomorpisms &lt;span class=&quot;math math-inline&quot;&gt;GR(p^s, m) → ℤ_{p^s}^m&lt;&#x2F;span&gt; that can be constructed? We can change &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt; and change the choice of basis. The result must equal the automorphism group&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{Aut}_{ℤ_{p^s}}(ℤ_{p^s}^m) ≃ \operatorname{GL}_{m}(ℤ_{p^s})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hypothesis.&lt;&#x2F;strong&gt; Changes of basis on &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}[x] &#x2F; h(x)&lt;&#x2F;span&gt; are in one-to-one correspondence with matrices &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{GL}_{m}(ℤ_{p^s})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hypothesis.&lt;&#x2F;strong&gt; The &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}&lt;&#x2F;span&gt;-module automorphisms are also ring homomorphisms by an appropriate transformation of the bilinear map for ring products.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; &lt;strong&gt;14.32&lt;&#x2F;strong&gt;) Given Galois ring &lt;span class=&quot;math math-inline&quot;&gt;R=GR(p^s, m)&lt;&#x2F;span&gt; with subring &lt;span class=&quot;math math-inline&quot;&gt;R&amp;#39;=GR(p^s, n)&lt;&#x2F;span&gt;, the automorphism group of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;R&amp;#39;&lt;&#x2F;span&gt; is isomorphic to the automorphism group over their residue fields.
&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{Aut}_{R&amp;#39;}(R) ≃ \operatorname{Aut}_{𝔽_{p^n}}(𝔽_{p^m})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So every automorphism of a Galois ring is a power of the generalized Frobenius automorphism.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
σ(n) = n^{p^m}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The automorphism group of &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt;, denoted &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Aut}_{A}(B)&lt;&#x2F;span&gt; here following &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt;, is also commonly denoted &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Aut}(B&#x2F; A)&lt;&#x2F;span&gt;. When &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; are Galois fields, this group is typically denoted &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Gal}(B &#x2F; A)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Under this isomorphism the &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-product becomes a symmetric bilinear map &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}^m × ℤ_{p^s}^m → ℤ_{p^s}^m&lt;&#x2F;span&gt;. Such bilinear maps are uniquely characterized by a rank-3 tensor &lt;span class=&quot;math math-inline&quot;&gt;m ∈ ℤ_{p^s}^{m^3}&lt;&#x2F;span&gt; defined by:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x^k ⋅ x^l = \sum_{r} m_{klr} ⋅ x^r
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; values depend on the choice of &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt; and basis.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; values are constraint by the automorphism group as the product needs to satisfy&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a ⋅ b = ϕ^{-k}(ϕ^k(a) ⋅ ϕ^k(b))
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; What are other constraints to make this a valid product? It needs to be bilinear, symmetric. Basically needs to satisfy the ring axioms? Distributivity follows from bilinearity. Missing is identity and associativity. What about compatibility with the scalar product?&lt;&#x2F;p&gt;
&lt;p&gt;The ring product operation is a symmetric bilinear map over the module. Given two bases &lt;span class=&quot;math math-inline&quot;&gt;\setn U = \set{\vec u_i}&lt;&#x2F;span&gt; and  &lt;span class=&quot;math math-inline&quot;&gt;\setn V = \set{\vec v_i}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; we can represent the product in coordinates as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a ⋅ b = \sum_k a^{\setn U}_i ⋅ b^{\setn U}_j ⋅ m_{ijk} ⋅ \vec v_k
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;a^{\setn U}_i, b^{\setn U}_j ∈ ℤ_{p^s}&lt;&#x2F;span&gt; are coordinates of &lt;span class=&quot;math math-inline&quot;&gt;a, b&lt;&#x2F;span&gt; in basis &lt;span class=&quot;math math-inline&quot;&gt;\setn U&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; is a rank-&lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt; tensor over &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}&lt;&#x2F;span&gt; with coordinates given by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
m_{ijk} = (\vec u_i ⋅ \vec u_j)^{\setn V}_k
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Observe that each product coordinate &lt;span class=&quot;math math-inline&quot;&gt;(a ⋅ b)^{\setn V}_k&lt;&#x2F;span&gt; is a symmetric bilinear form on the input coordinates. This let&#x27;s us state our main question:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Which symmetric bilinear forms on &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}^m&lt;&#x2F;span&gt; can be constructed by appropriate choices of &lt;span class=&quot;math math-inline&quot;&gt;\setn U&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\setn V&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;computing-bilinear-forms&quot;&gt;Computing Bilinear Forms&lt;&#x2F;h2&gt;
&lt;p&gt;Without loss of generality we can focus on the first output coordinate &lt;span class=&quot;math math-inline&quot;&gt;\vec v_0&lt;&#x2F;span&gt;. Given a bilinear form &lt;span class=&quot;math math-inline&quot;&gt;\mat B_{ij}&lt;&#x2F;span&gt;, we need&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
m_{ij0} = (\vec u_i ⋅ \vec u_j)^{\setn V}_0 = \delta_{ij}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Represent &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}[x] &#x2F; h(x)&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;\setn X = \set{ x^i }&lt;&#x2F;span&gt; is a basis. We can represent the transformation from &lt;span class=&quot;math math-inline&quot;&gt;\setn X&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\setn U&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\setn V&lt;&#x2F;span&gt; by invertible matrices &lt;span class=&quot;math math-inline&quot;&gt;u_{ij} = (x^i)^{\setn U}_j&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;v_{ij} = (x^i)^{\setn V}_j&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x^k ⋅ x^l = \sum_{r} m_{klr} ⋅ x^r
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the target bases&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec u_i = \sum_j u_{ij} ⋅ x^j
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;u_{ij} = (\vec u_i)^{\setn X}_j&lt;&#x2F;span&gt; and similarly for &lt;span class=&quot;math math-inline&quot;&gt;\setn V&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x^r = \sum_{q} v_{rq} ⋅ \vec v_q
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;v_{rq} = (x^r)^{\setn V}_q&lt;&#x2F;span&gt;. Then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\vec u_i ⋅ \vec u_j &amp;amp;= \p{\sum_k u_{ik} ⋅ x^k} ⋅ \p{\sum_l u_{jl} ⋅ x^l} \\
&amp;amp;= \sum_k \sum_l u_{ik} ⋅ u_{jl} ⋅ \p{x^k ⋅ x^l} \\
&amp;amp;= \sum_k \sum_l \sum_r u_{ik} ⋅ u_{jl} ⋅ m_{klr} ⋅ x^r \\
&amp;amp;= \sum_k \sum_l \sum_r \sum_q u_{ik} ⋅ u_{jl} ⋅ m_{klr} ⋅ v_{rq} ⋅ \vec v_q \\
(\vec u_i ⋅ \vec u_j)^{\setn V}_q &amp;amp;= \sum_k \sum_l \sum_r u_{ik} ⋅ u_{jl} ⋅ m_{klr} ⋅ v_{rq}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a polynomial system of equations in unknowns &lt;span class=&quot;math math-inline&quot;&gt;u_{ij}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;v_{ij}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
u_i^T ⋅ M_r ⋅ u_j
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-the-galois-ring&quot;&gt;Example: the Galois ring &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^{16}}[x] &#x2F; (x^4 -x - 1)&lt;&#x2F;span&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;In &lt;span class=&quot;math math-inline&quot;&gt;R = ℤ_{2^{16}}[x] &#x2F; (x^4 -x - 1)&lt;&#x2F;span&gt; with basis &lt;span class=&quot;math math-inline&quot;&gt;\{ x^i \}&lt;&#x2F;span&gt; we have multiplication represented by structure constants&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c = \begin{bmatrix}\begin{pmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0&amp;amp; 1 \\
\end{pmatrix}, \begin{pmatrix}
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 \\
1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
\end{pmatrix}, \begin{pmatrix}
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 \\
1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 1 &amp;amp; 1 &amp;amp; 0 \\
\end{pmatrix}, \begin{pmatrix}
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 \\
1 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 1 &amp;amp; 1 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 1 \\
\end{pmatrix}
\end{bmatrix}
&lt;&#x2F;span&gt;
such that &lt;span class=&quot;math math-inline&quot;&gt;x^i⋅x^j = \sum_k c_{ij}^k ⋅ x^k&lt;&#x2F;span&gt;. The order of the multiplicative group &lt;span class=&quot;math math-inline&quot;&gt;|R^×| = 2^{60}⋅3⋅5&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{ord}(x) = 2^{15}⋅3⋅5&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; dividing &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{ord}(x)&lt;&#x2F;span&gt; we construct primitive &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-th roots of unity &lt;span class=&quot;math math-inline&quot;&gt;ω_k&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;ω_k = x^\frac{\operatorname{ord}(x)}{k}&lt;&#x2F;span&gt;. In particular the generator of the Teichmüller set is
&lt;span class=&quot;math math-display&quot;&gt;
ω_{2^4-1} = 40289 + 46738⋅x + 59713⋅x^2 + 8880⋅x^3
&lt;&#x2F;span&gt;
and the Frobenius map &lt;span class=&quot;math math-inline&quot;&gt;ϕ&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^{16}}&lt;&#x2F;span&gt; is represented by the matrix
&lt;span class=&quot;math math-display&quot;&gt;
\mat F = \begin{bmatrix}
    1 &amp;amp;     0 &amp;amp;     0 &amp;amp;     0 \\
14104 &amp;amp; 36826 &amp;amp; 23545 &amp;amp;  3040 \\
50161 &amp;amp; 28753 &amp;amp; 57364 &amp;amp; 20500 \\
21492 &amp;amp; 33826 &amp;amp; 19639 &amp;amp; 36881
\end{bmatrix}
&lt;&#x2F;span&gt;
such that &lt;span class=&quot;math math-inline&quot;&gt;ϕ(x^i) = \sum_j \mat F_{ij} ⋅ x^j&lt;&#x2F;span&gt;. &lt;span class=&quot;math math-inline&quot;&gt;\mat F&lt;&#x2F;span&gt; generates the automorphism group of the ring. The automorphism group of the module is the general linear group &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{GL}_4(ℤ_{2^{16}})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
(\vec u_i ⋅ \vec u_j)^{\setn V}_q &amp;amp;= \sum_k \sum_l \sum_r u_{ik} ⋅ u_{jl} ⋅ m_{klr} ⋅ v_{rq} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So we need to solve&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
δ_{ij} = \sum_k \sum_l \sum_r u_{ik} ⋅ u_{jl} ⋅ m_{klr} ⋅ v_{r0}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the lhs and &lt;span class=&quot;math math-inline&quot;&gt;m_{klr}&lt;&#x2F;span&gt; are constants, and &lt;span class=&quot;math math-inline&quot;&gt;u&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;v&lt;&#x2F;span&gt; are invertible matrices. Ignoring the invertibility constraint, this is a system of &lt;span class=&quot;math math-inline&quot;&gt;16&lt;&#x2F;span&gt; polynomial equations in &lt;span class=&quot;math math-inline&quot;&gt;20&lt;&#x2F;span&gt; unknowns of degree &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Why are there exactly two solutions when we constrain the matrix to be unitriangular?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Which symmetric bilinear forms can be computed simultaneously?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; If we pick two different bases for the input elements the coordinate bilinear forms are no longer symmetric. Which (not necessarily symmetric) bilinear forms can be constructed by an appropriate choice of basis?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;efficient-computation-in-mpc&quot;&gt;Efficient Computation in MPC&lt;&#x2F;h2&gt;
&lt;p&gt;The scheme is to be used inside an Shamir Secret Sharing setting. Let &lt;span class=&quot;math math-inline&quot;&gt;(a_0, a_1, … a_n)&lt;&#x2F;span&gt; be valid evaluation points, with the secret stored at &lt;span class=&quot;math math-inline&quot;&gt;a_0&lt;&#x2F;span&gt;, then the secret &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; is reconstructed from shares &lt;span class=&quot;math math-inline&quot;&gt;s_i&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Claim.&lt;&#x2F;strong&gt; Given a Shamir secret sharing with secret evaluation point &lt;span class=&quot;math math-inline&quot;&gt;x_s&lt;&#x2F;span&gt; and party points &lt;span class=&quot;math math-inline&quot;&gt;x_0,…x_{n-1}&lt;&#x2F;span&gt; the parties can locally convert to additive sharing.&lt;&#x2F;p&gt;
&lt;p&gt;This follows from the observation that the Lagrange interpolation formula is a sum over locally computable terms
&lt;span class=&quot;math math-display&quot;&gt;
s = \sum_{i∈[1,n]} L_i(x_s) ⋅ s_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Are the &lt;span class=&quot;math math-inline&quot;&gt;L_i(x_s)&lt;&#x2F;span&gt; guaranteed to be units? Can we therefore always convert locally back from  additive to Shamir sharing? Can this be generalized to any linear sharing scheme?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Claim.&lt;&#x2F;strong&gt; Given a linear map &lt;span class=&quot;math math-inline&quot;&gt;p:U→V&lt;&#x2F;span&gt; and an additive secret &lt;span class=&quot;math math-inline&quot;&gt;s ∈ U&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;s = \sum_i s_i&lt;&#x2F;span&gt;, the parties can locally compute an additive sharing of &lt;span class=&quot;math math-inline&quot;&gt;p(s)&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(s) = p\!\p{\sum_i s_i} = \sum_i p(s_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So given a Shamir sharing of &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; we can locally compute an additive sharing of &lt;span class=&quot;math math-inline&quot;&gt;p(s)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;galois-rings-among-algebras&quot;&gt;Galois rings among &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}&lt;&#x2F;span&gt;-algebras&lt;&#x2F;h2&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}^m&lt;&#x2F;span&gt;, the free &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}&lt;&#x2F;span&gt;-module of rank &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;, and a bilinear operation denoted as multiplication to form an algebra &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt;. For a basis &lt;span class=&quot;math math-inline&quot;&gt;\{\vec e_i\}&lt;&#x2F;span&gt; multiplication is uniquely defined by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Structure_constants&quot;&gt;structure constants&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;c_{ij}^k ∈ ℤ_{p^s}&lt;&#x2F;span&gt; given by
&lt;span class=&quot;math math-display&quot;&gt;
\vec e_i ⋅ \vec e_j= \sum_k c_{ij}^k ⋅ \vec e_k
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We constrain &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; to be commutative, unital and associative, which respectively imply&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
c_{ij}^k &amp;amp;= c_{ji}^k \\
\sum_i u_i ⋅ c_{ij}^k &amp;amp;= δ_{jk} \\
\sum_l c_{ij}^l ⋅ c_{lk}^m &amp;amp;= \sum_l c_{ik}^l ⋅ c_{jl}^m
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;u_i&lt;&#x2F;span&gt; are the coordinates of the identity element in the basis.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; What are the (additional) requirements for &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; to be a Galois ring?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; What other algebras are suitable for MPC?&lt;&#x2F;p&gt;
&lt;p&gt;To show that &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; is a Galois ring by the definition above, all that remains is to show that &quot;the set of its zero divisors with &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; added forms a principal ideal &lt;span class=&quot;math math-inline&quot;&gt;(p)&lt;&#x2F;span&gt; for some prime number &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;&quot;. We already have that &lt;span class=&quot;math math-inline&quot;&gt;(p)&lt;&#x2F;span&gt; is an ideal, as this is inherited from &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^s}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1142&#x2F;8250&quot;&gt;Wan11&lt;&#x2F;a&gt; Zhe-Xian Wan (2011). Finite Fields and Galois Rings.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dergipark.org.tr&#x2F;en&#x2F;pub&#x2F;ieja&#x2F;issue&#x2F;55997&#x2F;768265&quot;&gt;Sis20&lt;&#x2F;a&gt; Virgilio P. Sison (2020). Bases and Automorphism Matrix of the Galoir Ring &lt;span class=&quot;math math-inline&quot;&gt;GR(p^r, m)&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{p^r}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;872&quot;&gt;ACD⁺19&lt;&#x2F;a&gt; Mark Abspoel, Ronald Cramer, Ivan Damgård, Daniel Escudero, Chen Yuan (2019). Efficient Information-Theoretic Secure Multiparty Computation over &lt;span class=&quot;math math-inline&quot;&gt;ℤ&#x2F;p^kℤ&lt;&#x2F;span&gt; via Galois Rings.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1256&quot;&gt;ACD⁺20&lt;&#x2F;a&gt; Mark Abspoel, Ronald Cramer, Ivan Damgård, Daniel Escudero, Matthieu Rambaud, Chaoping Xing, Chen Yuan (2019). Asymptotically Good Multiplicative LSSS over Galois Rings and Applications to MPC over &lt;span class=&quot;math math-inline&quot;&gt;ℤ&#x2F;p^kℤ&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;appendix-solver&quot;&gt;Appendix: Solver&lt;&#x2F;h2&gt;
&lt;p&gt;See the full source in &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;24&#x2F;galois-dot&#x2F;.&#x2F;galois-dot.rs&quot;&gt;&lt;code&gt;galois-dot.rs&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and associated SageMath notebook &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;24&#x2F;galois-dot&#x2F;.&#x2F;galois-dot.ipynb&quot;&gt;&lt;code&gt;galois-dot.ipynb&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To find solutions I wrote a little multi-threaded solver in Rust:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Solve polynomial systems of equations over `u64` by linear Hensel lifting.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; `eval` should be a function that takes a solution vector and returns the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; bitwise-or of the polynomial functions at that point.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; root&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; N&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; impl&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; N&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Sync&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; N&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; solutions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-macro z-rust&quot;&gt; vec!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; N&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-macro z-rust&quot;&gt;        println!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;Lifting bit &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, initial solutions &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; solutions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        solutions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;truncate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Limit number of candidate solutions to prevent explosion&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        solutions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; solutions&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;into_par_iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;flat_map&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;solution&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; N&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;into_par_iter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;map&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;bit_pattern&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;                std&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;array&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;from_fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; solution&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (((&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;bit_pattern&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            })&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;filter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;sol&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; eval&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;sol&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;trailing_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; bit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;            .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        })&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;collect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    solutions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For example to compute the inverse of 5:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;root&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For example to find &lt;span class=&quot;math math-inline&quot;&gt;2×2&lt;&#x2F;span&gt; invertible matrices &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
m_{00}⋅ m_{10}^3 &amp;amp;= m_{01} &amp;amp;
m_{01}^3 &amp;amp;= 5 &amp;amp; 
m_{00}^5 &amp;amp;= 9
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Check if a number is a unit by computing $1 - n^{2^{63}}$.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; is_unit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Wrapping&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Wrapping&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Wrapping&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Wrapping&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Equivalent expression&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; equations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m00&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m01&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m11&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;map&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Wrapping&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Wrapping&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; is_unit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;m00&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;m11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; m10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;m01&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Determinant is a unit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m00&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m01&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m01&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Wrapping&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m00&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Wrapping&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    lhs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-macro z-rust&quot;&gt;println!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;Solutions &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; root&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;equations&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There&#x27;s room for optimization. The &lt;code&gt;is_unit&lt;&#x2F;code&gt; checks can be dismissed after the first bits are found. Linear constraints can be solved first to reduce the number of variables.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Winograd Fast Inner Product</title>
        <published>2024-06-22T00:00:00+00:00</published>
        <updated>2024-06-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/inner-product/"/>
        <id>https://2π.com/24/inner-product/</id>
        
        <content type="html" xml:base="https://2π.com/24/inner-product/">&lt;h1 id=&quot;winograd-fast-inner-product&quot;&gt;Winograd Fast Inner Product&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\ceil#1{\delim\lceil{#1}\rceil}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2311.12224&quot;&gt;PN23&lt;&#x2F;a&gt; mentions a clever trick due to Winograd &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ieeexplore.ieee.org&#x2F;document&#x2F;1687427&quot;&gt;W68&lt;&#x2F;a&gt; to compute inner products with half the number of multiplications after pre-processing. Observe for &lt;span class=&quot;math math-inline&quot;&gt;(a_0, a_1)⋅(b_0, b_1)&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_0⋅b_0 + a_1 ⋅b_1 = (a_0 + b_1) ⋅ (a_1 + b_0) - a_0 ⋅ a_1 - b_0 ⋅ b_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the left hand side, the conventional method, takes two multiplications. The right hand side needs three multiplications but two of them only depend on one of the inputs and can be precomputed.&lt;&#x2F;p&gt;
&lt;p&gt;For arbitrary length vectors this can be repeated for all pairs&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\sum_{i \in [0,n)} a_i ⋅ b_i 
&amp;amp;= \sum_{i \in 2⋅[0,n&#x2F;2)} \p{a_{i} ⋅ b_{i} + a_{i + 1} ⋅ b_{i + 1} } \\
&amp;amp;= \sum_{i \in 2⋅[0,n&#x2F;2)} \p{
    \p{a_{i} + b_{i + 1}} ⋅ \p{a_{i + 1} + b_{i}} - 
    a_{i} ⋅ a_{i + 1} - b_{i} ⋅ b_{i + 1} 
} \\
&amp;amp;= A + B + \sum_{i \in 2⋅[0,n&#x2F;2)} \p{a_{i} + b_{i + 1}} ⋅ \p{a_{i + 1} + b_{i}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where we only need to store a single precomputed value per input vector&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A &amp;amp;= \!\!\!\sum_{i \in 2⋅[0,n&#x2F;2)}\!\!\! -a_{i} ⋅ a_{i + 1} &amp;amp;\quad
B &amp;amp;= \!\!\!\sum_{i \in 2⋅[0,n&#x2F;2)}\!\!\! -b_{i} ⋅ b_{i + 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Generalizing this to more than two terms does not seem beneficial, as it generates &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; useful terms, but &lt;span class=&quot;math math-inline&quot;&gt;n^2-n&lt;&#x2F;span&gt; noise terms that need to be cancelled. For &lt;span class=&quot;math math-inline&quot;&gt;n&amp;gt;2&lt;&#x2F;span&gt; these noise terms also include cross terms between &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; that can not be pre-computed in the same way.&lt;&#x2F;p&gt;
&lt;p&gt;Picking odd and even indices is arbitrary. Instead we can pad the vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; with zeros to have an even length, and then create two &lt;span class=&quot;math math-inline&quot;&gt;\ceil{\frac{n}{2}}&lt;&#x2F;span&gt; length subsequences &lt;span class=&quot;math math-inline&quot;&gt;\mathcal A&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathcal B&lt;&#x2F;span&gt; and compute:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec a ⋅ \vec b = \p{\vec a_{\mathcal A} + \vec b_{\mathcal B}}⋅\p{\vec a_{\mathcal B} + \vec b_{\mathcal A}} -
\vec a_{\mathcal A} ⋅ \vec a_{\mathcal B} -
\vec b_{\mathcal B} ⋅ \vec a_{\mathcal B}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In particular, we can can pick the lower and higher half of indices and get a block-matrix formulation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\begin{bmatrix}
\mat A &amp;amp; \mat A&amp;#39;
\end{bmatrix}⋅
\begin{bmatrix}
\mat B \\ \mat B&amp;#39;
\end{bmatrix}
&amp;amp;=\mat A ⋅ \mat B +
\mat A&amp;#39; ⋅ \mat B&amp;#39; \\
&amp;amp;=\p{\mat A + \mat B&amp;#39;}⋅
\p{\mat A&amp;#39; + \mat B}-\mat A⋅\mat A&amp;#39;-\mat B&amp;#39;⋅\mat B
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The naive algorithm for matrix multiplication involves a large number of dot products. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ieeexplore.ieee.org&#x2F;document&#x2F;1687427&quot;&gt;W68&lt;&#x2F;a&gt; shows that for large matrices the pre-processing cost ammortizes away and we can indeed half the number of multiplications. Winograd further shows that this leads to improvements for matrix inversion and solving linear systems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;To vectorize this we can swap pairs of elements in the vector &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt;, so that the addition is in order:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A + B + \sum_{i \in 2⋅[0,n&#x2F;2)} \p{a_{i} + b_{i}} ⋅ \p{a_{i + 1} + b_{i + 1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we split &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; into odd and even vectors we get:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i \in [0,n&#x2F;2)} \p{a_{i} + b_{i}} ⋅ \p{a_{i}&amp;#39; + b_{i}&amp;#39;}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Or batched:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat C = \vec a + \vec d + \p{\mat A + \mat B} ⋅ \p{\mat A&amp;#39; + \mat B&amp;#39;}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ieeexplore.ieee.org&#x2F;document&#x2F;1687427&quot;&gt;W68&lt;&#x2F;a&gt; Shmuel Winograd (1968). A New Algorithm for Inner Product.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2311.12224&quot;&gt;PN23&lt;&#x2F;a&gt; Trevor E. Pogue, Nicola Nicolici (2023). Fast Inner-Product Algorithms and Architectures for Deep Neural Network Accelerators.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linear Secret Sharing Schemes</title>
        <published>2024-02-27T00:00:00+00:00</published>
        <updated>2024-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/lsss/"/>
        <id>https://2π.com/24/lsss/</id>
        
        <content type="html" xml:base="https://2π.com/24/lsss/">&lt;h1 id=&quot;linear-secret-sharing-schemes&quot;&gt;Linear Secret Sharing Schemes&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\ps#1{\delim\{{#1}\}}
\gdef\box#1{\delim[{#1}]}
\gdef\floor#1{\delim\lfloor{#1}\rfloor}
\gdef\ceil#1{\delim\lceil{#1}\rceil}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\setn#1{\mathcal{#1}}
\gdef\Z{\mathrm{Z}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Thank you Daniel Kales, Roman Walch and others from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.taceo.io&#x2F;&quot;&gt;TACEO&lt;&#x2F;a&gt; for many pointers and explanations.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Derive generic construction from first principles.&lt;&#x2F;li&gt;
&lt;li&gt;Polynomial interpretation as Shamir secret sharing.&lt;&#x2F;li&gt;
&lt;li&gt;Multi-secrets.&lt;&#x2F;li&gt;
&lt;li&gt;CRT interpretation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{encode}: \mathsf{secret}^k → \mathsf{shares}^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{decode}: \mathsf{secret}^k → \mathsf{shares}^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-party secret sharing scheme&lt;&#x2F;em&gt; is a pair of functions &lt;em&gt;encode&lt;&#x2F;em&gt; and &lt;em&gt;decode&lt;&#x2F;em&gt; between &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; parties. Where an entity (not necessarily a party) with a value &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; can encode this to secret shares &lt;span class=&quot;math math-inline&quot;&gt;s_0, …, s_{n-1}&lt;&#x2F;span&gt; and distribute these to the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; parties. Given (a subset of) shares, the &lt;em&gt;decode&lt;&#x2F;em&gt; procedure reconstructs the original value.&lt;&#x2F;p&gt;
&lt;p&gt;Given a ring &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt;, usually &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; or some prime field &lt;span class=&quot;math math-inline&quot;&gt;𝔽&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Environment: We assume perfect synchronous private communication channels between all entities. In practice this is created using end-to-end encrypted connections.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;generic-construction&quot;&gt;Generic construction&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Todo.&lt;&#x2F;strong&gt; This is similar to the generalization to Monotone&#x2F;Extended Span Programs (MSP&#x2F;ESP) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.ethz.ch&#x2F;publications&#x2F;files&#x2F;Fehr98.pdf&quot;&gt;Feh98&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;841.pdf&quot;&gt;JSL21&lt;&#x2F;a&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;eurocrypt2000&#x2F;1807&#x2F;18070321-new.pdf&quot;&gt;CDM00&lt;&#x2F;a&gt;. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;3-540-39200-9_37.pdf&quot;&gt;CFIK03&lt;&#x2F;a&gt; it is stated they are in 1-1 correspondence with LSSSs, like I attempting here. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;3-540-39200-9_37.pdf&quot;&gt;CFIK03&lt;&#x2F;a&gt; paper seems to have a good concise overview.&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;dk&#x2F;universitypress&#x2F;subjects&#x2F;computer-science&#x2F;cryptography-cryptology-and-coding&#x2F;secure-multiparty-computation-and-secret-sharing&quot;&gt;CDN15&lt;&#x2F;a&gt; § 6.3 this is presented (though in field version). In particular it shows that any scheme leads to some form of multiplication when parties locally pair-wise multiply there shares that they have. See GCEPs on page 167 for a general presentation.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; How does this generalize to rings?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; How does this generalize to packed secrets?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; How does this generalize to mixed encoding? (i.e. inputs a, b are in different schemes).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; What do adversary structures like &lt;span class=&quot;math math-inline&quot;&gt;\mathcal Q_2&lt;&#x2F;span&gt; mean intuitively?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.math.ias.edu&#x2F;~avi&#x2F;PUBLICATIONS&#x2F;MYPAPERS&#x2F;KW93&#x2F;proc.pdf&quot;&gt;KW93&lt;&#x2F;a&gt; M. Karchmer, A. Wigderson (1993). On span programs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.ethz.ch&#x2F;publications&#x2F;files&#x2F;Fehr98.pdf&quot;&gt;Feh98&lt;&#x2F;a&gt; Serge Fehr (1998). Span programs over rings and how to share a secret from a module.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;eurocrypt2000&#x2F;1807&#x2F;18070321-new.pdf&quot;&gt;CDM00&lt;&#x2F;a&gt; Ronald Cramer, Ivan Damgård, Ueli Maurer (2000). General Secure Multi-party Computation from any Linear Secret-Sharing Scheme.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;3-540-39200-9_37.pdf&quot;&gt;CFIK03&lt;&#x2F;a&gt; Ronald Cramer, Serge Fehr, Yuval Ishai, Eyal Kushilevitz (2003). Efficient Multi-party Computation over Rings.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Given a commutative ring &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt; such a &lt;span class=&quot;math math-inline&quot;&gt;ℤ&#x2F;qℤ&lt;&#x2F;span&gt;. An &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-party affine &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt;-multi secret sharing scheme over &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt;&lt;&#x2F;em&gt; has a cleartext values in &lt;span class=&quot;math math-inline&quot;&gt;𝕂^s&lt;&#x2F;span&gt; and secrets in the set of tuples &lt;span class=&quot;math math-inline&quot;&gt;\setn S = \prod_{i∈[0,n)} \setn S_i&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\setn S_i&lt;&#x2F;span&gt; is the set of possible shares of party &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;. There is a randomized injective protocol &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{encode}_{r}: 𝕂^s → \setn S&lt;&#x2F;span&gt; and a surjective function &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{decode}: \setn S → 𝕂^s&lt;&#x2F;span&gt;. Given &lt;span class=&quot;math math-inline&quot;&gt;a ∈ 𝕂^s&lt;&#x2F;span&gt;, denote with &lt;span class=&quot;math math-inline&quot;&gt;[a]&lt;&#x2F;span&gt; an arbitrary element of &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{decode}([a]) = a&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The set of secrets &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt; has operations to add two secrets and multiply secrets by an element of &lt;span class=&quot;math math-inline&quot;&gt;𝕂^s&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt; forms a &lt;span class=&quot;math math-inline&quot;&gt;𝕂^s&lt;&#x2F;span&gt;-module. It is also has an affine action of &lt;span class=&quot;math math-inline&quot;&gt;𝕂^s&lt;&#x2F;span&gt; (i.e. scalar addition).&lt;&#x2F;p&gt;
&lt;p&gt;Assume (argument TBD) that &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt; is a free module. This means it has a basis and can be represented as &lt;span class=&quot;math math-inline&quot;&gt;𝕂^k&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;. Let&#x27;s also assume &lt;span class=&quot;math math-inline&quot;&gt;k=n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\setn S = 𝕂^n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\setn S_i = 𝕂&lt;&#x2F;span&gt;. Given a basis on &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt; we can represent secrets &lt;span class=&quot;math math-inline&quot;&gt;[a] ∈ \setn S&lt;&#x2F;span&gt; as elements in &lt;span class=&quot;math math-inline&quot;&gt;𝕂^n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; These assumptions are overly restrictive and exclude replicated schemes where &lt;span class=&quot;math math-inline&quot;&gt;\setn S_i = 𝕂^k&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{decode}&lt;&#x2F;span&gt; function is a &lt;em&gt;surjective linear map&lt;&#x2F;em&gt; as for every element in &lt;span class=&quot;math math-inline&quot;&gt;\setn S&lt;&#x2F;span&gt; there is a pre-image and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{decode}([a] + [b]) = a+b&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{decode}(c ⋅ [a]) = c⋅ a&lt;&#x2F;span&gt; for any &lt;span class=&quot;math math-inline&quot;&gt;a,b,c ∈ 𝕂&lt;&#x2F;span&gt;. In the basis it is represented by a full-rank &lt;em&gt;decoding matrix&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\mat D ∈ 𝕂^{s × n}.&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a = \mathsf{decode}([a]) = \mat D ⋅ [a]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The null-space &lt;span class=&quot;math math-inline&quot;&gt;\ker \mat D&lt;&#x2F;span&gt; has dimension &lt;span class=&quot;math math-inline&quot;&gt;n - s&lt;&#x2F;span&gt;. This null-space allows for multiple valid encodings of the same secret and hence provides the randomness required for secrecy. It is however useful set aside a subspace of dimension &lt;span class=&quot;math math-inline&quot;&gt;n_c&lt;&#x2F;span&gt; to be held zero, leaving dimension &lt;span class=&quot;math math-inline&quot;&gt;n_r = n - s - n_c&lt;&#x2F;span&gt;. Picking a basis for the random and zero subspaces results in a matrix&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Even if &lt;span class=&quot;math math-inline&quot;&gt;𝕂^n&lt;&#x2F;span&gt; has a basis this does not guarantee &lt;span class=&quot;math math-inline&quot;&gt;\ker \mat D&lt;&#x2F;span&gt; has a basis. In fact, this appears not the case for additive sharing in &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
a \\ r \\ 0
\end{bmatrix} =
\begin{bmatrix}
\mat D \\
\mat R \\
\mat C
\end{bmatrix} ⋅ [a]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\mat R ∈ 𝕂^{n_r × n}, \mat C ∈ 𝕂^{n_c × n}&lt;&#x2F;span&gt;. We can now specify the &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{encode}_r&lt;&#x2F;span&gt; operation as solving the above equation for some &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r ∈ 𝕂^{n_r}&lt;&#x2F;span&gt;. The scheme is fully specified by &lt;span class=&quot;math math-inline&quot;&gt;(𝕂, \mat D, \mat R, \mat C)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; What are the conditions for this to be solvable? For example the additive scheme with an even number of parties is not invertable in &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; It is not strictly necessary that randomness and constants are linearly separable, but this is what all protocols seem to do.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Derive the threshold the scheme provides, and any mallicious resistance.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; There should be some requirement that the entries in &lt;span class=&quot;math math-inline&quot;&gt;\mat D&lt;&#x2F;span&gt; are all non-zero, or else there is degeneracy and fewer shares are required to learn about some secret. One way to approach define this might be to insist that each share value can set change any secret value. A similar argument applies to &lt;span class=&quot;math math-inline&quot;&gt;\mat R&lt;&#x2F;span&gt;. &lt;strong&gt;Q.&lt;&#x2F;strong&gt; Does it matter if a combination of rows or columns has zeros? &lt;strong&gt;Q&lt;&#x2F;strong&gt; What are sufficient and minimal constraints of &lt;span class=&quot;math math-inline&quot;&gt;\mat D, \mat R, \mat C&lt;&#x2F;span&gt; to make schemes unconditionally secure with some threshold?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Given an &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-party scheme with &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; shares we can recursively deal the shares with a &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;-party scheme to obtain &lt;span class=&quot;math math-inline&quot;&gt;n⋅m&lt;&#x2F;span&gt; shares. What are the properties of such recursive schemes? What sort of isomorphisms follow from it?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;concrete-schemes&quot;&gt;Concrete schemes&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;additive-sharing&quot;&gt;Additive sharing&lt;&#x2F;h3&gt;
&lt;p&gt;A simple protocol to share a single secret &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; among &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; parties is to create &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; random values &lt;span class=&quot;math math-inline&quot;&gt;x_0, x_1, …, x_{n-1}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a = x_0 + x_1 + ⋯ + x_{n-1}&lt;&#x2F;span&gt;. This can be represented using the decoding matrix&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat D = \begin{bmatrix} 1 &amp;amp; 1 &amp;amp; 1 &amp;amp; ⋯ &amp;amp; 1 \end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One basis for &lt;span class=&quot;math math-inline&quot;&gt;\ker \mat D&lt;&#x2F;span&gt; is the &lt;span class=&quot;math math-inline&quot;&gt;(n-1) × n&lt;&#x2F;span&gt; matrix:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat R = \begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; ⋯ &amp;amp; -1 \\
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; ⋯ &amp;amp; -1 \\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; ⋯ &amp;amp; -1 \\
⋮ &amp;amp; ⋮ &amp;amp; ⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ⋯ &amp;amp; -1 \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; In &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^{16}}&lt;&#x2F;span&gt; there is no &lt;span class=&quot;math math-inline&quot;&gt;\mat D^+&lt;&#x2F;span&gt; for even values of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. In those cases it is not possible to construct an encoding that has &lt;span class=&quot;math math-inline&quot;&gt;\mat R ⋅ \vec y = \vec 0&lt;&#x2F;span&gt;. Does this imply there is less entropy? How do we define the encode operation?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shamir-secret-sharing&quot;&gt;Shamir secret sharing&lt;&#x2F;h3&gt;
&lt;p&gt;First introduced in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.mit.edu&#x2F;6.857&#x2F;OldStuff&#x2F;Fall03&#x2F;ref&#x2F;Shamir-HowToShareASecret.pdf&quot;&gt;Sha79&lt;&#x2F;a&gt;, applied to MPC in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;62212.62213&quot;&gt;BGW88&lt;&#x2F;a&gt;, and generalized to multi-secrets in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;129712.129780&quot;&gt;FY92&lt;&#x2F;a&gt;. See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2011&#x2F;136.pdf&quot;&gt;AL11&lt;&#x2F;a&gt; for a detailed description. Given a ring &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt;, the protocol works implicitly with polynomials in &lt;span class=&quot;math math-inline&quot;&gt;𝕂[X]&lt;&#x2F;span&gt;. The protocol is specified by a set of secret and share evaluation points &lt;span class=&quot;math math-inline&quot;&gt;\vec s, \vec x ⊂ 𝕂&lt;&#x2F;span&gt; and such that all evaluation points are distinct. The multi-secret is represented as a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P ∈ 𝕂[X]&lt;&#x2F;span&gt; such that each party&#x27;s share &lt;span class=&quot;math math-inline&quot;&gt;y_i = P(x_i)&lt;&#x2F;span&gt; and the secrets are stored as &lt;span class=&quot;math math-inline&quot;&gt;a_i = P()&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Recall the Vandermonde matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat V_{\vec x}&lt;&#x2F;span&gt; for an evaluation basis &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; such that if &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt; are the coefficients of a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P ∈ 𝕂[X]&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;\vec y = \mat V_{\vec x} ⋅ \vec c&lt;&#x2F;span&gt; computes the evaluations such that &lt;span class=&quot;math math-inline&quot;&gt;y_i = P(x_i)&lt;&#x2F;span&gt;. This can also be seen as a transformation from monomial (coefficient) basis to an evaluation basis. It is given by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat V_{\vec x} =
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; x_0^3 &amp;amp; ⋯ \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; x_1^3 &amp;amp; ⋯ \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; x_2^3 &amp;amp; ⋯ \\
⋮ &amp;amp; ⋮ &amp;amp; ⋮ &amp;amp; ⋮ &amp;amp; ⋱
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Consequently &lt;span class=&quot;math math-inline&quot;&gt;\mat V_{\vec x}^{-1}&lt;&#x2F;span&gt;, which always exists if &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt; is a field, transforms from evaluations to coefficients. We can use this to convert from the share evaluation basis to the secret evaluation basis. This gives our decoding matrix as &lt;span class=&quot;math math-inline&quot;&gt;\mat D = \mat V_{\vec s} ⋅ \mat V_{\vec x}^{-1}&lt;&#x2F;span&gt;. We can compute the entries of the decoding matrix directly using the Lagrange interpolation formula:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat D_{ij}
= \mathrm{L}_j(s_i)
= \prod_{k ∈ [0,n) ∖ j} \frac{s_i - x_k}{x_j - x_k}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This matrix exists if each &lt;span class=&quot;math math-inline&quot;&gt;x_i - x_j&lt;&#x2F;span&gt; is invertible in &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt;. They are non-zero by the requirement of distinctness, so the matrix always exists when &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt; is a field. Unfortunately in the computationally interesting rings &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; there are no solutions with more than two points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A particularly useful basis for &lt;span class=&quot;math math-inline&quot;&gt;\ker \mat D&lt;&#x2F;span&gt; can be constructed by selecting the high coefficients.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix} \mat D \\ \hline \mat R  \\ \mat C\end{bmatrix} =
\begin{bmatrix} \mat V_{\vec s} \\ \hline
\begin{array}{ccc} 0 &amp;amp; I &amp;amp; 0 \\ 0 &amp;amp; 0 &amp;amp; I \end{array}
\end{bmatrix} ⋅
\mat V_{\vec x}^{-1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;By setting &lt;span class=&quot;math math-inline&quot;&gt;\vec c = \vec 0&lt;&#x2F;span&gt; we can restrict the degree of &lt;span class=&quot;math math-inline&quot;&gt;P(X)&lt;&#x2F;span&gt;, which is the key to BGW Multiplication. Let &lt;span class=&quot;math math-inline&quot;&gt;n_c&lt;&#x2F;span&gt; be the size of &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt;, then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\deg P ≤ n - n_c - 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Can BGW multiplication be made to work with values of &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt; other than &lt;span class=&quot;math math-inline&quot;&gt;\vec 0&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Does this generalize to confluent Vandermonde matrices? I.e. we also include evaluations over formal derivatives of &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; in our basis. (See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hermite_interpolation&quot;&gt;Hermite interpolation&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; It is not possible to represent the additive scheme as a Shamir scheme. Consider the &lt;span class=&quot;math math-inline&quot;&gt;n=2&lt;&#x2F;span&gt; case, the Lagrange interpolation formula for &lt;span class=&quot;math math-inline&quot;&gt;\mat D&lt;&#x2F;span&gt; implies the unsolvable system&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
1 &amp;amp;= \frac{s_0 - x_1}{x_0 - x_1} &amp;amp;
1 &amp;amp;= \frac{s_0 - x_0}{x_1 - x_0}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;useful-protocols&quot;&gt;Useful Protocols&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;dealing-secrets&quot;&gt;Dealing secrets&lt;&#x2F;h3&gt;
&lt;p&gt;To input a value &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; the &lt;em&gt;dealer&lt;&#x2F;em&gt; who has the value generates shares &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; and distributes them to the parties. Note that the dealer can be one of the parties. Some protocols use this to distribute a share &lt;span class=&quot;math math-inline&quot;&gt;y_i&lt;&#x2F;span&gt; as a secret &lt;span class=&quot;math math-inline&quot;&gt;[y_i]&lt;&#x2F;span&gt;, known as &lt;em&gt;shares-of-shares&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Todo.&lt;&#x2F;strong&gt; Elaborate how this works for multi-secrets. Could set only the desired values and set the others to zero. Then add the secrets.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dealing-non-secret-values&quot;&gt;Dealing non-secret values&lt;&#x2F;h3&gt;
&lt;p&gt;If a non-secret value &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; needs to be input the trivial solution is to broadcast it to all parties. The value can then be used as cleartext in the protocols. But if the value is only used additively (i.e. it is not multiplied by a secret), it can also be dealt as a secret &lt;span class=&quot;math math-inline&quot;&gt;[a]&lt;&#x2F;span&gt;. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;189.pdf&quot;&gt;GSZ20&lt;&#x2F;a&gt; it is observed that since this value is not really secret, we can use the &lt;span class=&quot;math math-inline&quot;&gt;n_r&lt;&#x2F;span&gt; degrees of freedom in the randomness to instead fix  &lt;span class=&quot;math math-inline&quot;&gt;n_r&lt;&#x2F;span&gt; of the shares &lt;span class=&quot;math math-inline&quot;&gt;y_i&lt;&#x2F;span&gt; to constant values (typically zero) already known to those parties. This saves &lt;span class=&quot;math math-inline&quot;&gt;n_r&lt;&#x2F;span&gt; messages compares to plaintext broadcast.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Explicit formulas.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;revealing-secrets&quot;&gt;Revealing secrets&lt;&#x2F;h3&gt;
&lt;p&gt;An efficient protocol to open or reveal a secret is to send all shares to a single entity&lt;&#x2F;p&gt;
&lt;h3 id=&quot;randomness-generation&quot;&gt;Randomness generation&lt;&#x2F;h3&gt;
&lt;p&gt;From &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;crypto2007&#x2F;46220565&#x2F;46220565.pdf&quot;&gt;DN07&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;tcc2008&#x2F;49480207&#x2F;49480207.pdf&quot;&gt;BH08&lt;&#x2F;a&gt;. It starts with the observation that for a suitable matrix &lt;span class=&quot;math math-inline&quot;&gt;l×n&lt;&#x2F;span&gt; matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt; (such as a Vandermonde matrix), we can generate &lt;span class=&quot;math math-inline&quot;&gt;l ≤ n&lt;&#x2F;span&gt; secret random values using only &lt;span class=&quot;math math-inline&quot;&gt;n^2 - n&lt;&#x2F;span&gt; messages with malicious security against &lt;span class=&quot;math math-inline&quot;&gt;n - l&lt;&#x2F;span&gt; adversaries. The protocol proceeds as follows.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Each party &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; picks a random number &lt;span class=&quot;math math-inline&quot;&gt;r_i ∈_R 𝔽&lt;&#x2F;span&gt; and secret shares it, creating &lt;span class=&quot;math math-inline&quot;&gt;[r_i]&lt;&#x2F;span&gt;. This requires &lt;span class=&quot;math math-inline&quot;&gt;n^2 - n&lt;&#x2F;span&gt; messages.&lt;&#x2F;li&gt;
&lt;li&gt;Each party locally computes &lt;span class=&quot;math math-inline&quot;&gt;[\vec r&amp;#39;] = \mat M ⋅ [\vec r]&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The vector &lt;span class=&quot;math math-inline&quot;&gt;[\vec r&amp;#39;]&lt;&#x2F;span&gt; now has &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt; independent uniform random values. A variant of this protocol has the parties simultaneously compute &lt;span class=&quot;math math-inline&quot;&gt;[\vec r]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;[\vec r]_{\deg &amp;lt; \frac n2}&lt;&#x2F;span&gt;, where the latter is a low degree Shamir secret encoding in the BGW sense.&lt;&#x2F;p&gt;
&lt;p&gt;This requires &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt; to be &lt;em&gt;hyper-invertable&lt;&#x2F;em&gt;, meaning that each square submatrix is invertible. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;dk&#x2F;universitypress&#x2F;subjects&#x2F;computer-science&#x2F;cryptography-cryptology-and-coding&#x2F;secure-multiparty-computation-and-secret-sharing&quot;&gt;CDN15&lt;&#x2F;a&gt; p. 186 it is claimed this is known as a &#x27;regular matrix&#x27; and &#x27;maximum distance seperable (MDS) matrix&#x27; in other fields.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Are &#x27;every square submatrix is invertible&#x27; and &#x27;every submatrix is full-rank&#x27; equivalent? See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;dk&#x2F;universitypress&#x2F;subjects&#x2F;computer-science&#x2F;cryptography-cryptology-and-coding&#x2F;secure-multiparty-computation-and-secret-sharing&quot;&gt;CDN15&lt;&#x2F;a&gt; p 186. &lt;strong&gt;A.&lt;&#x2F;strong&gt; Yes. The &lt;span class=&quot;math math-inline&quot;&gt;←&lt;&#x2F;span&gt; case is trivial, for the other direction pick any maximal size square submatrix in the submatrix, this is invertible and hence the non-square matrix is full rank.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; How to generate all MDS matrices? Vandermonde (&lt;span class=&quot;math math-inline&quot;&gt;x_i^j&lt;&#x2F;span&gt;), Cauchy (&lt;span class=&quot;math math-inline&quot;&gt;\p{x_i - x_j}^{-1}&lt;&#x2F;span&gt;), and circulant matrices (&lt;span class=&quot;math math-inline&quot;&gt;x_{i+j}&lt;&#x2F;span&gt;) are examples. Are MDS matrices closed under matrix or elementwise multiplication? Are the other transformations we can do that perserve the MDS property?&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;MDS_matrix&lt;&#x2F;p&gt;
&lt;h3 id=&quot;local-randomness-generation&quot;&gt;Local randomness generation&lt;&#x2F;h3&gt;
&lt;p&gt;Simply set &lt;span class=&quot;math math-inline&quot;&gt;y_i = r_i&lt;&#x2F;span&gt; to create random &lt;span class=&quot;math math-inline&quot;&gt;[r]&lt;&#x2F;span&gt;. Assumes semi-honest. Needs more nuance of there are constraints.&lt;&#x2F;p&gt;
&lt;p&gt;Replicated version party &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; has key to PRNG &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;i+1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;converting-between-schemes&quot;&gt;Converting between &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt;-schemes&lt;&#x2F;h3&gt;
&lt;p&gt;Given two different affine schemes &lt;span class=&quot;math math-inline&quot;&gt;\mathcal A&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathcal B&lt;&#x2F;span&gt; over the same ring &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt;. We want to convert a secret &lt;span class=&quot;math math-inline&quot;&gt;[a]_{\mathcal A}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;[a]_{\mathcal B}&lt;&#x2F;span&gt;. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.cs.mcgill.ca&#x2F;~crepeau&#x2F;PDFx&#x2F;ASPUBLISHED&#x2F;CCD88A.pdf&quot;&gt;CCD88&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;eurocrypt2001&#x2F;20450279.pdf&quot;&gt;CDN01&lt;&#x2F;a&gt; the &lt;em&gt;double-randomness&lt;&#x2F;em&gt; protocol is introduced that works as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The parties generate a random secret &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; simultaneously in both schemes &lt;span class=&quot;math math-inline&quot;&gt;[r]_{\mathcal A}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;[r]_{\mathcal B}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The parties compute &lt;span class=&quot;math math-inline&quot;&gt;[a + r]_{\mathcal A} = [a]_{\mathcal A} + [r]_{\mathcal A}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The parties open this value to reveal &lt;span class=&quot;math math-inline&quot;&gt;\p{a + r}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The parties compute &lt;span class=&quot;math math-inline&quot;&gt;[a]_{\mathcal B} = \p{a + r} - [r]_{\mathcal B}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that the first step can be done efficiently in batch as a preprocessing step. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;189.pdf&quot;&gt;GSZ20&lt;&#x2F;a&gt; (see also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;062.pdf&quot;&gt;Esc23&lt;&#x2F;a&gt;) it is observed that for step 3 it is more efficient to let a single party do the decoding and use secret sharing to deal &lt;span class=&quot;math math-inline&quot;&gt;\p{\vec a + \vec r}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This is notably used in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.cs.mcgill.ca&#x2F;~crepeau&#x2F;PDFx&#x2F;ASPUBLISHED&#x2F;CCD88A.pdf&quot;&gt;CCD88&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;crypto2007&#x2F;46220565&#x2F;46220565.pdf&quot;&gt;DN07&lt;&#x2F;a&gt; with Shamir schemes to convert from a high-degree to a low-degree polynomials.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; This is very generic and the schemes don&#x27;t need to be MPC schemes, as long as they are affine. This allows it to be used for conversion between, say a homomorphic encryption scheme and elliptic curves.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;idea-local-conversion-between-schemes&quot;&gt;Idea: local conversion between &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt;-schemes?&lt;&#x2F;h3&gt;
&lt;p&gt;Assuming single-secret linear schemes &lt;span class=&quot;math math-inline&quot;&gt;\mathcal A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathcal B&lt;&#x2F;span&gt; with decoding vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec d_{\mathcal A}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec d_{\mathcal B}&lt;&#x2F;span&gt;. Given a secret &lt;span class=&quot;math math-inline&quot;&gt;\box{a}_{\mathcal A}&lt;&#x2F;span&gt; as shares &lt;span class=&quot;math math-inline&quot;&gt;a_i&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a = \sum_i a_i ⋅ d_{\mathcal A,i}&lt;&#x2F;span&gt;. We want to obtain shares &lt;span class=&quot;math math-inline&quot;&gt;a_i&amp;#39;&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a = \sum_i a_i&amp;#39; ⋅ d_{\mathcal B,i}&lt;&#x2F;span&gt;. One way to do this locally is have every party compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_i&amp;#39; = \frac{d_{\mathcal A,i}}{d_{\mathcal B,i}} ⋅ a_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;assuming the fraction exists in &lt;span class=&quot;math math-inline&quot;&gt;𝕂&lt;&#x2F;span&gt;. If it doesn&#x27;t, we still have a little more freedom left to try as the order of the shares does not need to correspond between &lt;span class=&quot;math math-inline&quot;&gt;\mathcal A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathcal B&lt;&#x2F;span&gt;. We can pick a permutation of shares &lt;span class=&quot;math math-inline&quot;&gt;σ&lt;&#x2F;span&gt; and compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_{σ(i)}&amp;#39; = \frac{d_{\mathcal A,i}}{d_{\mathcal B,σ(i)}} ⋅ a_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;this can still be computed locally.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec a = \mat D ⋅ \vec s
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the general case we want to find a matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\mat D_{\mathcal B} ⋅ \mat M = \mat D_{\mathcal A}&lt;&#x2F;span&gt;. Then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec s = \mat D_{\mathcal A} ⋅ \vec a = \mat D_{\mathcal B} ⋅ \p{\mat M ⋅ \vec a} = \mat D_{\mathcal B} ⋅ \vec a&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt; is diagonal, or can be permuted into diagonal, then this can be done locally.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;converting-between-any-schemes&quot;&gt;Converting between any schemes&lt;&#x2F;h3&gt;
&lt;p&gt;Given sets &lt;span class=&quot;math math-inline&quot;&gt;𝕂, 𝕃&lt;&#x2F;span&gt; with secret sharing schemes &lt;span class=&quot;math math-inline&quot;&gt;\mathcal K, \mathcal L&lt;&#x2F;span&gt;, and a function &lt;span class=&quot;math math-inline&quot;&gt;f:𝕂 → 𝕃&lt;&#x2F;span&gt;, we want to convert &lt;span class=&quot;math math-inline&quot;&gt;[a]_{\mathcal K}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;[f(a)]_{\mathcal L}&lt;&#x2F;span&gt;. Here is a template for a protocol:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Each party computes &lt;span class=&quot;math math-inline&quot;&gt;y_i&amp;#39; = f_i(y_i)&lt;&#x2F;span&gt; and inputs &lt;span class=&quot;math math-inline&quot;&gt;[y_i&amp;#39;]_{\mathcal L}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The parties compute &lt;span class=&quot;math math-inline&quot;&gt;[a]_{\mathcal L} = \mathsf{decode}_{\mathcal K}([y_0&amp;#39;]_{\mathcal L},[y_1&amp;#39;]_{\mathcal L},…,[y_{n-1}&amp;#39;]_{\mathcal L})&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The key idea here is that &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{decode}_{\mathcal K}&lt;&#x2F;span&gt; is computed in &lt;span class=&quot;math math-inline&quot;&gt;\mathcal L&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; When &lt;span class=&quot;math math-inline&quot;&gt;𝕂 = 𝕃&lt;&#x2F;span&gt; and the schemes are AMSSs, does &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{decode}_{\mathcal K}&lt;&#x2F;span&gt; become a locally computable operation?&lt;&#x2F;p&gt;
&lt;h4 id=&quot;converting-between-additive-and&quot;&gt;Converting between additive &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;ℤ_2^k&lt;&#x2F;span&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; additive secret sharing scheme &lt;span class=&quot;math math-inline&quot;&gt;\mathcal A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;ℤ_2^k&lt;&#x2F;span&gt; scheme &lt;span class=&quot;math math-inline&quot;&gt;\mathcal B&lt;&#x2F;span&gt;. Take twos-complement encoding &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{bits}_k: ℤ_{2^k} → ℤ_2^k&lt;&#x2F;span&gt; and an &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-input &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-bit binary adder circuit &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{adder}_{nk}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Each party computes &lt;span class=&quot;math math-inline&quot;&gt;y_i&amp;#39; = \mathsf{bits}_k(y_i)&lt;&#x2F;span&gt; and inputs &lt;span class=&quot;math math-inline&quot;&gt;[y_i&amp;#39;]_{\mathcal B}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The parties compute &lt;span class=&quot;math math-inline&quot;&gt;[a]_{\mathcal B} = \mathsf{adder}_{nk}([y_0&amp;#39;]_{\mathcal B},[y_1&amp;#39;]_{\mathcal B},…,[y_{n-1}&amp;#39;]_{\mathcal B})&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;converting-between-and&quot;&gt;Converting between &lt;span class=&quot;math math-inline&quot;&gt;ℤ_2^k&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt;&lt;&#x2F;h4&gt;
&lt;p&gt;Convert individual bits &lt;span class=&quot;math math-inline&quot;&gt;[b_i]_{\mathcal A}&lt;&#x2F;span&gt; and compute the sum &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i ∈ [0,k)} [b_i]_{\mathcal A}⋅2^i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;double-randomness-between-rings&quot;&gt;Double randomness between rings?&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;Q&lt;&#x2F;strong&gt; Given secrets &lt;span class=&quot;math math-inline&quot;&gt;[s], [r]&lt;&#x2F;span&gt; over a ring &lt;span class=&quot;math math-inline&quot;&gt;ℤ_m&lt;&#x2F;span&gt;. Is there a protocol to compute and reveal &lt;span class=&quot;math math-inline&quot;&gt;\floor{\frac{s + r}{m}}&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;Given LSSSs with different moduli &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;, and a secret &lt;span class=&quot;math math-inline&quot;&gt;[s]_m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Parties generate double randomness &lt;span class=&quot;math math-inline&quot;&gt;[r]_m&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;[r]_k&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;r ∈ [0,m)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Parties compute &lt;span class=&quot;math math-inline&quot;&gt;[s + r]_m&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Parties reveal &lt;span class=&quot;math math-inline&quot;&gt;(s+r) \mod m&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;q = \floor{\frac{s + r}{m}}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Parties input &lt;span class=&quot;math math-inline&quot;&gt;[s + r]_k&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Parties compute &lt;span class=&quot;math math-inline&quot;&gt;[s+r]_k - [r]_k - q ⋅ m&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; How much does &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; reveal? Note that &lt;span class=&quot;math math-inline&quot;&gt;k∈\ps{0,1}&lt;&#x2F;span&gt; since &lt;span class=&quot;math math-inline&quot;&gt;s + r &amp;lt; 2⋅p&lt;&#x2F;span&gt;, so it can not be more than one bit.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The end result will be &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; reduced modulo &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;, but this is intentional.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;intra-share-matrix-multiplication&quot;&gt;Intra-share matrix multiplication&lt;&#x2F;h3&gt;
&lt;p&gt;BGW matrix multiplication&lt;&#x2F;p&gt;
&lt;p&gt;We would like a secure protocol for applying an arbitrary &lt;span class=&quot;math math-inline&quot;&gt;n×n&lt;&#x2F;span&gt; matrix to the secret shares:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec y&amp;#39; = \mat M ⋅ \vec y
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each output share can depend on each input share, so it is clear some form of communication is required here. We can use secret sharing to create shares of each share, and then use the linearity of the encoding to compute each output share, and reveal this value to the party that should hold it.&lt;&#x2F;p&gt;
&lt;p&gt;One way to achieve this is to secret share each&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Each party &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; shares it&#x27;s share &lt;span class=&quot;math math-inline&quot;&gt;y_i&lt;&#x2F;span&gt; as a secret &lt;span class=&quot;math math-inline&quot;&gt;[y_i]&lt;&#x2F;span&gt;, we now have &lt;span class=&quot;math math-inline&quot;&gt;[\vec y]&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Each party locally computes &lt;span class=&quot;math math-inline&quot;&gt;[\vec y&amp;#39;] = \mat M ⋅ [\vec y]&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The parties reveal &lt;span class=&quot;math math-inline&quot;&gt;[y_i&amp;#39;]&lt;&#x2F;span&gt; to party &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;to do.&lt;&#x2F;strong&gt; Step 3 is unnecessary and only one round is required. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;securecomputation.org&#x2F;docs&#x2F;pragmaticmpc.pdf&quot;&gt;EKR18&lt;&#x2F;a&gt; § 3.3.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q&lt;&#x2F;strong&gt; Does this generalize to other decoding matrices than ones constructed by Shamir?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multiplication-protocols&quot;&gt;Multiplication protocols&lt;&#x2F;h2&gt;
&lt;p&gt;While affine transformations are trivially locally computed in all LSSSs, to compute arbitrary functions we also need the ability to multiply two secret values &lt;span class=&quot;math math-inline&quot;&gt;[a]&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;[b]&lt;&#x2F;span&gt; to get &lt;span class=&quot;math math-inline&quot;&gt;[a⋅b]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A number of protocols exists, but they all share a perculiar feature: They first execute a round of communication to bring the parties in a specific state. This state is then consumed when do the multiplication.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;beaver-multiplication-triples&quot;&gt;Beaver multiplication triples&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;3-540-46766-1_34.pdf&quot;&gt;Bea91&lt;&#x2F;a&gt; presents a method to pre-compute a multiplication also known as &lt;em&gt;circuit randomization&lt;&#x2F;em&gt;. Generate random secrets &lt;span class=&quot;math math-inline&quot;&gt;[a]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;[b]&lt;&#x2F;span&gt; and pre-compute their product &lt;span class=&quot;math math-inline&quot;&gt;[a⋅b]&lt;&#x2F;span&gt; using any protocol. Then during the &#x27;live&#x27; phase where the parties have &lt;span class=&quot;math math-inline&quot;&gt;[x]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;[y]&lt;&#x2F;span&gt; and want to compute &lt;span class=&quot;math math-inline&quot;&gt;[x⋅y]&lt;&#x2F;span&gt;, they do the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;[x + a]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;[y + b]&lt;&#x2F;span&gt; locally.&lt;&#x2F;li&gt;
&lt;li&gt;Reveal &lt;span class=&quot;math math-inline&quot;&gt;\p{x+a}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\p{y+b}&lt;&#x2F;span&gt; it to all parties.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;[x⋅y] = \p{x + a}⋅[y] - \p{y + b}⋅[a] + [a⋅b]&lt;&#x2F;span&gt; locally.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The only live communication is revealing two secrets to all parties, which requires &lt;span class=&quot;math math-inline&quot;&gt;2⋅(n^2 -n)&lt;&#x2F;span&gt; messages. Note that the secrecy of the protocol depends on the triplet &lt;span class=&quot;math math-inline&quot;&gt;([a], [b], [a⋅b])&lt;&#x2F;span&gt; being used only once. A fresh triplet is required for each multiplication.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Can this be adapted to allow for efficient dot-products like most other protocols? I.e. can we take a linear or affine combination of products with communication complexity in the size of the result? This likely also implies consuming correspondingly fewer triples.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Some papers instead compute &lt;span class=&quot;math math-inline&quot;&gt;[x⋅y] = \p{x + a}⋅\p{y + b} - \p{x + a}⋅[b] - \p{y + b}⋅[a] + [a⋅b]&lt;&#x2F;span&gt; which also works, but requires one more multiplication.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The dotproduct protocol in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1225.pdf&quot;&gt;PSSY20&lt;&#x2F;a&gt; seems to do the sharing &lt;em&gt;after&lt;&#x2F;em&gt; computing the (intermediate) product. The intermediate is also linear, allowing them to aggregate it for efficient dot-products.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; It seems that in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1225.pdf&quot;&gt;PSSY20&lt;&#x2F;a&gt; this is generalized by considering the state where &lt;span class=&quot;math math-inline&quot;&gt;\p{x+a}&lt;&#x2F;span&gt; is cleartext and &lt;span class=&quot;math math-inline&quot;&gt;[a]&lt;&#x2F;span&gt; secret it&#x27;s own linear secret sharing scheme. They also extend it to 3,4 and &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-way multiplication by preprocessing (many) more shares, e.g. &lt;span class=&quot;math math-inline&quot;&gt;[a],[b],[c],[a⋅b],[b⋅c],[a⋅c],[a⋅b⋅c]&lt;&#x2F;span&gt; for the 3-way case.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Can any arithmetic circuit be computed one-round using LSSSs?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;replicated-sharing&quot;&gt;Replicated sharing&lt;&#x2F;h3&gt;
&lt;p&gt;From &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;bfb0054140.pdf&quot;&gt;BW98&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sciencedirect.com&#x2F;science&#x2F;article&#x2F;pii&#x2F;S0166218X05002428&quot;&gt;Mau06&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;403.pdf&quot;&gt;MR18&lt;&#x2F;a&gt;. Consider an &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt;-party additive secret sharing scheme such that the secret value is the sum of the shares, &lt;span class=&quot;math math-inline&quot;&gt;a = a_0 + a_1 + a_2&lt;&#x2F;span&gt;, then the product of two secrets is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a ⋅ b
&amp;amp;= \p{a_0 + a_1 + a_2} ⋅ \p{b_0 + b_1 + b_2} \\
&amp;amp;= \phantom{+} \p{a_0 + a_1} ⋅ \p{b_0 + b_1} - a_1 ⋅ b_1 \\
&amp;amp;\phantom{=} + \p{a_1 + a_2} ⋅ \p{b_1 + b_2} - a_2 ⋅ b_2 \\
&amp;amp;\phantom{=} + \p{a_2 + a_0} ⋅ \p{b_2 + b_0} - a_0 ⋅ b_0 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If party &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; knows the secret shares of &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;i+1&lt;&#x2F;span&gt; it can compute the &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;-th row of this product. Since these rows summed together produce the product value, they constitute valid shares for &lt;span class=&quot;math math-inline&quot;&gt;[a⋅b]&lt;&#x2F;span&gt;. This leads to the following protocol (indices are taken modulo &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;):&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Party &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; sends its shares &lt;span class=&quot;math math-inline&quot;&gt;a_i, b_i&lt;&#x2F;span&gt; to party &lt;span class=&quot;math math-inline&quot;&gt;i-1&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Party &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; computes &lt;span class=&quot;math math-inline&quot;&gt;c_i = \p{a_i + a_{i+1}}⋅\p{b_i + b_{i+1}} - a_{i+1}⋅b_{i+1}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;It is important to note that the first step reduces the treshold, as now any two parties can recover the secret where before all three where required.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; We can view the regular state and the replicated state as two different secret sharing schemes. A multiplication operation converts a replicated state into a regular one. The replication protocol re-establishes the replicated state.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; What re-randomization is required?&lt;&#x2F;p&gt;
&lt;p&gt;To generalize this to &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; parties with a threshold of &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; we need to find a number of shares &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; and an assignment to parties such that for every combination &lt;span class=&quot;math math-inline&quot;&gt;(i,j)&lt;&#x2F;span&gt; of shares at least one party has those two shares, and no fewer than &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; parties combined have all the shares. A combinatorial search gives the following as the smallest &lt;span class=&quot;math math-inline&quot;&gt;t=3&lt;&#x2F;span&gt; solution, it requires &lt;span class=&quot;math math-inline&quot;&gt;10&lt;&#x2F;span&gt; parties and &lt;span class=&quot;math math-inline&quot;&gt;5&lt;&#x2F;span&gt; shares assigned as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ps{0, 1}, \ps{0, 2}, \ps{0, 3}, \ps{0, 4},
\ps{1, 2}, \ps{1, 3}, \ps{1, 4},
\ps{2, 3}, \ps{2, 4},
\ps{3, 4}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These are the edges of the &lt;span class=&quot;math math-inline&quot;&gt;K_5&lt;&#x2F;span&gt; graph. Similarly the &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt;-party scheme is generated by the &lt;span class=&quot;math math-inline&quot;&gt;K_3&lt;&#x2F;span&gt; graph. Generally the full graph &lt;span class=&quot;math math-inline&quot;&gt;K_k&lt;&#x2F;span&gt; generates a replication protocol with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
n &amp;amp;= \frac{k⋅\p{k-1}}{2} &amp;amp;
t &amp;amp;= \ceil{\frac{k}{2}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{c|ccccccccc}
k &amp;amp; 2 &amp;amp; 3 &amp;amp; 4 &amp;amp; 5 &amp;amp; 6 &amp;amp; 7 &amp;amp; 8 &amp;amp; 9 &amp;amp; 10 \\ \hline
n &amp;amp; 1 &amp;amp; 3 &amp;amp; 6 &amp;amp; 10 &amp;amp; 15 &amp;amp; 21 &amp;amp; 28 &amp;amp; 36 &amp;amp; 45 \\
t &amp;amp; 1 &amp;amp; 2 &amp;amp; 2 &amp;amp; 3 &amp;amp; 3 &amp;amp; 4 &amp;amp; 4 &amp;amp; 5 &amp;amp; 5\\
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; How does this relate to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;841.pdf&quot;&gt;JSL21&lt;&#x2F;a&gt; § B.2? They cite in the intro &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sciencedirect.com&#x2F;science&#x2F;article&#x2F;pii&#x2F;S0166218X05002428&quot;&gt;Mau06&lt;&#x2F;a&gt; as the originator and [KRSW18], [SW19] and call the replication protocol &#x27;KRSW&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Todo.&lt;&#x2F;strong&gt; In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sciencedirect.com&#x2F;science&#x2F;article&#x2F;pii&#x2F;S0166218X05002428&quot;&gt;Mau06&lt;&#x2F;a&gt; and others each party deals their partial result to all parties, which are then summed. This has different communication complexity then the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;768.pdf&quot;&gt;AFL⁺16&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;403.pdf&quot;&gt;MR18&lt;&#x2F;a&gt; protocol where each party adds randomized zero and shares with their neighbor. The summation of terms is implicitly performed on decoding. This is distinct enough to consider them separate variants (like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;62212.62213&quot;&gt;BGW88&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.cs.mcgill.ca&#x2F;~crepeau&#x2F;PDFx&#x2F;ASPUBLISHED&#x2F;CCD88A.pdf&quot;&gt;CCD88&lt;&#x2F;a&gt; below).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;shamir-multiplication&quot;&gt;Shamir multiplication&lt;&#x2F;h3&gt;
&lt;p&gt;Consider a Shamir secret sharing schemes with &lt;span class=&quot;math math-inline&quot;&gt;\vec s&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt;. The parties have secrets &lt;span class=&quot;math math-inline&quot;&gt;[a]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;[b]&lt;&#x2F;span&gt; and wish to compute the product &lt;span class=&quot;math math-inline&quot;&gt;[c] = [a⋅b]&lt;&#x2F;span&gt;. If they locally multiply shares such that &lt;span class=&quot;math math-inline&quot;&gt;c_i = a_i ⋅ b_i&lt;&#x2F;span&gt; they have constructed a polynomial&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P_c(X) = P_a(X)⋅P_b(X) \mod \Z_{\vec x}(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\vec x}&lt;&#x2F;span&gt; is the zero polynomial such that &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\vec x}(X) = \prod_{x ∈ \vec x} \p{X - x}&lt;&#x2F;span&gt;. To get the correct results we instead need to end up with a &lt;span class=&quot;math math-inline&quot;&gt;P_c(X)&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P_c(X) = P_a(X)⋅P_b(X) \mod \Z_{\vec s}(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;62212.62213&quot;&gt;BGW88&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.cs.mcgill.ca&#x2F;~crepeau&#x2F;PDFx&#x2F;ASPUBLISHED&#x2F;CCD88A.pdf&quot;&gt;CCD88&lt;&#x2F;a&gt; it is noted this can be achieved by reducing the degrees of &lt;span class=&quot;math math-inline&quot;&gt;P_a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;P_b&lt;&#x2F;span&gt; such that their product is lower degree than &lt;span class=&quot;math math-inline&quot;&gt;\deg \Z_{\vec x} = n&lt;&#x2F;span&gt;. Denote with &lt;span class=&quot;math math-inline&quot;&gt;[–]_d&lt;&#x2F;span&gt; the Shamir scheme restricted to degree at most &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;. Then elementwise multiplication of shares &lt;span class=&quot;math math-inline&quot;&gt;[a]_k&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;[b]_l&lt;&#x2F;span&gt; results in &lt;span class=&quot;math math-inline&quot;&gt;[a⋅b]_{k+l}&lt;&#x2F;span&gt; if &lt;span class=&quot;math math-inline&quot;&gt;k+l &amp;lt; n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;62212.62213&quot;&gt;BGW88&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;129712.129780&quot;&gt;FY92&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2011&#x2F;136.pdf&quot;&gt;AL11&lt;&#x2F;a&gt; degree reduction to &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; is achieved using the &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;24&#x2F;lsss&#x2F;#intra-share-matrix-multiplication&quot;&gt;intra-share matrix multiplication&lt;&#x2F;a&gt; protocol with the matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt; given by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat M = \mat V_{\vec x} ⋅ \operatorname{diag}(\overbrace{1, 1, …, 1 }^{d+1}, \overbrace{0, 0, …, 0}^{n - d - 1})
⋅ \mat V_{\vec x}^{-1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.cs.mcgill.ca&#x2F;~crepeau&#x2F;PDFx&#x2F;ASPUBLISHED&#x2F;CCD88A.pdf&quot;&gt;CCD88&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;crypto2007&#x2F;46220565&#x2F;46220565.pdf&quot;&gt;DN07&lt;&#x2F;a&gt; the degree reduction is instead achieved under the scheme conversion protocol.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Instead of degree reduction, can we use other constraints on the scheme? The degree reduction aims to avoid the effects of the modular reduction, other schemes will instead need to correct for it. This seems like a linear problem.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Is there any way this can be made to work for non-Shamir schemes?&lt;&#x2F;p&gt;
&lt;p&gt;The minimum and maximum degree for an &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-party Shamir scheme with &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; secrets and threshold &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
s + t - 2 ≤ d ≤ n - 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The number of minimum degree secret factors that can be multiplied before the product exceeds the degree capacity of the parameters is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\floor{\frac{n - 1}{s + t - 2}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some optimal small-&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; parameter choices are:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{c|c:cc:ccc:}
n                &amp;amp; 2 &amp;amp; 3 &amp;amp; 3 &amp;amp; 4 &amp;amp; 4 &amp;amp; 4 &amp;amp; 5 &amp;amp; 5 &amp;amp; 5 &amp;amp; 5\\
s                &amp;amp; 1 &amp;amp; 1 &amp;amp; 2 &amp;amp; 1 &amp;amp; 2 &amp;amp; 3 &amp;amp; 1 &amp;amp; 1 &amp;amp; 2 &amp;amp; 4\\
t                &amp;amp; 2 &amp;amp; 2 &amp;amp; 2 &amp;amp; 2 &amp;amp; 3 &amp;amp; 2 &amp;amp; 2 &amp;amp; 3 &amp;amp; 2 &amp;amp; 2\\
\hline
d_{\min}         &amp;amp; 1 &amp;amp; 1 &amp;amp; 2 &amp;amp; 1 &amp;amp; 3 &amp;amp; 3 &amp;amp; 1 &amp;amp; 2 &amp;amp; 2 &amp;amp; 4 \\
d_{\max}         &amp;amp; 1 &amp;amp; 2 &amp;amp; 2 &amp;amp; 3 &amp;amp; 3 &amp;amp; 3 &amp;amp; 4 &amp;amp; 4 &amp;amp; 4 &amp;amp; 4 \\
n_{\mathrm{mul}} &amp;amp; 1 &amp;amp; 2 &amp;amp; 1 &amp;amp; 3 &amp;amp; 1 &amp;amp; 1 &amp;amp; 4 &amp;amp; 2 &amp;amp; 2 &amp;amp; 1 \\
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; What if we have an &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt;-multi secret where we want to multiply all &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; against the same value, encoded as a &lt;span class=&quot;math math-inline&quot;&gt;s=1&lt;&#x2F;span&gt; secret? We can alternatively encode it as a &lt;span class=&quot;math math-inline&quot;&gt;s=2&lt;&#x2F;span&gt; secret with the constraint that both are identical. This constraint acts much like a degree reduction. Then in the &lt;span class=&quot;math math-inline&quot;&gt;n=4, t=2&lt;&#x2F;span&gt; case we could multiply an &lt;span class=&quot;math math-inline&quot;&gt;s=2&lt;&#x2F;span&gt; secret times an (repeated) &lt;span class=&quot;math math-inline&quot;&gt;s=1&lt;&#x2F;span&gt; secret.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Extensions like multi-variate polynomials, Hermite interpolation and recursive Shamir schemes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.mit.edu&#x2F;6.857&#x2F;OldStuff&#x2F;Fall03&#x2F;ref&#x2F;Shamir-HowToShareASecret.pdf&quot;&gt;Sha79&lt;&#x2F;a&gt; Adi Shamir (1979). How to Share a Secret.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.cs.mcgill.ca&#x2F;~crepeau&#x2F;PDFx&#x2F;ASPUBLISHED&#x2F;CCD88A.pdf&quot;&gt;CCD88&lt;&#x2F;a&gt; David Chaum, Claude Crépeau, Ivan Damgård (1988). Multiparty unconditionally secure protocols.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;62212.62213&quot;&gt;BGW88&lt;&#x2F;a&gt; Michael Ben-Or, Shafi Goldwasser, Avi Wigderson (1988). Completeness theorems for non-cryptographic fault-tolerant distributed computation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;3-540-46766-1_34.pdf&quot;&gt;Bea91&lt;&#x2F;a&gt; Donald Beaver (1991). Efficient Multiparty Protocols Using Circuit Randomization.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;129712.129780&quot;&gt;FY92&lt;&#x2F;a&gt; Matthew Franklin, Moti Yung (1992). Communication complexity of secure computation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;bfb0054140.pdf&quot;&gt;BW98&lt;&#x2F;a&gt; Donald Beaver, Avishai Wool (1998). Quorum-based multi-party computations.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;eurocrypt2001&#x2F;20450279.pdf&quot;&gt;CDN01&lt;&#x2F;a&gt; Ronald Cramer, Ivan Damgård, Jesper B. Nielsen (2001). Multiparty Computation from Threshold Homomorphic Encryption.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;crypto2007&#x2F;46220565&#x2F;46220565.pdf&quot;&gt;DN07&lt;&#x2F;a&gt; Ivan Damgård, Jesper Buus Nielsen (2007). Scalable and Unconditionally Secure Multiparty Computation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;tcc2008&#x2F;49480207&#x2F;49480207.pdf&quot;&gt;BH08&lt;&#x2F;a&gt; Zuzana Beerliová-Trubíniová, Martin Hirt (2008). Perfectly-Secure MPC with Linear Communication Complexity.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2011&#x2F;136.pdf&quot;&gt;AL11&lt;&#x2F;a&gt; Gilad Asharov, Yehuda Lindell (2011). A Full Proof of the BGW Protocol for Perfectly-Secure Multiparty Computation&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;dk&#x2F;universitypress&#x2F;subjects&#x2F;computer-science&#x2F;cryptography-cryptology-and-coding&#x2F;secure-multiparty-computation-and-secret-sharing&quot;&gt;CDN15&lt;&#x2F;a&gt; Ronald Cramer, Ivan Bjerre Damgård, Jesper Buus Nielsen (2015). Secure Multiparty Computation and Secret Sharing.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;768.pdf&quot;&gt;AFL⁺16&lt;&#x2F;a&gt; Toshinori Araki, Jun Furukawa, Yehuda Lindell, Ariel Nof, and Kazuma Ohara (2016) High-Throughput Semi-Honest Secure Three-Party Computation with an Honest Majority.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;403.pdf&quot;&gt;MR18&lt;&#x2F;a&gt; Payman Mohassel and Peter Rindal (2018). ABY3: A Mixed Protocol Framework for Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;securecomputation.org&#x2F;docs&#x2F;pragmaticmpc.pdf&quot;&gt;EKR18&lt;&#x2F;a&gt; David Evans, Vladimir Kolesnikov, Mike Rosulek (2018). A Pragmatic Introduction to Secure Multi-Party Computation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;134.pdf&quot;&gt;GS20&lt;&#x2F;a&gt; Vipul Goyal, Yifan Song (2020). Malicious Security Comes Free in Honest-Majority MPC.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;754.pdf&quot;&gt;CGG⁺20&lt;&#x2F;a&gt; Arka Rai Choudhuri, Aarushi Goel, Matthew Green, Abhishek Jain, Gabriel Kaptchuk (2020). Fluid MPC: Secure Multiparty Computation with Dynamic Participants.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;189.pdf&quot;&gt;GSZ20&lt;&#x2F;a&gt; Vipul Goyal, Yifan Song, and Chenzhi Zhu (2020). Guaranteed Output Delivery Comes Free in Honest Majority MPC.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;841.pdf&quot;&gt;JSL21&lt;&#x2F;a&gt; Robin Jadoul, Nigel P. Smart, Barry Van Leeuwen (2021). MPC for &lt;span class=&quot;math math-inline&quot;&gt;\mathcal Q_2&lt;&#x2F;span&gt; Access Structures over Rings and Field.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;062.pdf&quot;&gt;Esc23&lt;&#x2F;a&gt; Daniel Escudero (2023). An Introduction to Secret-Sharing-Based Secure Multiparty Computation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1225.pdf&quot;&gt;PSSY20&lt;&#x2F;a&gt; Arpita Patra, Thomas Schneider, Ajith Suresh, and Hossein Yalame (2020). ABY2.0: Improved Mixed-Protocol Secure Two-Party Computation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2015&#x2F;931.pdf&quot;&gt;MRZ15&lt;&#x2F;a&gt; Payman Mohassel, Mike Rosulek, and Ye Zhang (2015). Fast and Secure Three-party Computation: The Garbled Circuit Approach.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;396.pdf&quot;&gt;MZ17&lt;&#x2F;a&gt; Payman Mohassel and Yupeng Zhang (2017). SecureML: A System for Scalable Privacy-Preserving Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;1315.pdf&quot;&gt;CRS19&lt;&#x2F;a&gt; Harsh Chaudhari, Rahul Rachuri, and Ajith Suresh (2019). Trident: Efficient 4PC Framework for Privacy Preserving Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;1365.pdf&quot;&gt;BCPS19&lt;&#x2F;a&gt; Megha Byali, Harsh Chaudhari, Arpita Patra, and Ajith Suresh (2019). FLASH: Fast and Robust Framework for Privacy-preserving Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;042.pdf&quot;&gt;PS20&lt;&#x2F;a&gt; Arpita Patra and Ajith Suresh (2020). BLAZE: Blazing Fast Privacy-Preserving Machine Learning.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;pdf.sciencedirectassets.com&#x2F;271602&#x2F;1-s2.0-S0166218X05X03134&#x2F;1-s2.0-S0166218X05002428&#x2F;main.pdf&lt;&#x2F;p&gt;
&lt;p&gt;D. Beaver, A. Wool, , Advances in Cryptology—EUROCRYPT ’98, Lecture Notes in Computer
Science, vol. 1403, Springer, Berlin, 1998, pp. 25–35.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;872&quot;&gt;ACD⁺19&lt;&#x2F;a&gt; Mark Abspoel, Ronald Cramer, Ivan Damgård, Daniel Escudero, and Chen Yuan (2019). Efficient Information-Theoretic Secure Multiparty Computation over &lt;span class=&quot;math math-inline&quot;&gt;\mathbb{Z}&#x2F;p^k \mathbb{Z}&lt;&#x2F;span&gt; via Galois Rings.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;260.pdf
https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;1025.pdf&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1080&#x2F;09720529.2000.10697897&quot;&gt;EIP00&lt;&#x2F;a&gt; Michele Elia, J. Carmelo Interlando, and Reginaldo Palazzo Jr. (2000) Computing the reciprocal of units in Galois rings.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cholesky decomposition</title>
        <published>2024-02-18T00:00:00+00:00</published>
        <updated>2024-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/cholesky/"/>
        <id>https://2π.com/24/cholesky/</id>
        
        <content type="html" xml:base="https://2π.com/24/cholesky/">&lt;h1 id=&quot;cholesky-decomposition&quot;&gt;Cholesky decomposition&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\mat#1{\mathrm #1}
\gdef\T{\mathrm T}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Positive definite matrices occur as covariance matrices. Given a positive definite matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt; it can be factored into a triangular matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat L&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat M = \mat L ⋅ \mat L^\T
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;computing-the-cholesky-decompostion&quot;&gt;Computing the Cholesky decompostion&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cholesky_decomposition#The_Cholesky_algorithm&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cholesky_decomposition#The_Cholesky%E2%80%93Banachiewicz_and_Cholesky%E2%80%93Crout_algorithms&lt;&#x2F;p&gt;
&lt;p&gt;A reasonably efficient way to compute it is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; cholesky&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;M&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    L&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;tril&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;M&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:,:&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;].&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;T&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;sqrt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; L&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But it&#x27;s more efficient to use the LAPACK &lt;code&gt;dpotrf&lt;&#x2F;code&gt; function, available as &lt;code&gt;np.linalg.cholesky&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;netlib.org&#x2F;lapack&#x2F;explore-html&#x2F;d2&#x2F;d09&#x2F;group__potrf_ga84e90859b02139934b166e579dd211d4.html#ga84e90859b02139934b166e579dd211d4&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; cholesky_update&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;sqrt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:])&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;        x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; cholesky_subset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    L&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;copy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; range&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;        if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;            cholesky_update&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:],&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;ix_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;subset-of-cholesky&quot;&gt;Subset of Cholesky&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;algowiki-project.org&#x2F;en&#x2F;Cholesky_decomposition&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cs.utexas.edu&#x2F;users&#x2F;flame&#x2F;Notes&#x2F;NotesOnCholReal.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cs.utexas.edu&#x2F;users&#x2F;flame&#x2F;pubs&#x2F;flawn41.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;christian-igel.github.io&#x2F;paper&#x2F;AMERCMAUfES.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;scipy&#x2F;scipy&#x2F;issues&#x2F;8188&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;link.springer.com&#x2F;article&#x2F;10.1007&#x2F;BF01933218&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gaussian Process inference</title>
        <published>2024-02-18T00:00:00+00:00</published>
        <updated>2024-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/guassian-process/"/>
        <id>https://2π.com/24/guassian-process/</id>
        
        <content type="html" xml:base="https://2π.com/24/guassian-process/">&lt;h1 id=&quot;gaussian-process-inference&quot;&gt;Gaussian Process inference&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\N{\mathcal N}
\gdef\vec#1{\bm #1}
\gdef\mat#1{\mathrm #1}
\gdef\k{\mathrm k}
\gdef\u{\mathrm u}
\gdef\c{\mathrm c}
\gdef\T{\mathrm T}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;\vec μ&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mat Σ&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; is multivariate normal distributed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P\p{\vec y} ∼ \N\p{\vec μ, \mat Σ}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a draw of standard normal individually independent values &lt;span class=&quot;math math-inline&quot;&gt;\vec n&lt;&#x2F;span&gt;, we can transform this to a draw from &lt;span class=&quot;math math-inline&quot;&gt;\N\p{\vec μ, \mat Σ}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec y = \vec μ + \mat L \cdot \vec n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\mat L&lt;&#x2F;span&gt; is the Cholesky factor such that &lt;span class=&quot;math math-inline&quot;&gt;\mat L ⋅ \mat L^{\T} = \mat Σ&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;computing-the-cholesky-decompostion&quot;&gt;Computing the Cholesky decompostion&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cholesky_decomposition#The_Cholesky_algorithm&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cholesky_decomposition#The_Cholesky%E2%80%93Banachiewicz_and_Cholesky%E2%80%93Crout_algorithms&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;do i = 1, size(A,1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    L(i,i) = sqrt(A(i,i) - dot_product(L(i,1:i-1), L(i,1:i-1)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    L(i+1:,i) = (A(i+1:,i) - matmul(conjg(L(i,1:i-1)), L(i+1:,1:i-1))) &#x2F; L(i,i)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;end do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;inversion-using-cholesky&quot;&gt;Inversion using Cholesky&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;inference&quot;&gt;Inference&lt;&#x2F;h3&gt;
&lt;p&gt;Supposed we know a subset of values &lt;span class=&quot;math math-inline&quot;&gt;\vec y_{\mathrm k}&lt;&#x2F;span&gt; and we want to use this to infer about the remaining unknown values &lt;span class=&quot;math math-inline&quot;&gt;\vec y_{\mathrm u}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P\p{\vec y_{\u} \vert \vec y_{\k}} ∼ \N\p{\vec μ_{\c}, \mat Σ_{\c}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is again normally distributed with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\vec μ_{\c} &amp;amp;= \vec μ_{\u} + Σ_{\k\u}⋅Σ_{\k\k}^{-1}⋅ \p{\vec y_{\k} - \vec μ_{\k}} \\
\mat Σ_{\c} &amp;amp;= \mat Σ_{\u\u} - Σ_{\u\k}⋅Σ_{\k\k}^{-1}⋅ \mat Σ_{\k\u}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;{}_\k&lt;&#x2F;span&gt; represents known indices and &lt;span class=&quot;math math-inline&quot;&gt;{}_\u&lt;&#x2F;span&gt; the unknown indices. To avoid inverting we want to re-use &lt;span class=&quot;math math-inline&quot;&gt;\mat L&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the second matrix is also kind of an update:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat Σ_{\c} = \mat Σ_{\u\u} - Σ_{\u\k} ⋅ \p{\mat L_{\k\k} ⋅  \mat L_{\k\k}^\T}^{-1} ⋅ \mat Σ_{\u\k}^\T
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;efficient-computation&quot;&gt;Efficient computation&lt;&#x2F;h3&gt;
&lt;p&gt;Suppose we know &lt;span class=&quot;math math-inline&quot;&gt;\mat L&lt;&#x2F;span&gt;. Can we use this to quickly compute &lt;span class=&quot;math math-inline&quot;&gt;\mat L_{\k\k}&lt;&#x2F;span&gt;? This amounts to computing the Cholesky factor of a subset of the matrix. This can be done using repeated single-row deletion update:&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cholesky_decomposition#Adding_and_removing_rows_and_columns&lt;&#x2F;p&gt;
&lt;p&gt;Can we also compute &lt;span class=&quot;math math-inline&quot;&gt;\mat L_{\c}&lt;&#x2F;span&gt; efficiently?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Lookup arguments</title>
        <published>2024-02-18T00:00:00+00:00</published>
        <updated>2024-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/lookup/"/>
        <id>https://2π.com/24/lookup/</id>
        
        <content type="html" xml:base="https://2π.com/24/lookup/">&lt;h1 id=&quot;lookup-arguments&quot;&gt;Lookup arguments&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\vec#1{\bm{#1}}
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\set#1{\mathcal{#1}}
\gdef\mset#1{\mathrm{#1}}
\gdef\g{\mathrm{g}}
\gdef\F{\mathbb{F}}
\gdef\S{\mathcal S}
\gdef\X{\mathcal X}
\gdef\Z{\mathrm{Z}}
\gdef\∀{\mathop{\huge ∀}\limits}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zero-polynomials&quot;&gt;Zero polynomials&lt;&#x2F;h2&gt;
&lt;p&gt;Given a multiset &lt;span class=&quot;math math-inline&quot;&gt;\mset A&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;𝔽&lt;&#x2F;span&gt; define the zero polynomial &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\mset A} ∈ 𝔽[X]&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\mset A}(X) = \prod_{a ∈ \mset A} \p{X - a}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively using the base set &lt;span class=&quot;math math-inline&quot;&gt;\set A ⊆ 𝔽&lt;&#x2F;span&gt; and multiplicities &lt;span class=&quot;math math-inline&quot;&gt;m_A: 𝔽 → ℕ&lt;&#x2F;span&gt; we can collect factors&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\mset A}(X) = \prod_{a ∈ 𝔽} \p{X - a}^{m_A(a)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To guarantee uniqueness we require &lt;span class=&quot;math math-inline&quot;&gt;m_A(a) &amp;lt; p&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; is the characteristic of &lt;span class=&quot;math math-inline&quot;&gt;𝔽&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Logarithmic_derivative&quot;&gt;logarithmic derivative&lt;&#x2F;a&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\mset A}&lt;&#x2F;span&gt; has the curious property that all zeros turn into pole,s perserving multiplicities:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\Z_{\mset A}&amp;#39;(X)}{\Z_{\mset A}(X)} = \sum_{a ∈ \mset A} \frac{1}{X - a} = \sum_{a ∈ \set A} \frac{m_A(a)}{X - a}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;aurora-lemma&quot;&gt;Aurora lemma&lt;&#x2F;h2&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;H ⊆ 𝔽&lt;&#x2F;span&gt; be a multiplicative subgroup of size &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, then for &lt;span class=&quot;math math-inline&quot;&gt;f ∈ 𝔽_{&amp;lt;n}[X]&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{x ∈ H} f(x) = n ⋅ f(0)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This follows from the non-zero elements of &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt; being &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th roots of unity, that sum to zero for &lt;span class=&quot;math math-inline&quot;&gt;n&amp;gt;1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{x ∈ H} x^k = \begin{cases}
n &amp;amp; k = 0 \mod \p{n - 1} \\
0 &amp;amp; \text{otherwise}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fk-lemma&quot;&gt;FK lemma&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;cached-quotients&quot;&gt;Cached Quotients&lt;&#x2F;h2&gt;
&lt;p&gt;Cached quotiens (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1763.pdf&quot;&gt;EFG22&lt;&#x2F;a&gt;) builds on a series of prior protocols &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1530.pdf&quot;&gt;H22&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;621.pdf&quot;&gt;ZBK+22&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;957.pdf&quot;&gt;PAK22&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1447.pdf&quot;&gt;GK22&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1565.pdf&quot;&gt;ZGK+22&lt;&#x2F;a&gt;. We want to proof that some &lt;span class=&quot;math math-inline&quot;&gt;f ∈ \F[X]&lt;&#x2F;span&gt; evaluates to values in a certain set &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; on a domain &lt;span class=&quot;math math-inline&quot;&gt;\X&lt;&#x2F;span&gt;, i.e.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\∀_{x \in \X}\quad f(x) \in \S
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1530.pdf&quot;&gt;H22&lt;&#x2F;a&gt; it is shown that this holds if and only if there exists &lt;span class=&quot;math math-inline&quot;&gt;m_s ∈ \F&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{x ∈ \X} \frac{1}{X + f(x)} = \sum_{s ∈ \S} \frac{m_s}{X + s}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This follows from the uniqueness of the fractional decomposition and the observation that the values of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;\X&lt;&#x2F;span&gt; should differ only in multiplicities form &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;, where the multiplicity can also be zero.&lt;&#x2F;p&gt;
&lt;p&gt;This rational identity can be checked by evaluating in a random &lt;span class=&quot;math math-inline&quot;&gt;x ∈ 𝔽&lt;&#x2F;span&gt;. Computing polynomial commitments to either side is not a problem as they both only have &lt;span class=&quot;math math-inline&quot;&gt;|\set X|&lt;&#x2F;span&gt; non-zero terms. The challenge is to show that the commitment to the right hand side is computed correctly.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A(X) ⋅ \p{T(X) + x} - m(X) = Q_A(X) ⋅ \Z_{\set Y}(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;T(X)&lt;&#x2F;span&gt; evaluates to &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt; on the domain &lt;span class=&quot;math math-inline&quot;&gt;\set Y&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setup&quot;&gt;Setup&lt;&#x2F;h3&gt;
&lt;p&gt;Given elliptic curve pairing &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{e}:𝔾_1 × 𝔾_2 → 𝔾_T&lt;&#x2F;span&gt; with generators &lt;span class=&quot;math math-inline&quot;&gt;\g_1 ∈ 𝔾_1, \g_2 ∈ 𝔾_2, \g_T ∈ 𝔾_T&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Pick secret &lt;span class=&quot;math math-inline&quot;&gt;s ∈ 𝔽&lt;&#x2F;span&gt; and compute &lt;span class=&quot;math math-inline&quot;&gt;\p{s^0, …, s^{n-1}}⋅\g_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\p{s^0, …, s^n}⋅\g_2&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\set Y}(s)⋅\g_2&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;T(x)⋅\g_2&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;T(X) = \sum_{i ∈ [0,N)} s_i ⋅ \mathrm L_i(x)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;$$&lt;&#x2F;p&gt;
&lt;p&gt;$$&lt;&#x2F;p&gt;
&lt;h2 id=&quot;logup&quot;&gt;logUp&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;lasso-lookups&quot;&gt;Lasso lookups&lt;&#x2F;h2&gt;
&lt;p&gt;For fixed sparse matrix &lt;span class=&quot;math math-inline&quot;&gt;\mathrm M&lt;&#x2F;span&gt; and committed vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; show:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathrm M ⋅ \vec v = \vec a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1530.pdf&quot;&gt;H22&lt;&#x2F;a&gt; Ulrich Haböck (2022). Multivariate lookups based on logarithmic derivatives.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;621.pdf&quot;&gt;ZBK+22&lt;&#x2F;a&gt; Arantxa Zapico, Vitalik Buterin, Dmitry Khovratovich, Mary Maller, Anca Nitulescu, Mark Simkin (2022). Caulk: Lookup Arguments in Sublinear Time.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;957.pdf&quot;&gt;PAK22&lt;&#x2F;a&gt; Jim Posen, Assimakis A. Kattis (2022). Caulk+: Table-independent lookup arguments.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1447.pdf&quot;&gt;GK22&lt;&#x2F;a&gt; Ariel Gabizon, Dmitry Khovratovich (2022). flookup: Fractional decomposition-based lookups in quasi-linear time independent of table size.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1565.pdf&quot;&gt;ZGK+22&lt;&#x2F;a&gt; Arantxa Zapico, Ariel Gabizon, Dmitry Khovratovich, Mary Maller, Carla Ràfols (2022). Baloo: Nearly Optimal Lookup Arguments.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1763.pdf&quot;&gt;EFG22&lt;&#x2F;a&gt; Liam Eagen, Dario Fiore, Ariel Gabizon (2022). cq: Cached quotients for fast lookups.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;033.pdf&quot;&gt;FK23&lt;&#x2F;a&gt; Dankrad Feist, Dmitry Khovratovich (2023). Fast amortized KZG proofs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;066.pdf&quot;&gt;ABTD23&lt;&#x2F;a&gt; Alexandr Bulkin, Tim Dokchitser (2023). Plonkup scheme with multiple queries.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1216.pdf&quot;&gt;STW23&lt;&#x2F;a&gt; Srinath Setty, Justin Thaler, Riad Wabby (2023). Unlocking the lookup singularity with Lasso.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1518.pdf&quot;&gt;CFF+23&lt;&#x2F;a&gt; Matteo Campanelli , Antonio Faonio , Dario Fiore , Tianyu Li , Helger Lipmaa (2023). Lookup Arguments: Improvements, Extensions and Applications to Zero-Knowledge Decision Trees.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1284.pdf&quot;&gt;PH23&lt;&#x2F;a&gt; Shahar Papini, Ulrich Haböck (2023). Improving logarithmic derivative lookups using GKR.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Multi-party Computation notes.</title>
        <published>2024-02-18T00:00:00+00:00</published>
        <updated>2024-02-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/mpc-notes/"/>
        <id>https://2π.com/24/mpc-notes/</id>
        
        <content type="html" xml:base="https://2π.com/24/mpc-notes/">&lt;h1 id=&quot;multi-party-computation-notes&quot;&gt;Multi-party Computation notes.&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\ps#1{\delim\{{#1}\}}
\gdef\box#1{\delim[{#1}]}
\gdef\bbox#1{\mathopen{[\mkern-3mu[}{#1}\mathclose{]\mkern-3mu]}}
\gdef\set#1{\mathcal{#1}}
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;em&gt;Secure Multi-Party Computation Scheme&lt;&#x2F;em&gt; (MPC) allows a set of parties &lt;span class=&quot;math math-inline&quot;&gt;\set P&lt;&#x2F;span&gt; to compute a function over inputs while keeping the inputs secret.&lt;&#x2F;p&gt;
&lt;p&gt;MPC is a family of related protocols, with slightly different security guarantees. You can compare this to proving protocols being zero-knowledge or not, except in MPC there are more dimensions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;properties-of-mpc-schemes&quot;&gt;Properties of MPC schemes&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Arithmetization&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Boolean. Including bitvectors.&lt;&#x2F;li&gt;
&lt;li&gt;Ring. Often &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;k∈\{8,16,32,64\}&lt;&#x2F;span&gt; to use computer native integers.&lt;&#x2F;li&gt;
&lt;li&gt;Field.&lt;&#x2F;li&gt;
&lt;li&gt;Mixed. Efficient switching between different schemes.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Network&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Synchronous: Any message not arriving on time means the sender is corrupt.&lt;&#x2F;li&gt;
&lt;li&gt;Asynchronous: Eventually delivered. Messages between parties can get arbitrarily delayed and arrive out of order.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Corruption capacity.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Threshold: The protocol provides it&#x27;s guarantees as long as &lt;span class=&quot;math math-inline&quot;&gt;≤ t&lt;&#x2F;span&gt; parties are corrupt.&lt;&#x2F;li&gt;
&lt;li&gt;Non-threshold: The protocol is robust against specific subsets of parties colluding. (An &lt;em&gt;adversary structure&lt;&#x2F;em&gt;).
&lt;ul&gt;
&lt;li&gt;Note: Threshold is a special case where the adversary structure contains all subsets of &lt;span class=&quot;math math-inline&quot;&gt;\set P&lt;&#x2F;span&gt; of size &lt;span class=&quot;math math-inline&quot;&gt;≤ t&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Corruption power:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Cryptographically secure. Security relies on cryptographic hard problems.&lt;&#x2F;li&gt;
&lt;li&gt;Unconditional secure. Security derives from information-theoretic arguments. (&lt;strong&gt;Note:&lt;&#x2F;strong&gt; This assumes secure communication channels between parties.)
&lt;ul&gt;
&lt;li&gt;Statistically secure. There is a non-zero error probability.&lt;&#x2F;li&gt;
&lt;li&gt;Perfectly secure. The protocol is always secure.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Input privacy:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Nothing about the inputs can be learned from observing the messages.&lt;&#x2F;li&gt;
&lt;li&gt;Nothing about the inputs can be learned from the state of a single party?&lt;&#x2F;li&gt;
&lt;li&gt;Nothing about the inputs can be learned from protocol deviation by a single party?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Correctness:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Colluding parties can affect the outcome. (In what way?)&lt;&#x2F;li&gt;
&lt;li&gt;Output manipulation is detected and the protocol will abort.&lt;&#x2F;li&gt;
&lt;li&gt;Output manipulation is detected and corrected, the output will always be correct.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Semi-honest.&lt;&#x2F;strong&gt; All parties follow the protocol correctly but are curious. This means that while they will not deviate from the defined steps of the protocol, they may try to learn additional information from the data they observe during the execution of the protocol.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Malicious-security.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Question: Does this mean a single malicious actor can affect the outcome undetected, but never learn the secret?&lt;&#x2F;p&gt;
&lt;p&gt;Semi-honest three party computation.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Secure_multi-party_computation&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m considering a series of MPC protocol following [AFL+16], &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;396.pdf&quot;&gt;MZ17&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;403.pdf&quot;&gt;MR18&lt;&#x2F;a&gt;. These are called ABY protocols as they convert between arithmetic, binary and Yao representations. I will skip the Yao representation as it is not necessary for completeness and only adds better performance for&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;linear-secret-sharing-schemes&quot;&gt;Linear Secret Sharing Schemes&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A Secret Sharing Scheme (SSS) is a set of two protocols:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Distribution&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Reconstruction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;In Distribution, a dealer takes a secret s and distribute it to n parties. In Reconstruction, a subset of the parties reveal their secret shares in order to learn the secret s. It is guaranteed that if disallowed sets of parties will not be able to learn anything about the original secret.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A Secret Sharing Scheme is associated to an Access Structure, this is the set of sets of parties which can recover the secret (or equivalently the set of sets of parties which cannot access the secret). Access structures are always monotonically increasing, i.e. if you add a party to a set which can access the secret then the bigger set can also access the secret. There are a number of different methods to perform secret sharing.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;In multi-party computation we are usually interested in so-called Linear Secret Sharing Schemes (LSSSs) as they allow parties to locally compute linear functions of their secrets for free.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SHAMIR SECRET SHARING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;In Shamir Secret Sharing the number of parties which can be adversarial t is a threshold of the total number of parties n. In multi-party computation protocols one usually has either t&amp;lt;n&#x2F;2 or t&amp;lt;n&#x2F;3. Shamir is a form of LSSS, and usually the one used to introduce concepts in introductory courses.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;REPLICATED SECRET SHARING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Another popular LSSS scheme is called Replicated Secret Sharing, this is less efficient (usually) than Shamir Sharing for threshold structures. However, with Replicated Secret Sharing one is able to represent any access structure.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FULL THRESHOLD SECRET SHARING&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The simplest secret sharing scheme is one in which all parties need to come together to recover the secret. This form of sharing is the basis of almost all multi-party computation protocols in the dishonest majority setting. In this secret sharing each party P_i has a value x_i with the actual secret being x = x_1 + ... + x_n.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;https:&#x2F;&#x2F;wiki.mpcalliance.org&#x2F;Shamir%20Secret%20Sharing.html&lt;&#x2F;p&gt;
&lt;p&gt;Note: Creating a random zero alsoa useful operation.&lt;&#x2F;p&gt;
&lt;p&gt;In an LSSS we have encoded &lt;span class=&quot;math math-inline&quot;&gt;[x]&lt;&#x2F;span&gt; such that we can locally compute &lt;span class=&quot;math math-inline&quot;&gt;[a] + [b]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;c⋅[a]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Affine transformation&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Or generally we can compute any affine transformation of the secrets locally &lt;span class=&quot;math math-inline&quot;&gt;\mat A⋅[\vec x]+\vec b&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Multiplication&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Then we can do a round of multiplications as an affine bilinear algorithm:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat C ⋅ \left( \left(\mat A⋅[\vec x]+\vec a\right) ∘ \left(\mat B⋅[\vec x]+\vec b\right)\right) + \vec c
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the replicated scheme, multiplication converts from replicated to un-replicated form.&lt;&#x2F;p&gt;
&lt;p&gt;This can be un-done by replicating the results again.&lt;&#x2F;p&gt;
&lt;p&gt;The inverse transform, from replicated to plain shares is trivially forgetting shares.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multiplication&quot;&gt;Multiplication&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;beaver-triples&quot;&gt;Beaver Triples&lt;&#x2F;h3&gt;
&lt;p&gt;Assume the&lt;&#x2F;p&gt;
&lt;h3 id=&quot;replicated-shares&quot;&gt;Replicated shares&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;shamir&quot;&gt;Shamir&lt;&#x2F;h3&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;additive-mpc&quot;&gt;Additive MPC&lt;&#x2F;h2&gt;
&lt;p&gt;Given a group &lt;span class=&quot;math math-inline&quot;&gt;𝔾&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; shares &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ 𝔾^n&lt;&#x2F;span&gt;, we can define a linear encoding such that for values &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt;, randomness &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; we have:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
    \mat M_v \\ \mat M_r \\ \mat M_c
\end{bmatrix} ⋅
\begin{bmatrix}
    \vec x\\ 1
\end{bmatrix} =
\begin{bmatrix}
    \vec v \\ \vec r \\ \vec 0
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\mat M&lt;&#x2F;span&gt; is matrix with linearly independent rows.&lt;&#x2F;p&gt;
&lt;p&gt;For example the scheme below is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
    1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 0 \\
    \hline
    1 &amp;amp; -1 &amp;amp; 0 &amp;amp; 0 \\
    0 &amp;amp; 1 &amp;amp; -1 &amp;amp; 0 \\
\end{bmatrix} ⋅
\begin{bmatrix}
    x_0 \\ x_1 \\ x_2 \\ 1
\end{bmatrix} =
\begin{bmatrix}
    v \\ r_0 \\ r_1 
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;TODO: This &lt;span class=&quot;math math-inline&quot;&gt;\mat M_r&lt;&#x2F;span&gt; matrix is arbitrary, it can be any &lt;span class=&quot;math math-inline&quot;&gt;2 × 3&lt;&#x2F;span&gt; matrix.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;arithmetic-encoding&quot;&gt;Arithmetic encoding&lt;&#x2F;h2&gt;
&lt;p&gt;Given a ring &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;x∈ℤ_{2^k}&lt;&#x2F;span&gt;.v&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
⟦x⟧ = (x_0, x_1, x_2) \text{ s.t. } x = x_0 + x_1 + x_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each paricipant receives &lt;em&gt;two&lt;&#x2F;em&gt; shares &lt;span class=&quot;math math-inline&quot;&gt;(x_i, x_{i+1})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that each value has &lt;span class=&quot;math math-inline&quot;&gt;2^{2⋅k}&lt;&#x2F;span&gt; valid encodings.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Zero.&lt;&#x2F;strong&gt; A share for zero can be generated by producing three random numbers &lt;span class=&quot;math math-inline&quot;&gt;r_i&lt;&#x2F;span&gt; and computing&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
⟦0⟧ = (r_0 - r_1, r_1 - r_2, r_2 - r_0)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This can be done locally if each participant has a pseudo-random number generator for &lt;span class=&quot;math math-inline&quot;&gt;r_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r_{i+1}&lt;&#x2F;span&gt;, so at least 3 participants are required for security.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Encoding.&lt;&#x2F;strong&gt; To encode a cleartext value &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
⟦n⟧ = (n, 0, 0)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Idea:&lt;&#x2F;strong&gt; Since &lt;span class=&quot;math math-inline&quot;&gt;3^{-1}&lt;&#x2F;span&gt; always exists in &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; we could do &lt;span class=&quot;math math-inline&quot;&gt;(n,n,n)&#x2F;3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Mixed addition.&lt;&#x2F;strong&gt; Adding a cleartext value &lt;span class=&quot;math math-inline&quot;&gt;a ∈ ℤ_{2^k}&lt;&#x2F;span&gt; can be done by adding &lt;span class=&quot;math math-inline&quot;&gt;(x_0 + a, x_1, x_2)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Mixed multiplication.&lt;&#x2F;strong&gt; Multiplying by a cleartext value &lt;span class=&quot;math math-inline&quot;&gt;a ∈ ℤ_{2^k}&lt;&#x2F;span&gt; can be done by adding &lt;span class=&quot;math math-inline&quot;&gt;(a⋅x_0, b⋅x_1, c⋅x_2)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Addition.&lt;&#x2F;strong&gt; The sum of two shares can be computed locally&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
⟦x⟧ + ⟦y⟧ = (x_0 + y_0, x_1 + y_1, x_2 + y_2)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Multiplication.&lt;&#x2F;strong&gt; For multiplication $⟦z⟧ = ⟦x⟧ ⋅ ⟦y⟧ $ we need to find a &lt;span class=&quot;math math-inline&quot;&gt;(z_0, z_1, z_2)&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
z_0 + z_1 + z_2 &amp;amp;= \p{x_0 + x_1 + x_2} ⋅ \p{y_0 + y_1 + y_2} \\
&amp;amp;= x_0 ⋅ y_0 + x_1 ⋅ y_0 + x_2 ⋅ y_0 \\
&amp;amp;+   x_0 ⋅ y_1 + x_1 ⋅ y_1 + x_2 ⋅ y_1 \\
&amp;amp;+ x_0 ⋅ y_2 + x_1 ⋅ y_2 + x_2 ⋅ y_2 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;the terms can be grouped such that each party can compute one share &lt;span class=&quot;math math-inline&quot;&gt;z_i&lt;&#x2F;span&gt; locally given &lt;span class=&quot;math math-inline&quot;&gt;x_i, x_{i+1}, y_i, y_{i+1}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
z_0 &amp;amp;= x_0 ⋅ y_0 + x_0 ⋅ y_1 + x_1 ⋅ y_0 \\
z_1 &amp;amp;= x_1 ⋅ y_1 + x_1 ⋅ y_2 + x_2 ⋅ y_1 \\
z_2 &amp;amp;= x_2 ⋅ y_2 + x_2 ⋅ y_0 + x_0 ⋅ y_2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As a potential optimization, we can also trade multiplications for additions using:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
z_0 &amp;amp;= \p{x_0 + x_1} ⋅ \p{y_0 + y_1} - x_1 ⋅ y_1 \\
z_1 &amp;amp;= \p{x_1 + x_2} ⋅ \p{y_1 + y_2} - x_2 ⋅ y_2 \\
z_2 &amp;amp;= \p{x_2 + x_0} ⋅ \p{y_2 + y_0} - x_0 ⋅ y_0 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each node &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; can now communicate share &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; to node &lt;span class=&quot;math math-inline&quot;&gt;i-1&lt;&#x2F;span&gt; so that all nodes have a full complement of shares again. Before we do this we add a freshly generated share of zero to scramble the values and make sure node &lt;span class=&quot;math math-inline&quot;&gt;i-1&lt;&#x2F;span&gt; learns nothing about share &lt;span class=&quot;math math-inline&quot;&gt;i+1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Multplication&lt;&#x2F;strong&gt; For a two-party setting from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;3-540-46766-1_34.pdf&quot;&gt;B91&lt;&#x2F;a&gt; as in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1225.pdf&quot;&gt;PSSY20&lt;&#x2F;a&gt;. First the parties generate random shares &lt;span class=&quot;math math-inline&quot;&gt;a, b&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;c = a⋅b&lt;&#x2F;span&gt;, then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
z_i = (x_i + a_i)⋅(y_i + b_i) - (x_i + a_i)⋅b_i - a_i⋅(y_i + b_i) + c_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Two party multiply?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
z_0 + z_1 &amp;amp;= \p{x_0 + x_1} ⋅ \p{y_0 + y_1} \\
&amp;amp;= x_0 ⋅ y_0 + x_1 ⋅ y_0 \\
&amp;amp;+   x_0 ⋅ y_1 + x_1 ⋅ y_1  \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;generalization&quot;&gt;Generalization&lt;&#x2F;h3&gt;
&lt;p&gt;This multiplication method can potentially work for different number parties &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and collusion resistance &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;. The above is presented using &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt; shares, &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt; parties and a collusion resistance of &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; (i.e., &lt;span class=&quot;math math-inline&quot;&gt;≥ 2&lt;&#x2F;span&gt; parties need to collude to steal the secret). We can represent this scheme by share allocation as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ps{\ps{0, 1}, \ps{1,2}, \ps{2,0}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can also design a &lt;span class=&quot;math math-inline&quot;&gt;10&lt;&#x2F;span&gt; party scheme with collusion resistance of &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;5&lt;&#x2F;span&gt; shares:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ps{
    \ps{0, 1}, \ps{0, 2}, \ps{0, 3}, \ps{0, 4},
    \ps{1, 2}, \ps{1, 3}, \ps{1, 4},
    \ps{2, 3}, \ps{2, 4},
    \ps{3, 4}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Question: What other scemes are possible? I.e. can we create allocations of shares such that no union of &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; shares contains all shares, but each pair of shares occurs in at least one allocation.&lt;&#x2F;p&gt;
&lt;p&gt;Question: Can we design a &lt;span class=&quot;math math-inline&quot;&gt;9&lt;&#x2F;span&gt; node scheme with collusion resistance of &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;9&lt;&#x2F;span&gt; shares by applying the 3-share scheme recursively? Or does the top level re-sharing for multiplication leak too much?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inversion&quot;&gt;Inversion&lt;&#x2F;h3&gt;
&lt;p&gt;Question: Can we do inversion using Hensel lifting in &lt;span class=&quot;math math-inline&quot;&gt;\log_2 k&lt;&#x2F;span&gt; rounds?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
y&amp;#39; = y ⋅ \p{2 - x ⋅ y}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Computed in &lt;span class=&quot;math math-inline&quot;&gt;ℤ_2 ⊂ ℤ_{2^2} ⊂ ℤ_{2^4} ⊂ ℤ_{2^8} ⊂ ⋯ ⊂ ℤ_{2^k}&lt;&#x2F;span&gt;, so round complexity &lt;span class=&quot;math math-inline&quot;&gt;\log_2 k&lt;&#x2F;span&gt; but communication complexity only &lt;span class=&quot;math math-inline&quot;&gt;2⋅k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hensel&#x27;s_lemma#Quadratic_lifting&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bit-shift-right&quot;&gt;Bit shift right&lt;&#x2F;h3&gt;
&lt;p&gt;We want to compute&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;KaTeX&#x2F;KaTeX&#x2F;issues&#x2F;3561&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\bbox{x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;binary-encoding&quot;&gt;Binary encoding&lt;&#x2F;h3&gt;
&lt;p&gt;Use the above arithmetic procedure to create &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^1} = 𝔽_2&lt;&#x2F;span&gt;. Now create a vector of &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; such elements &lt;span class=&quot;math math-inline&quot;&gt;𝔽_2^k&lt;&#x2F;span&gt; to create a &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-bit bitvector. We can apply the arithmetic addition and multiplication operations of &lt;span class=&quot;math math-inline&quot;&gt;𝔽_2&lt;&#x2F;span&gt; elementwise to the vector to construct xor and and operations, denoted with &lt;span class=&quot;math math-inline&quot;&gt;⊕&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;∧&lt;&#x2F;span&gt; respectively. These elementwise operation happen in parallel such that, e.g. &lt;span class=&quot;math math-inline&quot;&gt;x = x_0 ⊕ x_1 ⊕_2&lt;&#x2F;span&gt; and the shares of &lt;span class=&quot;math math-inline&quot;&gt;z = x ∧ y&lt;&#x2F;span&gt; are computed as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
z_0 &amp;amp;= (x_0 ∧ y_0) ⊕ (x_0 ∧ y_1) ⊕ (x_1 ∧ y_0) \\
z_1 &amp;amp;= (x_1 ∧ y_1) ⊕ (x_1 ∧ y_2) ⊕ (x_2 ∧ y_1) \\
z_2 &amp;amp;= (x_2 ∧ y_2) ⊕ (x_2 ∧ y_0) ⊕ (x_0 ∧ y_2)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The communication complexity is exactly the same as due to parallelization the same number of rounds is required and the size of &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; is the same as &lt;span class=&quot;math math-inline&quot;&gt;𝔽_2^k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that any cleartext permutation of the vector indices can be applied locally.&lt;&#x2F;p&gt;
&lt;p&gt;Note that negation, &lt;span class=&quot;math math-inline&quot;&gt;¬&lt;&#x2F;span&gt;, is the same as xoring with the all-ones vector, and other bolean operations can be constructed from &lt;span class=&quot;math math-inline&quot;&gt;¬, ⊕, ∧&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;TODO: This applies to any kind of vectorization.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conversion&quot;&gt;Conversion&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;projection&quot;&gt;Projection&lt;&#x2F;h3&gt;
&lt;p&gt;i.e. arithmetic to binary.&lt;&#x2F;p&gt;
&lt;p&gt;Generically we can trivially convert from &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^h}&lt;&#x2F;span&gt; as long as &lt;span class=&quot;math math-inline&quot;&gt;h ≤ k&lt;&#x2F;span&gt;. Taking &lt;span class=&quot;math math-inline&quot;&gt;\box{a}_b&lt;&#x2F;span&gt; to mean &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; modulo &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
z = \box{\sum_i x_i}_b = \sum_i \box{x_i}_b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lifting&quot;&gt;Lifting&lt;&#x2F;h3&gt;
&lt;p&gt;i.e. binary to arithmetic&lt;&#x2F;p&gt;
&lt;p&gt;This is more challenging as we need to account for wraparound.&lt;&#x2F;p&gt;
&lt;p&gt;Question: Is there some polynomial we can construct and use Hensel lifting on?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;two-s-complement-encoding&quot;&gt;Two&#x27;s complement encoding&lt;&#x2F;h3&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{bits}: ℤ_{2^k} → 𝔽_2^k&lt;&#x2F;span&gt; the function mapping an number in &lt;span class=&quot;math math-inline&quot;&gt;ℤ_{2^k}&lt;&#x2F;span&gt; to a bitvector in &lt;span class=&quot;math math-inline&quot;&gt;𝔽_2^k&lt;&#x2F;span&gt; representing that number in two&#x27;s complement.&lt;&#x2F;p&gt;
&lt;p&gt;Given arithemtic shares &lt;span class=&quot;math math-inline&quot;&gt;⟦x⟧ = (x_1, x_2, x_3)&lt;&#x2F;span&gt; we can compute the two&#x27;s complement encoding &lt;em&gt;of each share&lt;&#x2F;em&gt; locally as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
⟦\mathrm{bits}(x_0)⟧^{\mathsf B} &amp;amp;= (\mathrm{bits}(x_1),0,0) \\
⟦\mathrm{bits}(x_1)⟧^{\mathsf B} &amp;amp;= (0, \mathrm{bits}(x_1),0) \\
⟦\mathrm{bits}(x_2)⟧^{\mathsf B} &amp;amp;= (0, 0, \mathrm{bits}(x_2))
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These can then be (locally) randomized by adding a random &lt;span class=&quot;math math-inline&quot;&gt;r ∈ 𝔽_2^k&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To finish constructing &lt;span class=&quot;math math-inline&quot;&gt;⟦\mathrm{bits}(x)⟧&lt;&#x2F;span&gt; we need to sum these shares. But this is an arithmetic sum that we need to execute over bitvectors in twos complement repesentation. This can be done using any kind of adder circuit. Minimal depth circuits are preffered to reduce the round complexity.&lt;&#x2F;p&gt;
&lt;p&gt;Note that two&#x27;s complement is only one method of encoding and others can be used as long as the addition circuit is modified accordingly.&lt;&#x2F;p&gt;
&lt;p&gt;Q: Do encodings other than two&#x27;s complement have better complexity for the adder circuit? How would Gray code addition work?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;two-s-complement-decoding&quot;&gt;Two&#x27;s complement decoding&lt;&#x2F;h3&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;3-540-46766-1_34.pdf&quot;&gt;B91&lt;&#x2F;a&gt; Donald Beaver (91). Efficient Multiparty Protocols Using Circuit Randomization.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2015&#x2F;931.pdf&quot;&gt;MRZ15&lt;&#x2F;a&gt; Payman Mohassel, Mike Rosulek, and Ye Zhang (2015). Fast and Secure Three-party Computation: The Garbled Circuit Approach.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;768.pdf&quot;&gt;AFL⁺16&lt;&#x2F;a&gt; Toshinori Araki, Jun Furukawa, Yehuda Lindell, Ariel Nof, and Kazuma Ohara (2016) High-Throughput Semi-Honest Secure Three-Party Computation with an Honest Majority.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;396.pdf&quot;&gt;MZ17&lt;&#x2F;a&gt; Payman Mohassel and Yupeng Zhang (2017). SecureML: A System for Scalable Privacy-Preserving Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;403.pdf&quot;&gt;MR18&lt;&#x2F;a&gt; Payman Mohassel and Peter Rindal (2018). ABY3: A Mixed Protocol Framework for Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;1315.pdf&quot;&gt;CRS19&lt;&#x2F;a&gt; Harsh Chaudhari, Rahul Rachuri, and Ajith Suresh (2019). Trident: Efficient 4PC Framework for Privacy Preserving Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;1365.pdf&quot;&gt;BCPS19&lt;&#x2F;a&gt; Megha Byali, Harsh Chaudhari, Arpita Patra, and Ajith Suresh (2019). FLASH: Fast and Robust Framework for Privacy-preserving Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;042.pdf&quot;&gt;PS20&lt;&#x2F;a&gt; Arpita Patra and Ajith Suresh (2020). BLAZE: Blazing Fast Privacy-Preserving Machine Learning.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1225.pdf&quot;&gt;PSSY20&lt;&#x2F;a&gt; Arpita Patra, Thomas Schneider, Ajith Suresh, and Hossein Yalame (2020). ABY2.0: Improved Mixed-Protocol Secure Two-Party Computation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Books: https:&#x2F;&#x2F;www.mpcalliance.org&#x2F;learn&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;securecomputation.org&#x2F;docs&#x2F;pragmaticmpc.pdf
https:&#x2F;&#x2F;www.cs.virginia.edu&#x2F;~evans&#x2F;pragmaticmpc&#x2F;pragmaticmpc.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;ebooks.iospress.nl&#x2F;volume&#x2F;applications-of-secure-multiparty-computation&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;assets.cambridge.org&#x2F;97811070&#x2F;43053&#x2F;copyright&#x2F;9781107043053_copyright_info.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.zellic.io&#x2F;blog&#x2F;mpc-from-scratch&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;nillion-oss&#x2F;nillion-oss.github.io&#x2F;blob&#x2F;main&#x2F;sum-of-products-lsss-non-interactive.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;wiki.mpcalliance.org&#x2F;protocols.html&lt;&#x2F;p&gt;
&lt;p&gt;Making robust against miscomputation:&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1330.pdf
https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;592.pdf
https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1744.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;medium.com&#x2F;partisia-blockchain&#x2F;beavers-trick-e275e79839cc&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;web.mit.edu&#x2F;6.857&#x2F;OldStuff&#x2F;Fall03&#x2F;ref&#x2F;Shamir-HowToShareASecret.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;iacr.org&#x2F;archive&#x2F;crypto2007&#x2F;46220565&#x2F;46220565.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;134.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;841.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;wiki.mpcalliance.org&#x2F;protocols.html&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.zellic.io&#x2F;blog&#x2F;mpc-from-scratch&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;300&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;131&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;1330&lt;&#x2F;p&gt;
&lt;p&gt;Shamir multi-sharing&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;129712.129780&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Representing (masked) bits in rings</title>
        <published>2024-02-16T00:00:00+00:00</published>
        <updated>2024-02-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/bits-in-rings/"/>
        <id>https://2π.com/24/bits-in-rings/</id>
        
        <content type="html" xml:base="https://2π.com/24/bits-in-rings/">&lt;h1 id=&quot;representing-masked-bits-in-rings&quot;&gt;Representing (masked) bits in rings&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\vec#1{\mathbf{#1}}
\gdef\mat#1{\mathrm{#1}}
\gdef\T{\mathsf{T}}
\gdef\F{\mathsf{F}}
\gdef\U{\mathsf{U}}
\gdef\popcount{\mathtt{popcount}}
\gdef\count{\mathtt{count}}
\gdef\hamming{\mathtt{hamming}}
\gdef\fhd{\mathtt{fhd}}
\gdef\vsum{\mathtt{sum}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In cryptography it is often useful to represent bits in algebraic objects. I will specifically consider rings &lt;span class=&quot;math math-inline&quot;&gt;ℤ_m&lt;&#x2F;span&gt; of integers modulo &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; is a prime number this happens to also be a field, but the difference is not very important here.&lt;&#x2F;p&gt;
&lt;p&gt;Bits are elements of &lt;span class=&quot;math math-inline&quot;&gt;𝔹 = \{\T, \F\}&lt;&#x2F;span&gt;, i.e. &lt;em&gt;true&lt;&#x2F;em&gt; and &lt;em&gt;false&lt;&#x2F;em&gt;, with the usual operations of &lt;em&gt;not&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;¬&lt;&#x2F;span&gt;, &lt;em&gt;and&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;∧&lt;&#x2F;span&gt;, &lt;em&gt;or&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;∨&lt;&#x2F;span&gt; and &lt;em&gt;xor&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;⊕&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Given bit vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec a, \vec b ∈ 𝔹^n&lt;&#x2F;span&gt; let the &lt;span class=&quot;math math-inline&quot;&gt;\popcount: 𝔹^n → [0,n]&lt;&#x2F;span&gt; function return the number of &lt;span class=&quot;math math-inline&quot;&gt;\T&lt;&#x2F;span&gt; values in a vector. We can then define the hamming distance function as &lt;span class=&quot;math math-inline&quot;&gt;\hamming(\vec a, \vec b) = \popcount(\vec a ⊕ \vec b)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Masked bits&lt;&#x2F;em&gt; are elements of &lt;span class=&quot;math math-inline&quot;&gt;𝕋 = \{\T, \F, \U\}&lt;&#x2F;span&gt;, i.e. &lt;em&gt;true&lt;&#x2F;em&gt;, &lt;em&gt;false&lt;&#x2F;em&gt;, and &lt;em&gt;unavailable&lt;&#x2F;em&gt;. The operations are the same as for binary, except when one of the arguments is &lt;span class=&quot;math math-inline&quot;&gt;\U&lt;&#x2F;span&gt;, the result is always &lt;span class=&quot;math math-inline&quot;&gt;\U&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We take &lt;span class=&quot;math math-inline&quot;&gt;\popcount&lt;&#x2F;span&gt; to count the number of &lt;span class=&quot;math math-inline&quot;&gt;\T&lt;&#x2F;span&gt;&#x27;s and introduce &lt;span class=&quot;math math-inline&quot;&gt;\count&lt;&#x2F;span&gt; to count the number of available entries i.e. either &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;\T&lt;&#x2F;span&gt; but not &lt;span class=&quot;math math-inline&quot;&gt;\U&lt;&#x2F;span&gt;. We can then define a &lt;em&gt;fractional hamming distance&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\fhd&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\fhd(\vec a, \vec b) = \frac{\popcount(\vec a ⊕ \vec b)}{\count(\vec a ⊕ \vec b)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-representation-of-bits&quot;&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}&lt;&#x2F;span&gt; representation of bits&lt;&#x2F;h2&gt;
&lt;p&gt;We represent &lt;span class=&quot;math math-inline&quot;&gt;\F, \T&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;0,1&lt;&#x2F;span&gt; respectively. The usual binary operations of &lt;em&gt;not&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;¬&lt;&#x2F;span&gt;, &lt;em&gt;and&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;∧&lt;&#x2F;span&gt;, &lt;em&gt;or&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;∨&lt;&#x2F;span&gt;, &lt;em&gt;xor&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;⊕&lt;&#x2F;span&gt;, can respectively be represented using ring operations as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
¬ a &amp;amp;= 1 - a \\
a ∧ b &amp;amp;= a ⋅ b \\
a ∨ b &amp;amp;= a + b - a ⋅ b \\
a ⊕ b &amp;amp;= a + b - 2 ⋅ a ⋅ b \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we have a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec a ∈ 𝔹^n&lt;&#x2F;span&gt; we can represent it element wise in &lt;span class=&quot;math math-inline&quot;&gt;ℤ_m^n&lt;&#x2F;span&gt;. This allows us to represent the &lt;span class=&quot;math math-inline&quot;&gt;\popcount&lt;&#x2F;span&gt; function:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\popcount(\vec a) &amp;amp;= \vsum(\vec a) \mod m\\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Observing that the sum over elementwise products is the dot product, we obtain the following useful identity:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\popcount(\vec a ∧ \vec b) = \vec a ⋅ \vec b \mod m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This representation is reversible for any &lt;span class=&quot;math math-inline&quot;&gt;m ≥ 2&lt;&#x2F;span&gt;, except for &lt;span class=&quot;math math-inline&quot;&gt;\popcount&lt;&#x2F;span&gt; which need &lt;span class=&quot;math math-inline&quot;&gt;m ≥ n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hamming(\vec a, \vec b) = \vec a ⋅ \vec a + \vec b ⋅ \vec b - 2 ⋅ \vec a ⋅ \vec b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-representation-of-bits-1&quot;&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\{1, -1\}&lt;&#x2F;span&gt; representation of bits&lt;&#x2F;h2&gt;
&lt;p&gt;We represent &lt;span class=&quot;math math-inline&quot;&gt;\F, \T&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;1,-1&lt;&#x2F;span&gt; respectively. The usual binary operations of &lt;em&gt;not&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;¬&lt;&#x2F;span&gt;, &lt;em&gt;and&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;∧&lt;&#x2F;span&gt;, &lt;em&gt;or&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;∨&lt;&#x2F;span&gt;, &lt;em&gt;xor&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;⊕&lt;&#x2F;span&gt;, can respectively be represented using ring operations as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
¬ a &amp;amp;= - a \\
a ∧ b &amp;amp;= ? \\
a ∨ b &amp;amp;= ? \\
a ⊕ b &amp;amp;= a ⋅ b \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we have a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec a ∈ 𝔹^n&lt;&#x2F;span&gt; we can represent it element wise in &lt;span class=&quot;math math-inline&quot;&gt;ℤ_m^n&lt;&#x2F;span&gt;. This allows us to represent the &lt;span class=&quot;math math-inline&quot;&gt;\popcount&lt;&#x2F;span&gt; function:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\popcount(\vec a) &amp;amp;= ½ ⋅(n - \vsum(\vec a)) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; bit vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec a_i ∈ 𝔹^n&lt;&#x2F;span&gt; we can construct a matrix &lt;span class=&quot;math math-inline&quot;&gt;\mat A ∈ 𝔹^{n×m}&lt;&#x2F;span&gt; such tht &lt;span class=&quot;math math-inline&quot;&gt;\mat A_{i,:} = \vec a_i&lt;&#x2F;span&gt;. If we have a second matrix of hamming distances &lt;span class=&quot;math math-inline&quot;&gt;\mat D ∈ [0,n]^{m×m}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\mat D_{ij} = \hamming(\vec a_i, \vec a_j)&lt;&#x2F;span&gt; then the following holds:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mat D = ½ ⋅(n⋅\mat J - \mat A ⋅ \mat A^\T)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\mat J&lt;&#x2F;span&gt; is the matrix of all ones. Suppose we are given &lt;span class=&quot;math math-inline&quot;&gt;\mat D&lt;&#x2F;span&gt;, we can compute &lt;span class=&quot;math math-inline&quot;&gt;\mat D&amp;#39; = n⋅\mat J - 2⋅\mat D&lt;&#x2F;span&gt; and solve the following quadratic system:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mat D&amp;#39; &amp;amp;= \mat A ⋅ \mat A^\T \\
\mat J &amp;amp;= \mat A ⊙ \mat A
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-representation-of-masked-bits&quot;&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\{-1,0,1\}&lt;&#x2F;span&gt; representation of masked bits&lt;&#x2F;h2&gt;
&lt;p&gt;We represent &lt;span class=&quot;math math-inline&quot;&gt;\F, \U, \T&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;-1, 0, 1&lt;&#x2F;span&gt; respectively. The binary operations become&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
¬ a &amp;amp;= - a \\
a ∧ b &amp;amp;= ½ ⋅ a ⋅ b ⋅ (1 + a + b - a ⋅ b) \\
a ∨ b &amp;amp;= ½ ⋅ a ⋅ b ⋅ (a ⋅ b + a + b -1 ) \\
a ⊕ b &amp;amp;= -a ⋅ b \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that the formulas for &lt;span class=&quot;math math-inline&quot;&gt;∧, ∨&lt;&#x2F;span&gt; can be evaluated using two multiplies in a depth-2 circuit.&lt;&#x2F;p&gt;
&lt;p&gt;Given a masked bitvector &lt;span class=&quot;math math-inline&quot;&gt;\vec a ∈ 𝕋^n&lt;&#x2F;span&gt;, we can define&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\count(\vec a) &amp;amp;= \vsum\left(\vec a^{⊙2}\right) \\
\popcount(\vec a) &amp;amp;= ½ ⋅ \vsum\left(\vec a^{⊙2} + \vec a\right)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can represent this on a suitably large (&lt;strong&gt;Q&lt;&#x2F;strong&gt; how large?) ring as &lt;span class=&quot;math math-inline&quot;&gt;-1,0,1&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;\F, \U, \T&lt;&#x2F;span&gt; respectively.&lt;&#x2F;p&gt;
&lt;p&gt;Note that squaring, &lt;span class=&quot;math math-inline&quot;&gt;\vec a^{⊙2}&lt;&#x2F;span&gt;, produces a regular &lt;span class=&quot;math math-inline&quot;&gt;0,1&lt;&#x2F;span&gt; bitvector that is &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; whenever the value is &lt;span class=&quot;math math-inline&quot;&gt;\U&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; otherwise, i.e. it  allows us to extract the mask as a regular bitvector. Similarly &lt;span class=&quot;math math-inline&quot;&gt;½ ⋅(\vec a^{⊙2} + \vec a)&lt;&#x2F;span&gt; extracts the data bits: &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;\T&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; otherwise. The reverse mapping, converting data bits &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; and mask bits &lt;span class=&quot;math math-inline&quot;&gt;\vec m&lt;&#x2F;span&gt; to a masked bitvector is &lt;span class=&quot;math math-inline&quot;&gt;\vec m - 2⋅\vec b⊙\vec m&lt;&#x2F;span&gt;. If the data bits are known to be &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; in the in the unavailable region, then it simplifies to &lt;span class=&quot;math math-inline&quot;&gt;\vec m - 2⋅\vec b⊙\vec m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In this representation &lt;em&gt;and&lt;&#x2F;em&gt; and &lt;em&gt;or&lt;&#x2F;em&gt; have awkward fourth degree expressions, though they can be evaluated using only two multiplies. The expressions for &lt;em&gt;xor&lt;&#x2F;em&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\count&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\popcount&lt;&#x2F;span&gt; are quite nice considering that they correctly account for masks. This makes it a suitable system for computing fractional hamming distances.&lt;&#x2F;p&gt;
&lt;p&gt;This representation is reversible for any &lt;span class=&quot;math math-inline&quot;&gt;m ≥ 2&lt;&#x2F;span&gt;, except for &lt;span class=&quot;math math-inline&quot;&gt;\popcount&lt;&#x2F;span&gt; which need &lt;span class=&quot;math math-inline&quot;&gt;m ≥ n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fractional-hamming-distance&quot;&gt;Fractional hamming distance&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;em&gt;fractional hamming weight&lt;&#x2F;em&gt; of a masked bitvector &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; is defined as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathtt{fhw}(\vec a) &amp;amp;= \frac
{\popcount(\vec a)}
{\count(\vec a )}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and the &lt;em&gt;fractional hamming distance&lt;&#x2F;em&gt; between two masked bitvectors &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\fhd(\vec a, \vec b)
&amp;amp;= \mathtt{fhw}(\vec a ⊕ \vec b) = \frac
{\popcount(\vec a ⊕ \vec b)}
{\count(\vec a ⊕ \vec b)}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the ring representation these can be computed as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\fhd(\vec a, \vec b)
&amp;amp; =\frac
{ ½ ⋅ \vsum\left((-\vec a ⊙ \vec b)^{⊙2} -\vec a ⊙ \vec b\right)}
{\vsum\left((-\vec a ⊙ \vec b)^{⊙2}\right)} 
&amp;amp;&amp;amp;=\frac{1}{2} -\frac
{ \vsum\left(\vec a ⊙ \vec b\right)}
{2⋅\vsum\left((\vec a ⊙ \vec b)^{⊙2}\right)}  \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;(\vec a ⊙ \vec b)^{⊙2} = \vec a^{⊙2} ⊙ \vec b^{⊙2}&lt;&#x2F;span&gt; and thus depends only on the masks of &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt;. Given the masks &lt;span class=&quot;math math-inline&quot;&gt;\vec a_m&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec b_m&lt;&#x2F;span&gt; it can be computed in binary as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vsum\left((\vec a ⊙ \vec b)^{⊙2}\right) = \popcount(\vec a_m ∧ \vec b_m)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sumcheck, MLEs and GKR</title>
        <published>2024-01-11T00:00:00+00:00</published>
        <updated>2024-01-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/sumcheck-gkr/"/>
        <id>https://2π.com/24/sumcheck-gkr/</id>
        
        <content type="html" xml:base="https://2π.com/24/sumcheck-gkr/">&lt;h1 id=&quot;sumcheck-mles-and-gkr&quot;&gt;Sumcheck, MLEs and GKR&lt;&#x2F;h1&gt;
&lt;p&gt;Split up into two pages:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;24&#x2F;sumcheck&quot;&gt;Sumcheck&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;24&#x2F;gkr&quot;&gt;GKR&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sumcheck and MLEs</title>
        <published>2024-01-11T00:00:00+00:00</published>
        <updated>2024-01-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/sumcheck/"/>
        <id>https://2π.com/24/sumcheck/</id>
        
        <content type="html" xml:base="https://2π.com/24/sumcheck/">&lt;h1 id=&quot;sumcheck-and-mles&quot;&gt;Sumcheck and MLEs&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\ps#1{\delim\{{#1}\}}
\gdef\F{\mathbb F}
\gdef\set#1{\mathcal #1}
\gdef\vec#1{\bm #1}
\gdef\popcount{\mathrm{popcount}}
\gdef\eq{\mathrm{eq}}
\gdef\∀{\mathop{\huge ∀}\limits}
\gdef\mul{\mathsf{mul}}
\gdef\add{\mathsf{add}}
\gdef\addc{\mathsf{add^C}}
\gdef\bar#1{\overline{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sumcheck&quot;&gt;Sumcheck&lt;&#x2F;h2&gt;
&lt;p&gt;Sumcheck was introduced in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;users.cs.fiu.edu&#x2F;~giri&#x2F;teach&#x2F;5420&#x2F;f01&#x2F;LundIPS.pdf&quot;&gt;LFKN92&lt;&#x2F;a&gt; and allows reducing certain sums of evaluations to a single evaluation. Given a field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; multivariate polynomial &lt;span class=&quot;math math-inline&quot;&gt;f ∈ \F[X_1,…,X_n]&lt;&#x2F;span&gt; and an evaluation domain &lt;span class=&quot;math math-inline&quot;&gt;\set B = \set B_1 × ⋯ × \set B_n&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\set B_i \subseteq \F&lt;&#x2F;span&gt;. Typically the evaluation domain is a unit hypercube, &lt;span class=&quot;math math-inline&quot;&gt;\set B = \ps{0,1}^n&lt;&#x2F;span&gt;, but I&#x27;ll present it generically here.&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to reduce proving&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
h = \sum_{\vec x ∈ \set B} f\p{\vec x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;to proving &lt;span class=&quot;math math-inline&quot;&gt;f(\vec r) = c&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;\vec r ∈ \F^n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;c ∈ \F&lt;&#x2F;span&gt;. This can then be proven by other means, for example by an opening of a polynomial commitment. The protocol proceeds as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;f_1 ∈ \F[X]&lt;&#x2F;span&gt;, a univariate polynomial such that
&lt;span class=&quot;math math-display&quot;&gt;
 f_1(X) = \sum_{\vec x ∈ \set B_2×⋯×\set B_n} f\p{X, \vec x}
 &lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends a random &lt;span class=&quot;math math-inline&quot;&gt;r_1 ∈ \F&lt;&#x2F;span&gt; and checks that &lt;span class=&quot;math math-inline&quot;&gt;\deg f_1 = \deg_1 f&lt;&#x2F;span&gt; and computes
&lt;span class=&quot;math math-display&quot;&gt;
 h = \sum_{x ∈ \set B_1} f_1\p{x}
 &lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;f_2(X)&lt;&#x2F;span&gt; where
&lt;span class=&quot;math math-display&quot;&gt;
 f_2(X) = \sum_{\vec x ∈ \set B_3×⋯×\set B_n} f\p{r_1, X, \vec x}
 &lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends a random &lt;span class=&quot;math math-inline&quot;&gt;r_2 ∈ \F&lt;&#x2F;span&gt; and checks that &lt;span class=&quot;math math-inline&quot;&gt;\deg f_2 = \deg_2 f&lt;&#x2F;span&gt; and
&lt;span class=&quot;math math-display&quot;&gt;
f_1(r_1) = \sum_{x ∈ \set B_2} f_2\p{x}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; repeat this process &lt;span class=&quot;math math-inline&quot;&gt;n-3&lt;&#x2F;span&gt; more times.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;f_n&lt;&#x2F;span&gt; where
&lt;span class=&quot;math math-display&quot;&gt;
 f_n(X) = f\p{\vec r, X}
 &lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends a random &lt;span class=&quot;math math-inline&quot;&gt;r_n ∈ \F&lt;&#x2F;span&gt; and computes &lt;span class=&quot;math math-inline&quot;&gt;c = f_n(r_n)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; use further methods to check
&lt;span class=&quot;math math-display&quot;&gt;
c = f(\vec r)
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;See Justin Thaler&#x27;s notes on Sum-Check &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;blogpost.pdf&quot;&gt;T20a&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;ProofsArgsAndZK.pdf&quot;&gt;T23a&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q&lt;&#x2F;strong&gt;: Does this generalize to other reductions than addition? What is it about addition that makes this work?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q&lt;&#x2F;strong&gt;: Does this generalize to other projections than on an axis? Would a sequence of linear independent lines &lt;span class=&quot;math math-inline&quot;&gt;\F → \F^n&lt;&#x2F;span&gt; work?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;analysis&quot;&gt;Analysis&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Soundness.&lt;&#x2F;strong&gt;
(TODO: check) Soundness &lt;span class=&quot;math math-inline&quot;&gt;O\p{\frac {b ⋅ n}{|\F|}}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;b = \max_i |\set B_i|&lt;&#x2F;span&gt;. See also Thaler&#x27;s note on small fields &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;small-sumcheck.pdf&quot;&gt;T23b&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Communication.&lt;&#x2F;strong&gt; There are &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; rounds in the protocol and at each round &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; the prover sends a &lt;span class=&quot;math math-inline&quot;&gt;\deg_i f&lt;&#x2F;span&gt; univariate polynomial. Which in general takes &lt;span class=&quot;math math-inline&quot;&gt;\sum_i \p{\deg_i f + 1}&lt;&#x2F;span&gt; elements of &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; total. In each round the prover sends a random &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, so &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; elements of &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; total. Assuming&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Prover.&lt;&#x2F;strong&gt; TODO: Prover complexity, especially it being better than the &lt;span class=&quot;math math-inline&quot;&gt;k⋅\log k&lt;&#x2F;span&gt; (in terms of number of values committed) that univariate proving systems have.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Verifier.&lt;&#x2F;strong&gt;
In each round &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; the verifier computes a sum over &lt;span class=&quot;math math-inline&quot;&gt;|\set B_i|&lt;&#x2F;span&gt; evaluations of a &lt;span class=&quot;math math-inline&quot;&gt;\deg_i f&lt;&#x2F;span&gt; degree polynomial. With direct evaluation this takes
&lt;span class=&quot;math math-display&quot;&gt;
\p{|\set B_i|⋅\p{1 + \deg_i f} - 1} ⋅ \add + |\set B_i| ⋅ \deg_i f ⋅ \mul
&lt;&#x2F;span&gt;
but there are more efficient algorithms for polynomial multi-evaluation. It is also that likely &lt;span class=&quot;math math-inline&quot;&gt;\set B_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; have additional structure that can be exploited in a particular application.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multi-linear-functions&quot;&gt;Multi-linear functions&lt;&#x2F;h2&gt;
&lt;p&gt;A multilinear function is a multivariate polynomial such that no variable occurs with degree higher than one. In other words, when considering a single variable and holding the rest constant the function is linear.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-equality-function&quot;&gt;The equality function&lt;&#x2F;h3&gt;
&lt;p&gt;A particularly useful multilinear function is the &lt;strong&gt;equality function&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\eq(\vec x, \vec y) = \prod_{i∈[0,n)}\p{x_i⋅y_i + (1 - x_i)⋅(1 - y_i)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is called the equality function because it is the indicator function for equality of two vectors on the unit hypercube:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\∀_{\vec x, \vec y ∈ \{0,1\}^n}
\eq(\vec x, \vec y) = \begin{cases}
1 &amp;amp; \vec x = \vec y \\
0 &amp;amp; \vec x ≠ \vec y
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is symmetrical under swapping arguments and permuting the vectors, i.e. given a permutation matrix &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\eq(\vec x, \vec y) = \eq(\vec y, \vec x) = \eq(P⋅\vec x, P⋅\vec y)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It can be efficiently evaluated using the product formula above, requiring the following operation in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(3⋅n-1) ⋅ \mul + n⋅\add + 2⋅n⋅\addc
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Addendum.&lt;&#x2F;strong&gt; It actually can be rewritten into one multiplication
&lt;span class=&quot;math math-display&quot;&gt;
x_i⋅y_i + (1 - x_i)⋅(1 - y_i) = 1 - x_i - y_i + 2⋅x_i⋅y_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-hypercube-basis&quot;&gt;The hypercube basis&lt;&#x2F;h3&gt;
&lt;p&gt;The equality function makes it easy to define basis functions for the corners of the hypercube. Given a corner &lt;span class=&quot;math math-inline&quot;&gt;\vec c ∈ \{0,1\}^n&lt;&#x2F;span&gt; the function &lt;span class=&quot;math math-inline&quot;&gt;\eq(\vec c, \vec x)&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; on all other corners. The evaluation of this function simplifies to
&lt;span class=&quot;math math-display&quot;&gt;
\eq(\vec c, \vec x) = \prod_{i∈[0,n)}\begin{cases}
x_i &amp;amp; c_i = 1 \\
1 - x_i &amp;amp; c_i = 0
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This simplifies the number of operations in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; to:
&lt;span class=&quot;math math-display&quot;&gt;
(n - 1)⋅\mul + (n - \popcount(\vec c))⋅\addc
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we need the values &lt;span class=&quot;math math-inline&quot;&gt;\eq(\vec c, \vec r)&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;\vec c ∈ \{0,1\}^n&lt;&#x2F;span&gt; and some arbitrary &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; we can compute these efficiently by building up one dimension at a time. Taking &lt;span class=&quot;math math-inline&quot;&gt;\bar{r_i} = 1 - r_i&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_0 &amp;amp;= \bar{r_0} &amp;amp;\quad x_{00} &amp;amp;= x_0 ⋅ \bar{r_1} &amp;amp;\quad x_{000} &amp;amp;= x_{00} ⋅ \bar{r_2} &amp;amp; \quad&amp;amp;⋯\\
x_1 &amp;amp;= r_0       &amp;amp; x_{01} &amp;amp;= x_0 ⋅ r_1       &amp;amp; x_{001} &amp;amp;= x_{00} ⋅ r_2       &amp;amp; &amp;amp;⋯\\
    &amp;amp;            &amp;amp; x_{10} &amp;amp;= x_1 ⋅ \bar{r_1} &amp;amp; x_{010} &amp;amp;= x_{01} ⋅ \bar{r_2} &amp;amp; &amp;amp;⋯\\
    &amp;amp;            &amp;amp; x_{11} &amp;amp;= x_1 ⋅ r_1       &amp;amp; x_{011} &amp;amp;= x_{01} ⋅ r_2       &amp;amp; &amp;amp;⋯\\
    &amp;amp;            &amp;amp;        &amp;amp;                  &amp;amp; x_{100} &amp;amp;= x_{10} ⋅ \bar{r_2} &amp;amp; &amp;amp;⋯\\
    &amp;amp;            &amp;amp;        &amp;amp;                  &amp;amp; x_{100} &amp;amp;= x_{11} ⋅ r_2       &amp;amp; &amp;amp;⋯\\
    &amp;amp;            &amp;amp;        &amp;amp;                  &amp;amp;         &amp;amp;\ \ ⋮                &amp;amp; &amp;amp;⋱\\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This can be done in-place and takes &lt;span class=&quot;math math-inline&quot;&gt;\p{2^{n+1} - 4}⋅\mul + n⋅\addc&lt;&#x2F;span&gt; operations in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ieee-security.org&#x2F;TC&#x2F;SP2013&#x2F;papers&#x2F;4977a223.pdf&quot;&gt;VSBW13&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;IPsandextensions.pdf&quot;&gt;T17&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This method generalizes to any function that factors into the form &lt;span class=&quot;math math-inline&quot;&gt;f(\vec x) = \prod_{i∈[0,n)} f_i(x_i)&lt;&#x2F;span&gt; where we get the same number of multiplications and also &lt;span class=&quot;math math-inline&quot;&gt;2⋅n&lt;&#x2F;span&gt; evaluations of &lt;span class=&quot;math math-inline&quot;&gt;f_i&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;0, 1&lt;&#x2F;span&gt;. If we want the sum of all these &lt;span class=&quot;math math-inline&quot;&gt;f(\vec c)&lt;&#x2F;span&gt; values we only need &lt;span class=&quot;math math-inline&quot;&gt;\p{n-1}⋅\mul + n⋅\add&lt;&#x2F;span&gt; operations using:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{x ∈ \ps{0,1}^n} \prod_{i∈[0,n)} f_i(x_i) = \prod_{i∈[0,n)}\p{f_i(0) + f_i(1)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Both these methods generalize to arbitrary product domains &lt;span class=&quot;math math-inline&quot;&gt;\set B = \set B_0 × ⋯ × \set B_{n-1}&lt;&#x2F;span&gt;, e.g.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{\vec x ∈ \set B} \prod_{i∈[0,n)} f_i(x_i) = \prod_{i∈[0,n)} \sum_{x ∈ \set B_i} f_i(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Would it be posible to compute it in &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; time with &lt;span class=&quot;math math-inline&quot;&gt;O(1)&lt;&#x2F;span&gt; memory if we permute the order of elements to be a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gray_code&quot;&gt;Gray code&lt;&#x2F;a&gt;?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;multilinear-extensions-mles&quot;&gt;Multilinear extensions (MLEs)&lt;&#x2F;h3&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;k = 2^n&lt;&#x2F;span&gt; values in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; we can store them at the corners of a &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; dimensional hypercube &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}^n&lt;&#x2F;span&gt;. Take some ordering of the corners &lt;span class=&quot;math math-inline&quot;&gt;\vec c_i&lt;&#x2F;span&gt; and values &lt;span class=&quot;math math-inline&quot;&gt;y_i&lt;&#x2F;span&gt; then the multilinear function interpolating these values is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(\vec x) = \sum_{i ∈ [0,k)} y_i ⋅ \eq(\vec c_i, \vec x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Directly evaluating this takes &lt;span class=&quot;math math-inline&quot;&gt;O\p{k⋅\log k}&lt;&#x2F;span&gt; operations (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1109.6882.pdf&quot;&gt;CTY11&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;IPsandextensions.pdf&quot;&gt;T17&lt;&#x2F;a&gt;). This can be reduced to &lt;span class=&quot;math math-inline&quot;&gt;O\p{k}&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; memory by first computing all &lt;span class=&quot;math math-inline&quot;&gt;\eq(\vec c, \vec x)&lt;&#x2F;span&gt; values using the method above.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hyperrectangles&quot;&gt;Hyperrectangles&lt;&#x2F;h3&gt;
&lt;p&gt;We have focussed on the unit hypercube, &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}^n&lt;&#x2F;span&gt;, so far. Another interesting basis is the symmetric hypercube &lt;span class=&quot;math math-inline&quot;&gt;\{-1, 1\}&lt;&#x2F;span&gt;. And really this should generalize straightforward with non-degenerate affine transformations.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Multilinear_polynomial#On_a_rectangular_domain&quot;&gt;Wikipedia&lt;&#x2F;a&gt; has an interesting remark that transforming between coefficient and evaluation form on the unit hypercube is a Möbius transform, and for the symmetric hypercube a Hadamard transform.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Bit equality indicator in &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}&lt;&#x2F;span&gt; vs &lt;span class=&quot;math math-inline&quot;&gt;\{-1,1\}&lt;&#x2F;span&gt;:
&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
1 - a - b + 2⋅a⋅b &amp;amp;&amp;amp;\quad&amp;amp; \frac{a⋅b + 1}{2}
\end{aligned}
&lt;&#x2F;span&gt;
in the &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{eq}&lt;&#x2F;span&gt; usecase the &lt;span class=&quot;math math-inline&quot;&gt;\frac12&lt;&#x2F;span&gt; factor can be moved out of the product, and likely absorbed somewhere else entirely. So this seems beneficial. It does not appear possible for any basis to do better than &lt;span class=&quot;math math-inline&quot;&gt;a⋅b + 1&lt;&#x2F;span&gt; as neither addition or multiplication alone is sufficient.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zero-testing&quot;&gt;Zero testing&lt;&#x2F;h2&gt;
&lt;p&gt;Sumcheck can be used to prove &lt;span class=&quot;math math-inline&quot;&gt;f(\vec x) = 0&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \{0,1\}^n&lt;&#x2F;span&gt;. To do this, we first construct a function &lt;span class=&quot;math math-inline&quot;&gt;g(\vec x)&lt;&#x2F;span&gt; that is a multilinear extension of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; resricted to the unit cube:
&lt;span class=&quot;math math-display&quot;&gt;
g(\vec x) = \sum_{\vec y ∈ \{0,1\}^n} \eq(\vec y, \vec x) ⋅ f(\vec y)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since the interpolation is unique, &lt;span class=&quot;math math-inline&quot;&gt;g(\vec x)&lt;&#x2F;span&gt; is the zero polynomial if and only if &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is zero on the unit cube. By Schwartz-Zippel if &lt;span class=&quot;math math-inline&quot;&gt;g(\vec r) = 0&lt;&#x2F;span&gt; for a random &lt;span class=&quot;math math-inline&quot;&gt;\vec r ∈\F^n&lt;&#x2F;span&gt; then it is likely the zero polynomial. Thus, to proof our claim we do the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; send a random &lt;span class=&quot;math math-inline&quot;&gt;\vec r ∈ \F^n&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; use sumcheck on the sum
&lt;span class=&quot;math math-display&quot;&gt;
 0 = g(\vec r) = \sum_{\vec y ∈ \ps{0,1}^n} \eq(\vec y, \vec r) ⋅ f(\vec y)
 &lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; use further methods to check
&lt;span class=&quot;math math-display&quot;&gt;
\eq(\vec r&amp;#39;, \vec r) ⋅ f(\vec r&amp;#39;) = c
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;reduction-to-one-query&quot;&gt;Reduction to one query&lt;&#x2F;h2&gt;
&lt;p&gt;Suppose we have a polynomial &lt;span class=&quot;math math-inline&quot;&gt;f: \F^n → \F&lt;&#x2F;span&gt; and we want to prove &lt;span class=&quot;math math-inline&quot;&gt;f(\vec x_1) = y_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f(\vec x_2) = y_2&lt;&#x2F;span&gt;. We can reduce this to a single evaluation. Create a linear function &lt;span class=&quot;math math-inline&quot;&gt;l: \F → \F^n&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;l(0) = \vec x_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;l(1) = \vec x_2&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
l(x) = \vec x_1 + x⋅(\vec x_2 - \vec x_1)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends univariate polynomial &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;(x) = f(l(x))&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends random &lt;span class=&quot;math math-inline&quot;&gt;r ∈ \F&lt;&#x2F;span&gt; and checks &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;(0) = y_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;(1) = y_2&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; use further methods to check
&lt;span class=&quot;math math-display&quot;&gt;
   f&amp;#39;(r) = f(l(r))
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This last claim is of the form &lt;span class=&quot;math math-inline&quot;&gt;f(\vec x) = y&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; What is the size of &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;&lt;&#x2F;span&gt;? In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;IPsandextensions.pdf&quot;&gt;T17&lt;&#x2F;a&gt; it is stated to be at most degree &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, but this could be a special case.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is multilinear then &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;&lt;&#x2F;span&gt; is degree at most &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. This generalizes to &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; evaluation points with &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt; interpolating &lt;span class=&quot;math math-inline&quot;&gt;l(0)=\vec x_0, l(1) = \vec x_1,  …, l(k-1) = x_{k-1}&lt;&#x2F;span&gt;. And &lt;span class=&quot;math math-inline&quot;&gt;\deg f&amp;#39;&lt;&#x2F;span&gt; at most &lt;span class=&quot;math math-inline&quot;&gt;\p{k-1}⋅ n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alternative-using-linear-combinations&quot;&gt;Alternative using linear combinations&lt;&#x2F;h3&gt;
&lt;p&gt;See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;305&quot;&gt;CFS17&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;317&quot;&gt;XZZ⁺19&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends random &lt;span class=&quot;math math-inline&quot;&gt;r ∈ 𝔽&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;zero-knowledge&quot;&gt;Zero-knowledge&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; This still leaks a single evaluation of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The sum-check protocol by itself is not zero-knowledge, but can be made such. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;305&quot;&gt;CFS17&lt;&#x2F;a&gt; the prover does this using a random masking polynomial. Starting with the prover claiming &lt;span class=&quot;math math-inline&quot;&gt;h = \sum_{\vec x ∈ \set B} f\p{\vec x}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; picks a random &lt;span class=&quot;math math-inline&quot;&gt;g ∈ \F[X_1,…,X_n]&lt;&#x2F;span&gt; of equal degrees as &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; and computes &lt;span class=&quot;math math-inline&quot;&gt;h&amp;#39; = \sum_{\vec x ∈ \set B} g\p{\vec x}&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; sends &lt;span class=&quot;math math-inline&quot;&gt;h&amp;#39;&lt;&#x2F;span&gt; and a commitment to &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Verifier&lt;&#x2F;strong&gt; sends random &lt;span class=&quot;math math-inline&quot;&gt;ρ ∈ 𝔽&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; use the sumcheck protocol on
&lt;span class=&quot;math math-display&quot;&gt;
h + ρ ⋅ h&amp;#39; = \sum_{\vec x ∈ \set B} f\p{\vec x} + ρ ⋅ g\p{\vec x}
&lt;&#x2F;span&gt;
to reduce it to
&lt;span class=&quot;math math-display&quot;&gt;
c + ρ ⋅ c&amp;#39; = f\p{\vec r} + ρ ⋅ g\p{\vec r}
&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Prover&lt;&#x2F;strong&gt; decommits &lt;span class=&quot;math math-inline&quot;&gt;c&amp;#39; = g\p{\vec r}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;strong&gt;prover&lt;&#x2F;strong&gt; and &lt;strong&gt;verifier&lt;&#x2F;strong&gt; now continue with the claim &lt;span class=&quot;math math-inline&quot;&gt;c = f\p{\vec r}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The masking polynomial &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; has &lt;span class=&quot;math math-inline&quot;&gt;\prod_i(1 + \deg_i f)&lt;&#x2F;span&gt; random coefficients, which is as large as the original &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;. But often &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; has special structure that allows much faster evaluation than an arbitrary polynomial. But &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; being arbitrary ruins these often crucial optimizations. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;317&quot;&gt;XZZ⁺19&lt;&#x2F;a&gt; (aka Libra) this is addressed by realizing that a smaller &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is sufficient. In particular
&lt;span class=&quot;math math-display&quot;&gt;
g(\vec x) = g_1(x_1) + g_2(x_2) + ⋯ + g_n(x_n)
&lt;&#x2F;span&gt;
where &lt;span class=&quot;math math-inline&quot;&gt;g_i ∈ 𝔽[X]&lt;&#x2F;span&gt; are random with &lt;span class=&quot;math math-inline&quot;&gt;\deg g_i = \deg_{i} f&lt;&#x2F;span&gt; is sufficient. Note that the constant term only has to be generated once, resulting in only &lt;span class=&quot;math math-inline&quot;&gt;1 + \sum_i \deg_i f&lt;&#x2F;span&gt; random coefficients.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;wp-content&#x2F;uploads&#x2F;2008&#x2F;01&#x2F;GoldwasserKR08a.pdf&quot;&gt;GKR08&lt;&#x2F;a&gt; Shafi Goldwasser, Yael Tauman Kalai, Guy N. Rothblum (2008). Delegating Computation: Interactive Proofs for Muggles.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1109.6882.pdf&quot;&gt;CTY11&lt;&#x2F;a&gt; Graham Cormode, Justin Thaler, Ke Yi (2011). Verifying Computations with Streaming Interactive Proofs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1105.2003.pdf&quot;&gt;CMT12&lt;&#x2F;a&gt; Graham Cormode, Michael Mitzenmacher, Justin Thaler (2012). Practical Verified Computation with Streaming Interactive Proofs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;351.pdf&quot;&gt;T13&lt;&#x2F;a&gt; Justin Thaler (2013). &quot;Time-Optimal Interactive Proofs for Circuit Evaluation&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;GKRNote.pdf&quot;&gt;T15&lt;&#x2F;a&gt; Justin Thaler (2015). &quot;A Note on the GKR Protocol&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;305&quot;&gt;CFS17&lt;&#x2F;a&gt; Alessandro Chiesa, Michael A. Forbes, Nicholas Spooner (2017). A Zero Knowledge Sumcheck and its Applications.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;317&quot;&gt;XZZ⁺19&lt;&#x2F;a&gt; Tiancheng Xie, Jiaheng Zhang, Yupeng Zhang, Charalampos Papamanthou, Dawn Song (2019). Libra: Succinct Zero-Knowledge Proofs with Optimal Prover.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;blogpost.pdf&quot;&gt;T20a&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zkproof.org&#x2F;2020&#x2F;03&#x2F;16&#x2F;sum-checkprotocol&quot;&gt;T20b&lt;&#x2F;a&gt;: Justin Thaler (2020). &quot;The Unreasonable Power of the Sum-Check
Protocol&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;users.cs.duke.edu&#x2F;~elk27&#x2F;bibliography&#x2F;22&#x2F;Ka22gkr.pdf&quot;&gt;K22&lt;&#x2F;a&gt; Erich Kaltofen (2022). &quot;The GKR Protocol Revisited&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1284.pdf&quot;&gt;PH23&lt;&#x2F;a&gt; Shahar Papini, Ulrich Haböck (2023). &quot;Improving logarithmic derivative lookups using GKR&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;1611.pdf&quot;&gt;S23&lt;&#x2F;a&gt; Lev Soukhanov (2023). &quot;Power circuits: a new arithmetization for GKR-styled sumcheck&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;ProofsArgsAndZK.pdf&quot;&gt;T23a&lt;&#x2F;a&gt; Justin Thaler (2023). &quot;Proofs, Arguments, and Zero-Knowledge&quot;. See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;COSC544.html&quot;&gt;lecture notes&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;gkrnotes.pdf&quot;&gt;older lecture notes&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;small-sumcheck.pdf&quot;&gt;T23b&lt;&#x2F;a&gt; Justin Thaler (2023). The sumcheck protocol over fields of small characteristic.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arielgabizon&#x2F;Lectures&#x2F;blob&#x2F;master&#x2F;zkWarsawJan24.pdf&quot;&gt;G24&lt;&#x2F;a&gt; Ariel Gabizon (2024). zkWarsaw talk &quot;The GKR method&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2024&#x2F;1046&quot;&gt;BDT24&lt;&#x2F;a&gt; Suyash Bagad, Yuval Domb, Justin Thaler (2024). The Sum-Check Protocol over Fields of Small Characteristic.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ingonyama-zk&#x2F;papers&#x2F;blob&#x2F;a2505bc33187b473fb934403b08735c120ee1264&#x2F;sumcheck_201_book.pdf&quot;&gt;BI24&lt;&#x2F;a&gt; Suyash Bagad, Karthik Inbasekar (2024). Ingoyama Sumcheck 201.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Abstract Algebra</title>
        <published>2023-09-28T00:00:00+00:00</published>
        <updated>2023-09-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/algebra/"/>
        <id>https://2π.com/23/algebra/</id>
        
        <content type="html" xml:base="https://2π.com/23/algebra/">&lt;h1 id=&quot;abstract-algebra&quot;&gt;Abstract Algebra&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\set#1{\delim\{{#1}\}}
\gdef\floor#1{\delim\lfloor{#1}\rfloor}
\gdef\ceil#1{\delim\lceil{#1}\rceil}
\gdef\norm#1{\delim\vert{#1}\vert}
\gdef\S{\mathcal S}
\gdef\G{\mathcal G}
\gdef\vec#1{\bf{#1}}
\gdef\Z{\mathrm{Z}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Binary_operation&quot;&gt;binary operation&lt;&#x2F;a&gt; is a total function &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; for some set &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;. Abstract algebra is the study of such binary operations.&lt;&#x2F;p&gt;
&lt;p&gt;Due to historical reasons it is often presented as being about &#x27;generalized numbers&#x27; called structures. This causes the main emphasis to be on the domain &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; rather than the operation &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;. It also causes an eagerness to use infix notation for &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;. I find that a more neutral presentation better highlights the generality, so that is what I attempt here. This is similar to the approach taken in universal algebra.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Category:Properties_of_binary_operations
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Class_of_groups&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.math.uwaterloo.ca&#x2F;~snburris&#x2F;htdocs&#x2F;UALG&#x2F;univ-algebra.pdf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre-requisites&lt;&#x2F;h2&gt;
&lt;p&gt;Sets, predicates, orders, sequences, etc&lt;&#x2F;p&gt;
&lt;p&gt;domain, codomain, image&lt;&#x2F;p&gt;
&lt;p&gt;partial, total.&lt;&#x2F;p&gt;
&lt;p&gt;injective, surjective, bijective,&lt;&#x2F;p&gt;
&lt;p&gt;transformation, permutation.&lt;&#x2F;p&gt;
&lt;p&gt;identity, constant.&lt;&#x2F;p&gt;
&lt;p&gt;Number of (total) functions: &lt;span class=&quot;math math-inline&quot;&gt;\norm{\mathcal B}^{\norm{\mathcal A}}&lt;&#x2F;span&gt;.
partial functions: &lt;span class=&quot;math math-inline&quot;&gt;\p{\norm{\mathcal B} +1}^{\norm{\mathcal A}}&lt;&#x2F;span&gt;
Permutations: &lt;span class=&quot;math math-inline&quot;&gt;\norm{\mathcal A}!&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unary-operation&quot;&gt;Unary operation&lt;&#x2F;h2&gt;
&lt;p&gt;A unary operation is a total function &lt;span class=&quot;math math-inline&quot;&gt;f:\S→\S&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;collision&lt;&#x2F;strong&gt; is a pair of elements &lt;span class=&quot;math math-inline&quot;&gt;a,b ∈ \S&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;f(a) = f(b)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Either &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; has collisions or it is a bijection, invertible and a permutation.&lt;&#x2F;p&gt;
&lt;p&gt;one-way function. hash function.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cycle_detection&lt;&#x2F;p&gt;
&lt;p&gt;A directed graph where the out-degree is always exactly one.&lt;&#x2F;p&gt;
&lt;p&gt;Parallel cycle finding:&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cs.csi.cuny.edu&#x2F;~zhangx&#x2F;papers&#x2F;P_2018_LISAT_Weber_Zhang.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;people.scs.carleton.ca&#x2F;~paulv&#x2F;papers&#x2F;JoC97.pdf&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Rainbow tables.&lt;&#x2F;p&gt;
&lt;p&gt;Example applications: Pollard Rho factorization, discrete logarithm, password cracking, hash collision finding.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;two-variables&quot;&gt;Two variables&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Many of these definitions generalizes to functions with unequal arguments, &lt;span class=&quot;math math-inline&quot;&gt;f:\mathcal A × \mathcal B → \mathcal C&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;identity-element&quot;&gt;Identity element&lt;&#x2F;h3&gt;
&lt;p&gt;For a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; an element &lt;span class=&quot;math math-inline&quot;&gt;e ∈ \S&lt;&#x2F;span&gt; is a &lt;strong&gt;left-identity&lt;&#x2F;strong&gt; iff for all &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(e,a) = a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; an element &lt;span class=&quot;math math-inline&quot;&gt;e ∈ \S&lt;&#x2F;span&gt; is a &lt;strong&gt;right-identity&lt;&#x2F;strong&gt; iff for all &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a,e) = a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; has both a left-identity &lt;span class=&quot;math math-inline&quot;&gt;e_\mathrm{L}&lt;&#x2F;span&gt; and right-identity &lt;span class=&quot;math math-inline&quot;&gt;e_\mathrm{R}&lt;&#x2F;span&gt;, they must be the same&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
e_\mathrm{L} = f\p{e_\mathrm{L}, e_\mathrm{R}} = e_\mathrm{R}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;furthermore this identity element &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; must be unique, for if there was a second &lt;span class=&quot;math math-inline&quot;&gt;e&amp;#39;&lt;&#x2F;span&gt; that is also both a left- and right-identity then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
e = f\p{e, e&amp;#39;} = e&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;so if an element &lt;span class=&quot;math math-inline&quot;&gt;e∈\S&lt;&#x2F;span&gt; is both a left- and right-identity, it is the unique &lt;strong&gt;identity element&lt;&#x2F;strong&gt; for &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;absorbing-element&quot;&gt;Absorbing element&lt;&#x2F;h3&gt;
&lt;p&gt;For a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; an element &lt;span class=&quot;math math-inline&quot;&gt;z ∈ \S&lt;&#x2F;span&gt; is &lt;strong&gt;left-absorbing&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(z,a) = z
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; an element &lt;span class=&quot;math math-inline&quot;&gt;z ∈ \S&lt;&#x2F;span&gt; is &lt;strong&gt;right-absorbing&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a,z) = z
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; has both a left-absorbing element &lt;span class=&quot;math math-inline&quot;&gt;z_\mathrm{L}&lt;&#x2F;span&gt; and right-absorbing element &lt;span class=&quot;math math-inline&quot;&gt;z_\mathrm{R}&lt;&#x2F;span&gt;, they must be the same&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
z_\mathrm{L} = f\p{z_\mathrm{L}, z_\mathrm{R}} = z_\mathrm{R}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;furthermore this absorbing element &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt; must be unique, for if there was a second &lt;span class=&quot;math math-inline&quot;&gt;z&amp;#39;&lt;&#x2F;span&gt; that is also both a left- and right-absorbing then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
z = f\p{z, z&amp;#39;} = z&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;so if an element &lt;span class=&quot;math math-inline&quot;&gt;z∈\S&lt;&#x2F;span&gt; is both left- and right-absorbing, it is the unique &lt;strong&gt;absorbing element&lt;&#x2F;strong&gt; for &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Examples.&lt;&#x2F;strong&gt; Zero is the identity element for addition and the absorbing element for multiplication. Negative and positive infinity are the identity and absorbing elements for &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{max}&lt;&#x2F;span&gt;, and reversed for &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{min}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cancelability&quot;&gt;Cancelability&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cancellation_property&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cancellative_semigroup&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inverses&quot;&gt;Inverses&lt;&#x2F;h3&gt;
&lt;p&gt;Given a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; with an identity element &lt;span class=&quot;math math-inline&quot;&gt;e∈\S&lt;&#x2F;span&gt;. An element &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt; has a &lt;strong&gt;left-inverse&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;b ∈ \S&lt;&#x2F;span&gt; if&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(b,a) = e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; with an identity element &lt;span class=&quot;math math-inline&quot;&gt;e∈\S&lt;&#x2F;span&gt;. An element &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt; has a &lt;strong&gt;right-inverse&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;b ∈ \S&lt;&#x2F;span&gt; if&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a,b) = e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is associative the &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;-inverse element is unique, if it exists. If there where two elements &lt;span class=&quot;math math-inline&quot;&gt;b, b&amp;#39; ∈ \G&lt;&#x2F;span&gt; we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
b = f(b,e) = f(b,f(a, b&amp;#39;)) = f(f(b,a), b&amp;#39;) = f(e, b&amp;#39;) = b&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; with an identity element &lt;span class=&quot;math math-inline&quot;&gt;e∈\S&lt;&#x2F;span&gt;. &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;-&lt;strong&gt;invertible&lt;&#x2F;strong&gt; if an &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;-inverse exists for all elements of &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This defines a new unary operator &lt;span class=&quot;math math-inline&quot;&gt;g:\S→\S&lt;&#x2F;span&gt; mapping each element to its unique &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;-inverse. This inverse operator satisfies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a, g(a)) = f(g(a), a) = e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;commutativity&quot;&gt;Commutativity&lt;&#x2F;h3&gt;
&lt;p&gt;A binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; is &lt;strong&gt;commutative&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;a,b∈\S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a,b) = f(b,a)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; with inverse &lt;span class=&quot;math math-inline&quot;&gt;g:\S→\S&lt;&#x2F;span&gt; is &lt;strong&gt;anti-commutative&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;a,b∈\S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a,b) = g(f(b,a))
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; an element &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt; is a &lt;strong&gt;center&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;b ∈ \S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a,b)=f(b,a)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;associativity&quot;&gt;Associativity&lt;&#x2F;h3&gt;
&lt;p&gt;A binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; is &lt;strong&gt;associative&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;a,b,c∈\S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a, f(b,c)) = f(f(a,b), c)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; and an element &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt; we can define the sequence&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a_1 &amp;amp;= a &amp;amp;\quad
a_{n+1} = f\p{a, a_n}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An example of an operator that is commutative but not associative is the average &lt;span class=&quot;math math-inline&quot;&gt;f(a,b) = \frac{a + b}{2}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question&lt;&#x2F;strong&gt; Is there an example of commutativity without power-associativity?&lt;&#x2F;p&gt;
&lt;p&gt;A binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; is &lt;strong&gt;flexible&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;a,b∈\S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a, f(b, a)) = f(f(a, b), a)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; is &lt;strong&gt;alternative&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;a,b∈\S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f(a, f(a, b)) &amp;amp;= f(f(a, a), b) &amp;amp;
f(b, f(a, a)) &amp;amp;= f(f(b, a), a) &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Artin&#x27;s theorem: any alternative &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is associative on every subset of two elements.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;idempotence&quot;&gt;Idempotence&lt;&#x2F;h3&gt;
&lt;p&gt;For a binary operation &lt;span class=&quot;math math-inline&quot;&gt;f:\S×\S →\S&lt;&#x2F;span&gt; an element &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \S&lt;&#x2F;span&gt; is &lt;strong&gt;idempotent&lt;&#x2F;strong&gt; if&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a,a)=a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If all elements of &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; are idempotent we say that &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is &lt;strong&gt;idempotent&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Idempotence&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is commutative, associative and idempotent it is called a &lt;strong&gt;meet&lt;&#x2F;strong&gt;. We can define a partial order on &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;a ≤ b&lt;&#x2F;span&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;f(a, b) = a&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Join_and_meet#Universal_algebra_approach&lt;&#x2F;p&gt;
&lt;h3 id=&quot;power-associativity&quot;&gt;Power associativity&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is &lt;strong&gt;power-associative&lt;&#x2F;strong&gt; if for all &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;n,m ∈ \N^+&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_{n+m} = f\p{a_n, a_m}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we reduce a sequence of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; copies of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; by applying &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; to pairs of elements we will always get &lt;span class=&quot;math math-inline&quot;&gt;a_n&lt;&#x2F;span&gt; regardless of what order the &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;&#x27;s are applied in. If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is written infix as &lt;span class=&quot;math math-inline&quot;&gt;*&lt;&#x2F;span&gt; we can unambiguously write&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_n = \underbrace{a*a*⋯*a}_{
\begin{array}{rl}
    \small n &amp;amp;\!\! \text{copies of } a \\
    \small \p{n-1}&amp;amp;\!\!\text{times } *
\end{array}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This sequence is &lt;strong&gt;exponentiation&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;:\S×\N^+→\S&lt;&#x2F;span&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; has an identity element &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;, we set &lt;span class=&quot;math math-inline&quot;&gt;a_0 = e&lt;&#x2F;span&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; has an inverse &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; with its own exponentiation sequence &lt;span class=&quot;math math-inline&quot;&gt;b_n&lt;&#x2F;span&gt;, then we set &lt;span class=&quot;math math-inline&quot;&gt;a_{-n} = b_n&lt;&#x2F;span&gt;. This extends the domain to &lt;span class=&quot;math math-inline&quot;&gt;\N&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\Z&lt;&#x2F;span&gt; respectively. Note that all of these extensions are compatible with each other and the above relations.&lt;&#x2F;p&gt;
&lt;p&gt;Power-associativity implies that &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is associative on the set &lt;span class=&quot;math math-inline&quot;&gt;\set{a_i}&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;f(a_i, a_j) = a_{i+j} = f(a_j, a_i)&lt;&#x2F;span&gt;. &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; need not be associative on the whole &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Question: Is there an example of a commutative operator that is not power-associative?&lt;&#x2F;p&gt;
&lt;p&gt;From the definition we can compute &lt;span class=&quot;math math-inline&quot;&gt;a_n&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;n-1&lt;&#x2F;span&gt; applications of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;, but the power associativity allows us to do better. Consider the following two methods to compute &lt;span class=&quot;math math-inline&quot;&gt;a_{15}&lt;&#x2F;span&gt;, requiring &lt;span class=&quot;math math-inline&quot;&gt;6&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;5&lt;&#x2F;span&gt; applications of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; respectively instead of &lt;span class=&quot;math math-inline&quot;&gt;14&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a_1 &amp;amp;= a     &amp;amp;\quad\quad a_1 &amp;amp;= a \\
a_2 &amp;amp;= f(a_1, a_1)     &amp;amp; a_2 &amp;amp;= f(a_1, a_1) \\
a_4 &amp;amp;= f(a_2, a_2)     &amp;amp; a_3 &amp;amp;= f(a_1, a_2) \\
a_8 &amp;amp;= f(a_4, a_4)     &amp;amp; a_6 &amp;amp;= f(a_3, a_3) \\
a_3 &amp;amp;= f(a_1, a_2)     &amp;amp; a_{12} &amp;amp;= f(a_6, a_6) \\
a_7 &amp;amp;= f(a_3, a_4)     &amp;amp; a_{15} &amp;amp;= f(a_3, a_{12}) \\
a_{15} &amp;amp;= f(a_7, a_8)  &amp;amp; \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On the left we compute all powers of two up to &lt;span class=&quot;math math-inline&quot;&gt;\floor{\log_2 n}&lt;&#x2F;span&gt; and then combine them to create &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, requiring &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{pop}\p{n} - 1&lt;&#x2F;span&gt; applications of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{pop}&lt;&#x2F;span&gt; is the binary &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hamming_weight&quot;&gt;Hamming weight&lt;&#x2F;a&gt; (the number of non-zero digits in the binary expansion of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;). This method is called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exponentiation_by_squaring&quot;&gt;exponentiation by squaring&lt;&#x2F;a&gt;, works for all &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and requires exactly &lt;span class=&quot;math math-inline&quot;&gt;\floor{\log_2 n} + \operatorname{pop}\p{n} - 1&lt;&#x2F;span&gt; applications of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;. On the right we show a method specific to &lt;span class=&quot;math math-inline&quot;&gt;15&lt;&#x2F;span&gt; that performs better. Such methods rely on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Addition_chain&quot;&gt;addition chains&lt;&#x2F;a&gt; and are called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Addition-chain_exponentiation&quot;&gt;addition-chain exponentiation&lt;&#x2F;a&gt;. Finding optimal addition chains is an ongoing research topic &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wwwhomes.uni-bielefeld.de&#x2F;achim&#x2F;addition_chain.html&quot;&gt;Fla23&lt;&#x2F;a&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; has an easy to compute inverse, or if multiple exponentiations need to be computed in parallel, or if there is other structure, see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.dmgordon.org&#x2F;papers&#x2F;jalg.pdf&quot;&gt;Gor97&lt;&#x2F;a&gt;. In general exponents can be computed in &lt;span class=&quot;math math-inline&quot;&gt;≤\ceil{\log_2 n}&lt;&#x2F;span&gt; application of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;, so logarithmic in &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; is finite at some point the sequence &lt;span class=&quot;math math-inline&quot;&gt;a_i&lt;&#x2F;span&gt; will have to repeat. There will be a tail and a cycle. Does power associativity proof things about the tail and cycle length?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a_{T + L} &amp;amp;= a_{T}    &amp;amp; f(a_T, a_L) &amp;amp;= f(a_L, a_T) = a_T \\
a_{T + L + i} &amp;amp;= a_{T + i} &amp;amp; f(a_T, a_{L + i}) &amp;amp;= f(a_T, a_i) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This means &lt;span class=&quot;math math-inline&quot;&gt;a_L&lt;&#x2F;span&gt; acts as an identity to &lt;span class=&quot;math math-inline&quot;&gt;a_T&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;wlog we have &lt;span class=&quot;math math-inline&quot;&gt;k ≥ 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;l ≥ 1&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a_{k} = a_{k+l}&lt;&#x2F;span&gt; and are the smallest such numbers. If &lt;span class=&quot;math math-inline&quot;&gt;k &amp;gt; 1&lt;&#x2F;span&gt; we can write &lt;span class=&quot;math math-inline&quot;&gt;k = k&amp;#39; + 1&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_k = a_{k+l} = f(a_k, a_l)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first &#x27;inverse&#x27; operation is &lt;strong&gt;discrete logarithm&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\S×\S → \Z&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;n = \log_a b&lt;&#x2F;span&gt; is a number (if it exists) such that &lt;span class=&quot;math math-inline&quot;&gt;a_n = b&lt;&#x2F;span&gt;. This is a much harder problem and subject to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Discrete_logarithm_records&quot;&gt;active competition&lt;&#x2F;a&gt; on specific instances. The best methods have additional assumptions on &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;. For the generic case there does not appear to be a method better than a brute-force enumerating of &lt;span class=&quot;math math-inline&quot;&gt;a_n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The second &#x27;inverse&#x27; operation is &lt;strong&gt;&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th root&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\S×\Z → \S&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;a = \sqrt[n]{b}&lt;&#x2F;span&gt; is a number (if it exists) such that &lt;span class=&quot;math math-inline&quot;&gt;a_n = b&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Another function is the &lt;strong&gt;order&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\S → \Z&lt;&#x2F;span&gt; or &lt;em&gt;period&lt;&#x2F;em&gt; of an element where &lt;span class=&quot;math math-inline&quot;&gt;k = \operatorname{ord}\p{a}&lt;&#x2F;span&gt; is the smallest &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a_{n+k} = a_n&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Q: What about &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; guarantees that &lt;span class=&quot;math math-inline&quot;&gt;f(-,a)&lt;&#x2F;span&gt; is a cyclic? Ans: If &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; has an inverse, then &lt;span class=&quot;math math-inline&quot;&gt;(-,a)&lt;&#x2F;span&gt; has an inverse &lt;span class=&quot;math math-inline&quot;&gt;f(-,-a)&lt;&#x2F;span&gt; and thus both are permutations.&lt;&#x2F;p&gt;
&lt;p&gt;Q: What about &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; guarentees that &lt;span class=&quot;math math-inline&quot;&gt;orb(a)&lt;&#x2F;span&gt; divides &lt;span class=&quot;math math-inline&quot;&gt;|\S|&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; is the least common multiple of the orders of all elements, then for each &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;a_{1 + k} = a&lt;&#x2F;span&gt;. We also have &lt;span class=&quot;math math-inline&quot;&gt;a_{1 + k} = f(a_k, a)&lt;&#x2F;span&gt;, hence&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a_k, a) = f(a, a_k) = a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;a_k&lt;&#x2F;span&gt; is the same regardless of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, then it must be the identity element. But does the converse hold? If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; has an identity element, does it need to appear as &lt;span class=&quot;math math-inline&quot;&gt;a_k&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Langrange theorem, Cauchy theorem.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Order_(group_theory)
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lagrange&#x27;s_theorem_(group_theory)
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cauchy%27s_theorem_(group_theory) ( a special case of Sylow )
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sylow_theorems&lt;&#x2F;p&gt;
&lt;p&gt;Question: If &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; is finite the sequence &lt;span class=&quot;math math-inline&quot;&gt;a_i&lt;&#x2F;span&gt; will have to be cyclic. What can we say about the cycle length?&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;vixra.org&#x2F;pdf&#x2F;1509.0011v1.pdf (Generalization of Lagrange&#x27;s Theorem to certain semigroups)&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cycle_detection&lt;&#x2F;p&gt;
&lt;h3 id=&quot;notation&quot;&gt;Notation&lt;&#x2F;h3&gt;
&lt;p&gt;In &lt;strong&gt;additive notation&lt;&#x2F;strong&gt; the binary operation is written as infix &lt;span class=&quot;math math-inline&quot;&gt;+&lt;&#x2F;span&gt;, the identity element (if exits) as &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; and the inverse operator as prefix &lt;span class=&quot;math math-inline&quot;&gt;-&lt;&#x2F;span&gt; (i.e. the additive inverse of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;-a&lt;&#x2F;span&gt;). Exponentiation is written as &lt;span class=&quot;math math-inline&quot;&gt;n⋅a&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;strong&gt;multiplicative notation&lt;&#x2F;strong&gt; the binary operation is written as infix &lt;span class=&quot;math math-inline&quot;&gt;⋅&lt;&#x2F;span&gt;, the identity element (if it exits) as &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;, the absorbing element (if it exits) as &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;, and the inverse operator as suffix &lt;span class=&quot;math math-inline&quot;&gt;{}^{-1}&lt;&#x2F;span&gt; (i.e. the additive inverse of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;a^{-1}&lt;&#x2F;span&gt;). Exponentiation is written as &lt;span class=&quot;math math-inline&quot;&gt;a^n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;structures&quot;&gt;Structures&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Magma_(algebra)#Classification_by_properties&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Special_classes_of_semigroups&lt;&#x2F;p&gt;
&lt;p&gt;Depending on the properties of &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; the structure &lt;span class=&quot;math math-inline&quot;&gt;\p{\S, f}&lt;&#x2F;span&gt; goes by various names&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;&#x2F;th&gt;&lt;th&gt;associative&lt;&#x2F;th&gt;&lt;th&gt;identity&lt;&#x2F;th&gt;&lt;th&gt;invertible&lt;&#x2F;th&gt;&lt;th&gt;commutative&lt;&#x2F;th&gt;&lt;th&gt;idempotent&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;magma&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;semigroup&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;monoid&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;group&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;abelian group&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;unital magma&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;quasigroup&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;associative quasigroup&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;loop&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;band&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;semi-lattice&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;bounded semi-lattice&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;td&gt;✓&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h4 id=&quot;classification-theorems&quot;&gt;Classification theorems&lt;&#x2F;h4&gt;
&lt;p&gt;For many of these structures there are classification theorems enumerating all possible structures up to isomorphism.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Any cyclic group is abelian.&lt;&#x2F;li&gt;
&lt;li&gt;All subgroups of&lt;&#x2F;li&gt;
&lt;li&gt;Any group of prime order &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; is associative and isomorphic to the cyclic group &lt;span class=&quot;math math-inline&quot;&gt;C_p&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Any group of order &lt;span class=&quot;math math-inline&quot;&gt;p^2&lt;&#x2F;span&gt; for a prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; is associative and isomorphic to &lt;span class=&quot;math math-inline&quot;&gt;C_{p^2}&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;C_p × C_p&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Any abelian group of order &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is the direct sum of non-distinct prime-power cyclic groups.&lt;&#x2F;li&gt;
&lt;li&gt;The number of groups of order &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oeis.org&#x2F;A000001&quot;&gt;A000001&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The number of abelian groups of order &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oeis.org&#x2F;A000688&quot;&gt;A000688&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The number of monoids &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oeis.org&#x2F;A058129&quot;&gt;A058129&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The number of semigroups &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oeis.org&#x2F;A001423&quot;&gt;A001423&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Loops: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oeis.org&#x2F;A057771&quot;&gt;A057771&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Quasigroups &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oeis.org&#x2F;A057991&quot;&gt;A057991&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h4&gt;
&lt;p&gt;Derived operators&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Nonary
&lt;ul&gt;
&lt;li&gt;Identity&lt;&#x2F;li&gt;
&lt;li&gt;Absorbing&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Unary
&lt;ul&gt;
&lt;li&gt;Inverse&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;functions
&lt;ul&gt;
&lt;li&gt;Exponentiation &lt;span class=&quot;math math-inline&quot;&gt;\S×ℤ→\S&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Order &lt;span class=&quot;math math-inline&quot;&gt;\S→ℕ&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Logarithm &lt;span class=&quot;math math-inline&quot;&gt;\S×\S→ℤ&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;algorithms&quot;&gt;Algorithms&lt;&#x2F;h4&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Computational_group_theory&lt;&#x2F;p&gt;
&lt;h2 id=&quot;two-operations&quot;&gt;Two operations&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;distributive&quot;&gt;Distributive&lt;&#x2F;h3&gt;
&lt;p&gt;Given two binary operations &lt;span class=&quot;math math-inline&quot;&gt;f,g:\S × \S → \S&lt;&#x2F;span&gt;, we say &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is &lt;strong&gt;left-distributive&lt;&#x2F;strong&gt; over &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; iff for all &lt;span class=&quot;math math-inline&quot;&gt;a, b,c ∈ \S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
g(a, f(b, c)) = f(g(a, b), g(a, c))
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, we say &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is &lt;strong&gt;right-distributive&lt;&#x2F;strong&gt; over &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; iff for all &lt;span class=&quot;math math-inline&quot;&gt;a, b,c ∈ \S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
g(f(a, b), c) = f(g(a, c), g(b, c))
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is both left- and right-distributive over &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; we stay &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is &lt;strong&gt;distributive&lt;&#x2F;strong&gt; over &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is commutative, left- and right-distributive are equivalent.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;absorption&quot;&gt;Absorption&lt;&#x2F;h3&gt;
&lt;p&gt;Given two binary operations &lt;span class=&quot;math math-inline&quot;&gt;f,g:\S × \S → \S&lt;&#x2F;span&gt;, we say &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; and g$ satisfy the &lt;strong&gt;absorption&lt;&#x2F;strong&gt; law iff for all &lt;span class=&quot;math math-inline&quot;&gt;a, b ∈ \S&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(a, g(a, b)) = g(a, f(a, b)) = a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It follows that they are both idempotent, as &lt;span class=&quot;math math-inline&quot;&gt;a = f(a, g(a, f(a, a))) = f(a, a)&lt;&#x2F;span&gt; and symmetrically with &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; reversed.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; are also commutative and associative, the resulting structure with two operations is a &lt;strong&gt;lattice&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lattice_(order)&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Boolean_algebra_(structure)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;semi-rings&quot;&gt;Semi-rings&lt;&#x2F;h3&gt;
&lt;p&gt;A neat example of a semi-ring is &lt;span class=&quot;math math-inline&quot;&gt;ℝ∪\set{∞}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\min&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;+&lt;&#x2F;span&gt;. This is the &lt;strong&gt;tropical semiring&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tropical_semiring
https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2309.11256&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rings&quot;&gt;Rings&lt;&#x2F;h3&gt;
&lt;p&gt;A &lt;strong&gt;ring&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\p{\mathcal R, +, ⋅}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\p{\mathcal R, +}&lt;&#x2F;span&gt; is an abelian group (written additively) and &lt;span class=&quot;math math-inline&quot;&gt;\p{\mathcal R, ⋅}&lt;&#x2F;span&gt; is a monoid (written multiplicatively) and &lt;span class=&quot;math math-inline&quot;&gt;+, ⋅&lt;&#x2F;span&gt; satisfy the distributive property: for all &lt;span class=&quot;math math-inline&quot;&gt;a,b,c∈\mathcal R&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a⋅\p{b+c} &amp;amp;= a⋅b + a⋅c \\
\p{a+b}⋅c &amp;amp;= a⋅c + b⋅c \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;commutative ring&lt;&#x2F;strong&gt; is a ring &lt;span class=&quot;math math-inline&quot;&gt;\p{\mathcal R, +, ⋅}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;⋅&lt;&#x2F;span&gt; is commutative.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;field&lt;&#x2F;strong&gt; is a commutative ring &lt;span class=&quot;math math-inline&quot;&gt;\p{\mathcal R, +, ⋅}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\p{\mathcal R \setminus \{0\}, ⋅}&lt;&#x2F;span&gt; is an abelian group.&lt;&#x2F;p&gt;
&lt;p&gt;rngs ⊃ rings ⊃ commutative rings ⊃ integral domains ⊃ integrally closed domains ⊃ GCD domains ⊃ unique factorization domains ⊃ principal ideal domains ⊃ Euclidean domains ⊃ fields ⊃ algebraically closed fields&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scalar-multiplication&quot;&gt;Scalar multiplication&lt;&#x2F;h3&gt;
&lt;p&gt;An &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-&lt;strong&gt;module&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\p{\mathcal V, +, ⋅}&lt;&#x2F;span&gt; is an abelian group &lt;span class=&quot;math math-inline&quot;&gt;\p{\mathcal V, +}&lt;&#x2F;span&gt; with a &lt;strong&gt;scalar multiplication&lt;&#x2F;strong&gt; operation &lt;span class=&quot;math math-inline&quot;&gt;⋅:R×\mathcal V → \mathcal V&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is a ring such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\p{a ⋅ b} ⋅ \vec v &amp;amp;= a ⋅ \p{b ⋅ \vec v} \\
1⋅\vec v &amp;amp; = \vec v \\ 
a⋅\p{\vec u + \vec v} &amp;amp;= a⋅\vec u + \mathit a⋅\vec v \\
\p{a + b}⋅\vec v &amp;amp;= a ⋅ \vec v + \mathit b ⋅ \vec v
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is also called a module over &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The exponentiation in the abelian group is a &lt;span class=&quot;math math-inline&quot;&gt;\mathcal V × ℤ → \mathcal V&lt;&#x2F;span&gt; is a scalar multiplication, making any abelian group a &lt;span class=&quot;math math-inline&quot;&gt;ℤ&lt;&#x2F;span&gt;-module. Conversely, it can be shown that any &lt;span class=&quot;math math-inline&quot;&gt;ℤ&lt;&#x2F;span&gt;-module is an abelian group.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;basis&lt;&#x2F;strong&gt; for an &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;-module &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt; is a set of linearly independent vectors &lt;span class=&quot;math math-inline&quot;&gt;{\vec v}_i&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{span}_R\p{{\vec v}_0, {\vec v}_1, …} = M&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;free module&lt;&#x2F;strong&gt; is a module that has a basis.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;vector space&lt;&#x2F;strong&gt; is a module over a field.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;matrix space&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Every power-associative magma is a &lt;span class=&quot;math math-inline&quot;&gt;\Z&lt;&#x2F;span&gt;-module. Every Abelian group is a &lt;span class=&quot;math math-inline&quot;&gt;\Z&#x2F;n\Z&lt;&#x2F;span&gt;-magma. If &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is prime it is a vector space over the prime field &lt;span class=&quot;math math-inline&quot;&gt;\mathbb{F}_n&lt;&#x2F;span&gt;. Note that this applies to elliptic curves. (Q: What if &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;p^k&lt;&#x2F;span&gt;?)&lt;&#x2F;p&gt;
&lt;!--
An example of a link between finite generation and integral elements can be found in commutative algebras. To say that a commutative algebra A is a finitely generated ring over R means that there exists a set of elements G = {x1, ..., xn} of A such that the smallest subring of A containing G and R is A itself. Because the ring product may be used to combine elements, more than just R-linear combinations of elements of G are generated. For example, a polynomial ring R[x] is finitely generated by {1, x} as a ring, but not as a module. If A is a commutative algebra (with unity) over R, then the following two statements are equivalent:[5] 
--&gt;
&lt;h3 id=&quot;composition&quot;&gt;Composition&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Composition_ring&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_decomposition&lt;&#x2F;p&gt;
&lt;h3 id=&quot;derivatives&quot;&gt;Derivatives&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Formal_derivative&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Derivation_(differential_algebra)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;morphisms&quot;&gt;Morphisms&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Category_(mathematics)#Types_of_morphisms&lt;&#x2F;p&gt;
&lt;p&gt;A function between two structures of the same type &lt;span class=&quot;math math-inline&quot;&gt;f:G→H&lt;&#x2F;span&gt; is called a &lt;strong&gt;homomorphism&lt;&#x2F;strong&gt; if it preserves the structure: It maps any constants to the corresponding constants, i.e. &lt;span class=&quot;math math-inline&quot;&gt;f(0_G)=0_H&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;f(1_G)=1_H&lt;&#x2F;span&gt;, etc. It preserves any unary operators, i.e. &lt;span class=&quot;math math-inline&quot;&gt;f(g_G(x)) = g_H(f(x))&lt;&#x2F;span&gt;. It perserves binary operators &lt;span class=&quot;math math-inline&quot;&gt;f(g_G(a, b)) = g_H(f(a), f(b))&lt;&#x2F;span&gt; and so on for higher arities.&lt;&#x2F;p&gt;
&lt;p&gt;A homomorphism &lt;span class=&quot;math math-inline&quot;&gt;f:G→H&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; injective is a &lt;strong&gt;monomorphism&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A homomorphism &lt;span class=&quot;math math-inline&quot;&gt;f:G→H&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; surjective is an &lt;strong&gt;epimorphism&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A homomorphism &lt;span class=&quot;math math-inline&quot;&gt;f:G→H&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;G = H&lt;&#x2F;span&gt; is a &lt;strong&gt;endomorphism&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A homomorphism &lt;span class=&quot;math math-inline&quot;&gt;f:G→H&lt;&#x2F;span&gt; is a &lt;strong&gt;isomorphism&lt;&#x2F;strong&gt; if there is an inverse function &lt;span class=&quot;math math-inline&quot;&gt;g:H→G&lt;&#x2F;span&gt; that is also a homomorphism. If these exists &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt; are &lt;strong&gt;isomorphic&lt;&#x2F;strong&gt;, denoted &lt;span class=&quot;math math-inline&quot;&gt;G ≅ H&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A homomorphism &lt;span class=&quot;math math-inline&quot;&gt;f:G→H&lt;&#x2F;span&gt; that is both endomorphic and isomorphic is an &lt;strong&gt;automorphism&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;classification-theorems-1&quot;&gt;Classification theorems&lt;&#x2F;h2&gt;
&lt;p&gt;Up to isomorphism many algebraic structures are enumerable or otherwise constained in their instances.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Classification_of_finite_simple_groups&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Wedderburn%E2%80%93Artin_theorem&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Structure_theorem_for_finitely_generated_modules_over_a_principal_ideal_domain&lt;&#x2F;p&gt;
&lt;p&gt;All finite fields have order &lt;span class=&quot;math math-inline&quot;&gt;p^n&lt;&#x2F;span&gt; for some prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; and positive integer &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. All finite fields of the same order are isomorphic.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Structure_theorem_for_finitely_generated_modules_over_a_principal_ideal_domain&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_ring&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Isomorphism_theorems#Universal_algebra&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nullifiers and Account Abstraction</title>
        <published>2023-09-25T00:00:00+00:00</published>
        <updated>2023-09-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/nullifier-abstraction/"/>
        <id>https://2π.com/23/nullifier-abstraction/</id>
        
        <content type="html" xml:base="https://2π.com/23/nullifier-abstraction/">&lt;h1 id=&quot;nullifiers-and-account-abstraction&quot;&gt;Nullifiers and Account Abstraction&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\c#1{\mathsf{#1}}
\gdef\H{\c{H}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Privacy oriented protocols often need a mechanism to do an action &lt;em&gt;anonymously&lt;&#x2F;em&gt; and &lt;em&gt;only once&lt;&#x2F;em&gt;. For example spending a coin, claiming an airdrop, or voting on a proposal.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Why not use signatures or &lt;span class=&quot;math math-inline&quot;&gt;\H\p{\c{signature}}&lt;&#x2F;span&gt; as nullifiers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;status-quo-nullifiers&quot;&gt;Status Quo: Nullifiers&lt;&#x2F;h2&gt;
&lt;p&gt;The standard solution is using &lt;em&gt;nullifiers&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\c{nullifier} = \H\p{\c{context}, \c{private\_key}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Typically the zkSNARK would prove&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
\begin{array}{c}
\c{root}, \c{context}, \\ \c{nullifier}, \c{message}
\\ \hline
\c{merkle\_proof}, \\ \c{private\_key}
\end{array}
\middle\vert
\begin{array}{l}
\c{nullifier} = \H\p{\c{context}, \c{private\_key}} \\
\c{public\_key} = \c{derive\_public\_key}\p{\c{private\_key}} \\
\c{verify\_inclusion}\p{\c{merkle\_proof}, \c{public\_key}}
\end{array}
}]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;account-abstraction&quot;&gt;Account Abstraction&lt;&#x2F;h2&gt;
&lt;p&gt;Before account abstraction, actions are authorized using ecdsa signatures. The pair &lt;span class=&quot;math math-inline&quot;&gt;\p{\c{user\_id}, \c{message}, \c{signature}}&lt;&#x2F;span&gt; is verified by checking the signature, for example by recovering the public key and hence the user id.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\c{user\_id} = \H\p{\c{ecdsa\_recover}\p{\H\p{\c{message}}, \c{signature}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\c{ecdsa\_verify}&lt;&#x2F;span&gt; function has the nice property that it is &lt;em&gt;pure&lt;&#x2F;em&gt;. It is a well-defined computation depending only on its inputs that always gives the same result. It&#x27;s easy to zkSNARK these.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
\begin{array}{c}
\c{user\_id}, \c{message}
\\ \hline
\c{public\_key},\\
\c{signature}
\end{array}
\middle\vert
\begin{array}{l}
\c{user\_id} = \H\p{\c{public\_key}}\\
\c{ecdsa\_verify}\p{\c{public\_key}, \H\p{\c{message}}, \c{signature}}
\end{array}
}]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;or alternatively we can push the hashes out of the proof&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
\begin{array}{c}
\c{public\_key}, \\ \c{message\_hash}
\\ \hline
\c{signature}
\end{array}
\middle\vert
\begin{array}{l}
\c{ecdsa\_verify}\p{\c{public\_key}, \c{message\_hash}, \c{signature}}
\end{array}
}]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The main downside of the ecdsa signature is that they require the user to keep a secret.&lt;&#x2F;p&gt;
&lt;p&gt;In account abstraction we get rid of explicit private keys and instead use a smart contract with a programmable predicate to check signatures.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\c{wallet}\p{\c{user\_id}}.
\c{verify}\p{\H\p{\c{message}}, \c{signature}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;span class=&quot;math math-inline&quot;&gt;\c{verify}&lt;&#x2F;span&gt; is no longer pure, it depends on the current state of the chain. We can make this dependence explicit:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\c{evm\_verify}\p{\c{chain\_state}, \c{user\_id}, \H\p{\c{message}}, \c{signature}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This predicate is again &lt;em&gt;pure&lt;&#x2F;em&gt; and we can zkSNARK it, providing a commitment to &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt; (i.e. a block hash) as public input. The actual implementation of this zkSNARK is non-trivial and requires all full zkEVM implementation. While zkEVM implementations exist, they are quite resource hungry and do not currently appear feasible on mobile devices. I&#x27;ll ignore this problem for now and wait for the relentless march of progress to solve it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
\begin{array}{c}
\c{block\_hash}, \\ \c{user\_id}, \c{message}
\\ \hline
\c{chain\_state}, \\ \c{signature}
\end{array}
\middle\vert
\begin{array}{l}
\c{block\_hash} = \c{state\_hash}\p{\c{chain\_state}} \\
\c{evm\_verify}\p{\c{chain\_state}, \c{user\_id}, \H\p{\c{message}}, \c{signature}}
\end{array}
}]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;&#x2F;h2&gt;
&lt;p&gt;If we try to include the above zkEVM abstract signature proof into the semaphore scheme we get this&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
\begin{array}{c}
\c{block\_hash},\c{root},\\
\c{context}, \c{nullifier}, \\\c{message}
\\ \hline
\c{merkle\_proof}, \c{user},\\
\c{chain\_state}, \\ \c{signature}
\end{array}
\middle\vert
\begin{array}{l}
\c{block\_hash} = \c{state\_hash}\p{\c{chain\_state}} \\
\c{evm\_verify}\p{\c{chain\_state}, \c{user}, \H\p{\c{context}, \c{message}}, \c{signature}} \\[1em]
\c{nullifier} = \H\p{\c{context}, ???}
\c{public\_key} = \c{derive\_public\_key}\p{\c{private\_key}} \\
\c{verify\_inclusion}\p{\c{merkle\_proof}, \c{public\_key}}
\end{array}
}]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The problem is what to use as entropy in the place of &lt;span class=&quot;math math-inline&quot;&gt;???&lt;&#x2F;span&gt; for the nullifier derivation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\c{nullifier} = \H\p{\c{context}, ???}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We may have a private key that we use to produce signatures for the wallet, but even if that is the case it can change over time and does not provide the long-lived guarantees needed for nullifiers. (And being able to change it is a big part of the motivation for account abstraction).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;obfuscation&quot;&gt;Obfuscation&lt;&#x2F;h2&gt;
&lt;p&gt;Assume we can create a black-box function &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; for any computable function. Would this solve our problem? We can hide the entropy in the program.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s say we can take any pure computable function &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; and turn it into a black box &lt;span class=&quot;math math-inline&quot;&gt;\hat{f}&lt;&#x2F;span&gt; such that we can store and evaluate &lt;span class=&quot;math math-inline&quot;&gt;\hat{f}&lt;&#x2F;span&gt; onchain without anyone being able to see the implementations details of &lt;span class=&quot;math math-inline&quot;&gt;\hat f&lt;&#x2F;span&gt;. We could use this to store the user entropy. Let each user generate some private &lt;span class=&quot;math math-inline&quot;&gt;\c{entropy}&lt;&#x2F;span&gt;, and create &lt;span class=&quot;math math-inline&quot;&gt;\hat f(x) = \H\p{\c{entropy}, x}&lt;&#x2F;span&gt;. Then we can derive nullifiers as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
\begin{array}{c}
\c{context}, \c{nullifier}  \\ \hline
⋯
\end{array}
\middle\vert
\begin{array}{l}
⋯ \\
\c{nullifier} = \hat f\p{\c{context}} \\
⋯
\end{array}
}]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This works, but it&#x27;s no better than storing the &lt;span class=&quot;math math-inline&quot;&gt;\c{entropy}&lt;&#x2F;span&gt; directly onchain, and it suffers from the same problem: for a given nullifier we can just enumerate all user&#x27;s &lt;span class=&quot;math math-inline&quot;&gt;\hat f&lt;&#x2F;span&gt; and find the one that satisfies &lt;span class=&quot;math math-inline&quot;&gt;\c{nullifier} = \hat f\p{\c{context}}&lt;&#x2F;span&gt;. This will identify the user.&lt;&#x2F;p&gt;
&lt;p&gt;We need to modify &lt;span class=&quot;math math-inline&quot;&gt;\hat f&lt;&#x2F;span&gt; to prevent such enumeration. We can fix this by making the evaluation conditional on a user provided signature.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(\c{chain\_state}, x, \c{signature}) = \begin{cases}
\H\p{\c{entropy}, x} &amp;amp; \c{evm\_verify\p{\c{chain\_state},\c{user\_id},x,\c{signature}}}\\
⊥ &amp;amp; \text{otherwise}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;\c{user\_id}&lt;&#x2F;span&gt; can be hardcoded as we generate an &lt;span class=&quot;math math-inline&quot;&gt;\hat f&lt;&#x2F;span&gt; for each user. We can theoretically build such an &lt;span class=&quot;math math-inline&quot;&gt;hat f&lt;&#x2F;span&gt; using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Indistinguishability_obfuscation&quot;&gt;indistinguishability obfuscation&lt;&#x2F;a&gt; (&lt;span class=&quot;math math-inline&quot;&gt;\mathcal{iO}&lt;&#x2F;span&gt;), though current schemes are very inefficient. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;454.pdf&quot;&gt;SW13&lt;&#x2F;a&gt; for examples of protocols build using &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{iO}&lt;&#x2F;span&gt;. Note that it is and extremely powerful primitive that can be used to construct zkSNARKS and many other cryptographic primitives.&lt;&#x2F;p&gt;
&lt;p&gt;This solves the enumeration problem as long as the attacker is not able to produce valid signature. But the attacker can trivially generate a &lt;span class=&quot;math math-inline&quot;&gt;\p{\c{chain\_state}, \c{signature}}&lt;&#x2F;span&gt; pair if it can substitute any &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt;. We need a way to make sure &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt; is indeed part of the chain. Just proving that &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt; is part of the chain alone is also not enough. This allows any historical owner to call the function, even if they are no longer owner. We need a way to make sure &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt; is &lt;em&gt;onchain&lt;&#x2F;em&gt; and &lt;em&gt;recent&lt;&#x2F;em&gt;. The &lt;em&gt;onchain&lt;&#x2F;em&gt; part can be dealt with by deterministically checking consensus rules (baring long-range attacks). The &lt;em&gt;recency&lt;&#x2F;em&gt; part requires a new protocol however, as the current time is stateful.&lt;&#x2F;p&gt;
&lt;p&gt;For the zkSNARK this is not a problem as we can expose the &lt;span class=&quot;math math-inline&quot;&gt;\c{block\_hash}&lt;&#x2F;span&gt; as a public input and make the recency check part of the verification logic. There doesn&#x27;t seem to be a similar mechanism for obfuscated functions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;recent-block-oracle&quot;&gt;Recent block oracle&lt;&#x2F;h2&gt;
&lt;p&gt;If we had some oracle that givens us a recent &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt; we can simplify the &lt;span class=&quot;math math-inline&quot;&gt;\c{evm\_verify}&lt;&#x2F;span&gt; and solve the problem in &lt;span class=&quot;math math-inline&quot;&gt;\hat f&lt;&#x2F;span&gt;. But building such an oracle so it can be used in &lt;span class=&quot;math math-inline&quot;&gt;\hat f&lt;&#x2F;span&gt; is hard.&lt;&#x2F;p&gt;
&lt;p&gt;Suppose we have an oracle that on request signs the latest &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt; with some &lt;span class=&quot;math math-inline&quot;&gt;\c{signature}&lt;&#x2F;span&gt; such that we can use a pure computable function &lt;span class=&quot;math math-inline&quot;&gt;\c{verify}\p{\c{chain\_state}, \c{signature}}&lt;&#x2F;span&gt;. The first problem is that this introduces a new long running private key, which was exactly what we were trying to avoid. Turning this into a smart contract account just recurses the problem. The second problem is that the signature can simply be replayed. While this limits an attacker to old &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt;, a notable improvement, it&#x27;s not where I&#x27;d like it yet.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe we could make it such that the signature is also tied to the instance. That way the only usable &lt;span class=&quot;math math-inline&quot;&gt;\c{chain\_state}&lt;&#x2F;span&gt; for a nullifier is the one that was first used for that nullifier. This seems reasonable because now a leak of old keys only de-anonymizes the nullifiers made with those keys. Furthermore we can consider this &lt;span class=&quot;math math-inline&quot;&gt;\c{signature}&lt;&#x2F;span&gt; to be a secret between the oracle and the user.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f\p{
    \begin{array}{c}
    \c{chain\_state}, x,\\ \c{oracle\_signature},\\ \c{user\_signature}
    \end{array}
}
= \begin{cases}
\H\p{\c{entropy}, x} &amp;amp; 
\begin{array}{l}
\c{oracle\_verify}\p{\H\p{\c{chain\_state}, \c{user\_id}, x}, \c{oracle\_signature}} \\
\c{evm\_verify\p{\c{chain\_state},\c{user\_id},x,\c{user\_signature}}}
\end{array}\\
⊥ &amp;amp; \text{otherwise}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Again we generate obfuscated &lt;span class=&quot;math math-inline&quot;&gt;\hat f&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\c{user\_id}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\c{entropy}&lt;&#x2F;span&gt; hardcoded. The zkp becomes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
\begin{array}{c}
\c{block\_hash},\c{root},\\
\c{context}, \c{nullifier}, \\\c{message}
\\ \hline
\c{merkle\_proof}, \c{user},\\
\c{chain\_state}, \\ \c{user\_signature}_1, \\ \c{user\_signature}_2, \\ \c{oracle\_signature}
\end{array}
\middle\vert
\begin{array}{l}
\c{block\_hash} = \c{state\_hash}\p{\c{chain\_state}} \\
\c{evm\_verify}\p{\c{chain\_state}, \c{user\_id}, \H\p{\c{context}, \c{message}}, \c{user\_signature}_1} \\[1em]
\c{nullifier} = \hat f\p{\c{chain\_state}, \c{context}, \c{oracle\_signature}, \c{user\_signature}_2} \\
\c{public\_key} = \c{derive\_public\_key}\p{\c{private\_key}} \\
\c{verify\_inclusion}\p{\c{merkle\_proof}, \c{public\_key}}
\end{array}
}]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-solutions&quot;&gt;Other solutions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;secret-key-nullifiers&quot;&gt;Secret key nullifiers?&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s say we have some secret &lt;span class=&quot;math math-inline&quot;&gt;\c{entropy}&lt;&#x2F;span&gt; and derive nullifiers as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\c{nullifier} = \H\p{\c{entropy}, \c{user\_id}, \c{context}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This works as long as only the user can make queries. Above we derived an elaborate scheme using &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{iO}&lt;&#x2F;span&gt; to achieve this, but there are alternatives such as a trusted server, MPC, FHE, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;identity-based-encryption&quot;&gt;Identity based encryption?&lt;&#x2F;h3&gt;
&lt;p&gt;Maybe &lt;em&gt;identity based encryption&lt;&#x2F;em&gt; can help? &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;825.pdf&quot;&gt;MMT23&lt;&#x2F;a&gt; describes a scheme that allows users to request a private key without revealing their identity to the server.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;private-sets&quot;&gt;Private sets?&lt;&#x2F;h3&gt;
&lt;p&gt;What if instead of nullifers we maintained a set of &lt;span class=&quot;math math-inline&quot;&gt;\c{user\_id}&lt;&#x2F;span&gt;&#x27;s such that it is only possible to add to the set only once but not possible to query set membership. This seems very challenging as given a &lt;span class=&quot;math math-inline&quot;&gt;\c{user\_id}&lt;&#x2F;span&gt;, an attempting to add it will reveal if it was already a member.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;blind-signatures&quot;&gt;Blind signatures?&lt;&#x2F;h3&gt;
&lt;p&gt;The user generates a random nullifier. On seeing a valid zksnark the server signs the blinded nullifier. The user unblinds the nullifier and gets a server-signed nullifier.&lt;&#x2F;p&gt;
&lt;p&gt;Not sure how this helps. The server could avoid handing out nullifiers twice, but at this point it&#x27;s not much different from the server encrypting nullifiers for the users.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Evaluation Basis</title>
        <published>2023-09-21T00:00:00+00:00</published>
        <updated>2023-09-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/evaluation-basis/"/>
        <id>https://2π.com/23/evaluation-basis/</id>
        
        <content type="html" xml:base="https://2π.com/23/evaluation-basis/">&lt;h1 id=&quot;evaluation-basis&quot;&gt;Evaluation Basis&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\vec#1{\bm{#1}}
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\Mod#1{\delim[{#1}]}
\gdef\F{\mathbb{F}}
\gdef\NTT{\mathsf{NTT}}
\gdef\Mul{\mathsf{Mul}}
\gdef\D#1{\mathrm{\partial}_{#1}}
\gdef\Z{\mathrm{Z}}
\gdef\ω{\mathrm{ω}}
\gdef\set#1{\delim\{{#1}\}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a finite field &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; we can construct a polynomial ring &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Fermat&#x27;s little theorem: &lt;span class=&quot;math math-inline&quot;&gt;X^q-X&lt;&#x2F;span&gt; has as roots all of&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Frobenius_endomorphism&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; is a prime field or order &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\F}(X) = X^p - X&lt;&#x2F;span&gt; has as roots all elements of &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fermat%27s_little_theorem&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\Z_{\F}&amp;#39;(X) = p⋅X^{p-1} - 1 = -1&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim\vert{\F_q[X]_{&amp;lt;n}}\vert = q^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\F_q[X]_{&amp;lt;n} \sim \F_q^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim\vert{\F_q → \F_q}\vert = q^q
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Basis for &lt;span class=&quot;math math-inline&quot;&gt;\F_q[X]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
E_a(X)
= \frac{\Z_{\F \setminus \set{a}}(X)}{\Z_{\F}&amp;#39;(a)}
= -\frac{X^p - X}{X - a}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Idea.&lt;&#x2F;strong&gt; Since &lt;span class=&quot;math math-inline&quot;&gt;X^{q-1}&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;X=0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; otherwise we have &lt;span class=&quot;math math-inline&quot;&gt;E_0(X) = 1 - X^{q-1}&lt;&#x2F;span&gt;. Furthermore we have &lt;span class=&quot;math math-inline&quot;&gt;E_a(X) = E_0(X-a)&lt;&#x2F;span&gt;. This gives&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
1 - \p{X-a}^{q-1} &amp;amp;= -\frac{X^q - X}{X - a} \\
\p{X-a} - \p{X-a}^q &amp;amp;= -\p{X^q - X} \\
X-a - \p{X-a}^q &amp;amp;= -X^q + X \\
\p{X-a}^q &amp;amp;= X^q - a \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Which is a basic consequence of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Frobenius_endomorphism.&quot;&gt;Frobenius endomorphism&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fermat%27s_little_theorem&quot;&gt;Fermat&#x27;s little theorem&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This creates a map from functions over &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\F_q[X]_{&amp;lt;q}&lt;&#x2F;span&gt;. Given &lt;span class=&quot;math math-inline&quot;&gt;f(x)&lt;&#x2F;span&gt; the equivalent &lt;span class=&quot;math math-inline&quot;&gt;P(X)&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = \sum_{a∈\F} f(a) ⋅ E_a\p{X}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\F}(X) = X^p - X
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So we can not distinguish between &lt;span class=&quot;math math-inline&quot;&gt;\F_q[X]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\F_q[X]&#x2F;\p{X^q-X}&lt;&#x2F;span&gt; by evaluations. But what about the differential operator &lt;span class=&quot;math math-inline&quot;&gt;\D{X}&lt;&#x2F;span&gt;? Can it somehow shift in the &lt;span class=&quot;math math-inline&quot;&gt;X^q&lt;&#x2F;span&gt; and higher terms?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\D{X} X^q = q⋅X^{q-1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and since &lt;span class=&quot;math math-inline&quot;&gt;q = 0&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; this is also zero. So the differential operator also does not distinguish.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; How does this work in extension fields? We would already have &lt;span class=&quot;math math-inline&quot;&gt;p = 0&lt;&#x2F;span&gt; not &lt;span class=&quot;math math-inline&quot;&gt;q = p^n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;strong&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Derivation_(differential_algebra)&quot;&gt;derivative operator&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; is a linear map that satisfies &lt;span class=&quot;math math-inline&quot;&gt;\D{X}\p{a⋅b} = \D{X}\p{a}⋅b + a⋅\D{X}\p{b}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Given that every function can be represented by a polynomial. How does the multiplicative inversion operator look?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(X) = \frac{1}{P(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can start simple by &lt;span class=&quot;math math-inline&quot;&gt;\frac 1X&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X) &amp;amp;= \sum_{a∈\F} f(a) ⋅ E_a\p{X} \\
&amp;amp;= - \sum_{a∈\F} \frac 1a ⋅\frac{X^p - X}{X - a} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Or the applicative-inversion operator.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(X) = P^{-1}(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;monomial-basis&quot;&gt;Monomial basis&lt;&#x2F;h2&gt;
&lt;p&gt;Given a field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; and a polynomial ring &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&lt;&#x2F;span&gt; over it. A &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-term polynomials &lt;span class=&quot;math math-inline&quot;&gt;P∈\F[X]&lt;&#x2F;span&gt; can be written in monomial form&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = c_0 + c_1 ⋅ X + c_2 ⋅ X^2 + ⋯ + c_{n-1} ⋅ X^{n-1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\vec c ∈ \F^n&lt;&#x2F;span&gt; is the vector of coefficients. This is a basis in the linear algebra sense as we can construct a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec m ∈ \F[X]^n&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; is the inner product &lt;span class=&quot;math math-inline&quot;&gt;\vec c ⋅ \vec m&lt;&#x2F;span&gt;. Such a &lt;span class=&quot;math math-inline&quot;&gt;\vec m&lt;&#x2F;span&gt; is called a &lt;em&gt;standard basis&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = \begin{bmatrix}
c_0 \\ c_1 \\ c_2 \\ ⋮ \\ c_{n-1}
\end{bmatrix} ⋅
\begin{bmatrix}
1 \\ X \\ X^2 \\ ⋮ \\ X^{n-1}
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zero-polynomial&quot;&gt;Zero polynomial&lt;&#x2F;h2&gt;
&lt;p&gt;Polynomials that can be factored into a constant linear factors are called &lt;em&gt;splitting&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = a⋅(X - x_0)⋅(X - x_1)⋅⋯⋅(X - x_{n-1})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;the set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S \subset \F&lt;&#x2F;span&gt; are called roots as &lt;span class=&quot;math math-inline&quot;&gt;P(x) = 0&lt;&#x2F;span&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;x ∈ \mathcal S&lt;&#x2F;span&gt;. Define the &lt;em&gt;zero polynomial&lt;&#x2F;em&gt; over a set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\mathcal S}(X) = \prod_{x∈\mathcal X} \p{X - x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;this is the minimal polynomial such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\forall_{x ∈ \mathcal S}\quad \Z_{\mathcal S}(x) = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;the roots allow for some set theoretic operations (&lt;strong&gt;todo.&lt;&#x2F;strong&gt; generalize to multisets)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\Z_{\mathcal A \cup \mathcal B}(X) &amp;amp;= \frac{\Z_{\mathcal A}(X)⋅\Z_{\mathcal B}(X)}{\Z_{\mathcal A ∩ \mathcal B}(X)} &amp;amp;
\Z_{\mathcal A \setminus \mathcal B}(X) &amp;amp;= \frac{\Z_{\mathcal A}(X)}{\Z_{\mathcal A ∩ \mathcal B}(X)} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;in particular for &lt;span class=&quot;math math-inline&quot;&gt;x ∈ \mathcal S&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\mathcal S \setminus \set{x}}(X) = \frac{\Z_{\mathcal S}(X)}{X - x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;derivative&quot;&gt;Derivative&lt;&#x2F;h3&gt;
&lt;p&gt;The derivative of &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\mathcal S}&lt;&#x2F;span&gt; can be found using the product rule or the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Logarithmic_derivative&quot;&gt;logarithmic derivative&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\Z_{\mathcal S}&amp;#39;(X) &amp;amp;= \sum_{x∈\mathcal S} \Z_{\mathcal S \setminus \set{x}}(X) =
\sum_{x∈\mathcal S} \frac{\Z_{\mathcal S}(X)}{X - x} =
\Z_{\mathcal S}(X) ⋅ \sum_{x∈\mathcal S} \frac{1}{X - x}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first form is suitable to evaluate on the domain &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt;, which has an elegant result:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\forall_{x ∈ \mathcal S}\quad
\Z_{\mathcal S}&amp;#39;(x) = \Z_{\mathcal S \setminus \set{x}}(x)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;specific-values&quot;&gt;Specific values&lt;&#x2F;h3&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt; are the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th roots of unity &lt;span class=&quot;math math-inline&quot;&gt;\mathcal Ω_n = \set{1, ω_n, ω_n^2, …, ω_n^{n-1}}&lt;&#x2F;span&gt; the zero polynomial has a sparse monomial form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\Z_{\mathcal Ω_n}(X) &amp;amp;= X^n - 1 &amp;amp;\quad
\Z_{\mathcal Ω_n}&amp;#39;(X) &amp;amp;= n⋅X^{n-1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt; is the sequence &lt;span class=&quot;math math-inline&quot;&gt;[0,n) = \set{0,1,2,…,n-1}&lt;&#x2F;span&gt; the zero polynomial is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Falling_and_rising_factorials&quot;&gt;falling factorial&lt;&#x2F;a&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;(-n, 0]&lt;&#x2F;span&gt; it is the rising factorial:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\Z_{[0,n)}(X) &amp;amp;= X^{\underline{n}} &amp;amp;\quad
\Z_{(-n,0]}(X) &amp;amp;= X^{\overline{n}} &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;These are related to the factorial and gamma function&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\Z_{[0,n)}(X) &amp;amp;= \frac{\Gamma\p{X + 1}}{\Gamma\p{X - n + 1}} &amp;amp;\quad
\Z_{(-n,0]}(X) &amp;amp;= \frac{\Gamma\p{X + n}}{\Gamma\p{X}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In general they have lots of uses in combinatorics and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Umbral_calculus&quot;&gt;umbral calculus&lt;&#x2F;a&gt;  (&lt;strong&gt;todo&lt;&#x2F;strong&gt; explore)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;evaluation-basis-1&quot;&gt;Evaluation basis&lt;&#x2F;h2&gt;
&lt;p&gt;Given an &lt;em&gt;evaluation domain&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \F^n&lt;&#x2F;span&gt; containing &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; distinct elements, we can also represent &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; uniquely by its evaluations &lt;span class=&quot;math math-inline&quot;&gt;\vec y ∈ \F^n&lt;&#x2F;span&gt; on this domain &lt;span class=&quot;math math-inline&quot;&gt;y_i = P(x_i)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We can again construct a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Standard_basis&quot;&gt;standard basis&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\vec L ∈ \F[X]^n&lt;&#x2F;span&gt;, in this case called a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lagrange_polynomial&quot;&gt;Lagrange basis&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i(X) = \frac{\Z_{\vec x \setminus \set{x_i}}(X)}{\Z_{\vec x \setminus \set{x_i}}(x_i)}
= \frac{\Z_{\vec x \setminus \set{x_i}}(X)}{\Z_{\vec x}&amp;#39;(x_i)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;these satisfy &lt;span class=&quot;math math-inline&quot;&gt;L_i(x_j) = δ_{ij}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If we define normalization constants &lt;span class=&quot;math math-inline&quot;&gt;l_i = \p{Z_{\vec x \setminus \set{x_i}}(x_i)}^{-1}&lt;&#x2F;span&gt; then we get the &lt;em&gt;barycentric form&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i(X) = \Z_{\vec x}(X)⋅\frac{l_i}{X - x_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;this form is useful for evaluating the basis in &lt;span class=&quot;math math-inline&quot;&gt;x∉\vec x&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;Z_{\vec x}(x)&lt;&#x2F;span&gt; can be computed once. The fraction is ill-defined on &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; though, so this form is more appropriate&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i(X) = l_i⋅\frac{\Z_{\vec x}(X)}{X - x_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;derivative-1&quot;&gt;Derivative&lt;&#x2F;h3&gt;
&lt;p&gt;Say we have &lt;span class=&quot;math math-inline&quot;&gt;P(X) ∈ \F[X]&lt;&#x2F;span&gt; represented in evaluations basis on domain &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;\vec p&lt;&#x2F;span&gt; and we wish to know its derivative &lt;span class=&quot;math math-inline&quot;&gt;P&amp;#39;(X)&lt;&#x2F;span&gt; in the same basis.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X) &amp;amp;= \sum_{i∈[0,n)} p_i ⋅ L_i(x) &amp;amp;\quad
P&amp;#39;(X) &amp;amp;= \sum_{i∈[0,n)} p_i ⋅ L_i&amp;#39;(x)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;so to compute &lt;span class=&quot;math math-inline&quot;&gt;P&amp;#39;(X)&lt;&#x2F;span&gt; in the evaluation basis we need to know &lt;span class=&quot;math math-inline&quot;&gt;L_i&amp;#39;(x_j)&lt;&#x2F;span&gt;. Start with computing the derivate&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i&amp;#39;(X) = \sum_{x∈\mathcal S \setminus \set{x_i}} \frac{L_i(X)}{X - x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i&amp;#39;(X) = \frac{\Z_{\vec x \setminus \set{x_i}}&amp;#39;(X)}{\Z_{\vec x \setminus \set{x_i}}(x_i)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
L_i&amp;#39;(X) &amp;amp;= l_i⋅ \p{\frac{Z_{\vec x}&amp;#39;(X)}{X - x_i} - \frac{Z_{\vec x}(X)}{\p{X - x_i}^2}} \\
&amp;amp;= l_i⋅ \p{ \frac{\sum_{x∈\mathcal S} \frac{\Z_{\mathcal S}(X)}{X - x}}{X - x_i} - \frac{Z_{\vec x}(X)}{\p{X - x_i}^2}} \\
&amp;amp;= l_i⋅ \p{ \sum_{x∈\mathcal S} \frac{\Z_{\mathcal S}(X)}{\p{X - x}⋅\p{X - x_i}} - \frac{Z_{\vec x}(X)}{\p{X - x_i}^2} }  \\
&amp;amp;= l_i⋅\sum_{x∈\mathcal S  \setminus \set{x_i}} \frac{\Z_{\mathcal S}(X)}{\p{X - x}⋅\p{X - x_i}} \\
&amp;amp;= l_i ⋅ \frac{\Z_{\mathcal S}(X)}{X - x_i}⋅\sum_{x∈\mathcal S  \setminus \set{x_i}} \frac{1}{X - x} \\
&amp;amp;= l_i ⋅ \frac{\Z_{\mathcal S}(X)}{X - x_i}⋅\sum_{x∈\mathcal S  \setminus \set{x_i}} \frac{1}{X - x} \\
&amp;amp;= L_i(X) ⋅ \sum_{x∈\mathcal S \setminus \set{x_i}} \frac{1}{X - x} \\
&amp;amp;= \sum_{x∈\mathcal S \setminus \set{x_i}} \frac{L_i(X)}{X - x} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;p&gt;The on-diagonal elements &lt;span class=&quot;math math-inline&quot;&gt;L_i&amp;#39;(x_i)&lt;&#x2F;span&gt; are&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i&amp;#39;(x_i) = \frac{\Z_{\vec x \setminus \set{x_i}}&amp;#39;(x_i)}{\Z_{\vec x \setminus \set{x_i}}(x_i)} = \sum_{x ∈ \vec x \setminus \set{x_i}} \frac{1}{x_j - x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The off-diagonal elements &lt;span class=&quot;math math-inline&quot;&gt;L_i&amp;#39;(x_j)&lt;&#x2F;span&gt; are&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i&amp;#39;(x_j) = \frac{\Z_{\vec x \setminus \set{x_i}}&amp;#39;(x_j)}{\Z_{\vec x \setminus \set{x_i}}(x_i)}
= \frac{\Z_{\vec x \setminus \set{x_i,x_j}}(x_j)}{\Z_{\vec x \setminus \set{x_i}}(x_i)}
= \frac{1}{x_j - x_i}⋅ \frac{\Z_{\vec x \setminus \set{x_j}}(x_j)}{\Z_{\vec x \setminus \set{x_i}}(x_i)}
= \frac{1}{x_j - x_i}⋅ \frac{\Z_{\vec x}&amp;#39;(x_j)}{\Z_{\vec x}&amp;#39;(x_i)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Todo.&lt;&#x2F;strong&gt; What is the rank of this matrix?&lt;&#x2F;p&gt;
&lt;h4 id=&quot;roots-of-unity&quot;&gt;Roots of unity&lt;&#x2F;h4&gt;
&lt;p&gt;On-diagonal&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i&amp;#39;(\ω^i)
= \frac{\Z_{Ω_n \setminus \set{\ω^i}}&amp;#39;(\ω^i)}{\Z_{Ω_n \setminus \set{\ω^i}}(\ω^i)}
= \frac{\Z_{Ω_n \setminus \set{\ω^i}}&amp;#39;(\ω^i)}{\Z_{Ω_n}&amp;#39;(\ω^i)}
= \frac{?
}{n⋅\ω^{-i}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\mathcal A \setminus \mathcal B}&amp;#39;(X)
= \D{X} \p{\frac{\Z_{\mathcal A}(X)}{\Z_{\mathcal A ∩ \mathcal B}(X)}}
= \frac{\Z_{\mathcal A}&amp;#39;(X)⋅\Z_{\mathcal A ∩ \mathcal B}(X) - \Z_{\mathcal A}(X)⋅\Z_{\mathcal A ∩ \mathcal B}&amp;#39;(X)}{\p{\Z_{\mathcal A ∩ \mathcal B}(X)}^2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
\Z_{Ω_n \setminus \set{\ω^i}}&#x27;(X)
&amp;amp;= \frac{\Z_{Ω_n}&#x27;(X)⋅\Z_{\set{\ω^i}}(X) - \Z_{Ω_n}(X)⋅\Z_{\set{\ω^i}}&#x27;(X)}{\p{\Z_{\set{\ω^i}}(X)}^2} \
&amp;amp;= \frac{\p{n⋅X^{n -1}}⋅\p{X - \ω^i} - \p{X^n-1}}{\p{X - \ω^i}^2} \
&amp;amp;= \frac{n⋅X^{n -1}}{X - \ω^i}&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;\frac{\p{X^n-1}}{\p{X - \ω^i}^2}
\end{aligned}
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Off-diagonal&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i&amp;#39;(\ω^j)
= \frac{1}{\ω^j - \ω^i}⋅ \frac{\Z_{Ω_n}&amp;#39;(\ω^j)}{\Z_{Ω_n}&amp;#39;(\ω^i)}
= \frac{\ω^{i -j}}{\ω^j - \ω^i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cauchy_matrix&quot;&gt;Cauchy-like matrix&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;to do.&lt;&#x2F;strong&gt; Test these results numerically.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.ams.org&#x2F;journals&#x2F;mcom&#x2F;1988-50-181&#x2F;S0025-5718-1988-0917825-9&#x2F;S0025-5718-1988-0917825-9.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;link.springer.com&#x2F;article&#x2F;10.1007&#x2F;s11075-022-01391-y&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1506.02285.pdf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;crt-basis&quot;&gt;CRT Basis&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
E_i(X) = \delim[{\frac{m_1(X)}{M(X)}}]_{m_1}⋅\frac{M(X)}{m_1(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ntt-solution&quot;&gt;NTT Solution&lt;&#x2F;h2&gt;
&lt;p&gt;Pick &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; roots of unity and use &lt;span class=&quot;math math-inline&quot;&gt;\NTT_n&lt;&#x2F;span&gt; to convert to monomial form. Convert back to a coset &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;\NTT_n&lt;&#x2F;span&gt;. Square all values &lt;span class=&quot;math math-inline&quot;&gt;2⋅n⋅\Mul_{\F}&lt;&#x2F;span&gt;, convert to monomial form &lt;span class=&quot;math math-inline&quot;&gt;\NTT_{2⋅n}&lt;&#x2F;span&gt;. We now have coefficients of &lt;span class=&quot;math math-inline&quot;&gt;P^2(X)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basis-transformations&quot;&gt;Basis transformations&lt;&#x2F;h2&gt;
&lt;p&gt;Can every polynomial basis be written as a combination of point and derivative?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Polynomial bases
&lt;ul&gt;
&lt;li&gt;Evaluation bases
&lt;ul&gt;
&lt;li&gt;Roots of unity bases&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Derivative bases (Taylor series)
&lt;ul&gt;
&lt;li&gt;Monomial basis&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Mixed point&#x2F;derivative bases&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Category:Orthogonal_polynomials&lt;&#x2F;li&gt;
&lt;li&gt;Are there more?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The conversion between monomial and roots-of-unity is the &lt;span class=&quot;math math-inline&quot;&gt;\NTT&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multiplication-by-a-constant-polynomial&quot;&gt;Multiplication by a constant polynomial&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;division-by-a-constant-polynomial&quot;&gt;Division by a constant polynomial&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;modulo-operations&quot;&gt;Modulo operations&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;derivatives&quot;&gt;Derivatives&lt;&#x2F;h2&gt;
&lt;p&gt;The formal derivative is a linear operator.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\D{X} P(X)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\D{X}\p{a_0 + a_1 ⋅X + a_2 ⋅ X^2 + ⋯} = a_1 + 2 ⋅ a_2 ⋅ X + 3⋅a_3⋅X^3 ⋯
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a basis, linear operators can be expressed as a matrix. The monomial basis almost diagonalizes the derivative operator:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 2 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 3 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Q: Which basis diagonalizes it? Is there always such a basis?&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Multiplier_(Fourier_analysis)#On_the_unit_circle&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multiplications&quot;&gt;Multiplications&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;P(c ⋅ X)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_0 + a_1⋅(c⋅ X) + a_2 ⋅ (c ⋅ X)^2 + ⋯ = a_0 + a_1 ⋅ c ⋅ X + a_2 ⋅ c^2 ⋅ X^2 + ⋯
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; c &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; c^2 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; c^3 \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;translations&quot;&gt;Translations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;P(X+δ)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_0 + a_1⋅(X + δ) + a_2 ⋅ (X + δ)^2 + ⋯ = \p{a_0 + a_1⋅δ + a_2 ⋅δ^2 + ⋯} + \p{a_1 + 2⋅a_2⋅δ + ⋯}⋅X + \p{a_2 + ⋯} ⋅ X^2 + ⋯
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(X + δ)^2 = X^2 + 2⋅δ⋅X + δ^2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chinese-remainder-theorem&quot;&gt;Chinese Remainder Theorem&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;A.B mod X-1&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Companion_matrix#Diagonalizability&lt;&#x2F;p&gt;
&lt;p&gt;HSS Matrices: https:&#x2F;&#x2F;mipals.github.io&#x2F;pubs&#x2F;matrix&#x2F;hss&#x2F;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;coding-theory&quot;&gt;Coding Theory&lt;&#x2F;h2&gt;
&lt;p&gt;Reed-Solomon codes. Linear block codes that have maximal separation.&lt;&#x2F;p&gt;
&lt;p&gt;Vandermonde matrix &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
I &amp;amp; V
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Cauchy matrix &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
I &amp;amp; C
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;web.eecs.utk.edu&#x2F;~jplank&#x2F;plank&#x2F;papers&#x2F;CS-05-569.pdf&lt;&#x2F;p&gt;
&lt;h3 id=&quot;list-decoding&quot;&gt;List decoding&lt;&#x2F;h3&gt;
&lt;h2 id=&quot;linear-algebra&quot;&gt;Linear Algebra&lt;&#x2F;h2&gt;
&lt;p&gt;A vector space &lt;span class=&quot;math math-inline&quot;&gt;\F^n&lt;&#x2F;span&gt; and a matrix space &lt;span class=&quot;math math-inline&quot;&gt;\F^{n×m}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Linear maps &lt;span class=&quot;math math-inline&quot;&gt;\F^n ⇄ \F^{n×1}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\F^n ⇄ \F^{1×n}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\F^n → \F^{n×1}&lt;&#x2F;span&gt;. Given &lt;span class=&quot;math math-inline&quot;&gt;\vec a ∈ \F^n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;row-vector, column-vector, diagonal matrix.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\begin{bmatrix}
a_0 \\ a_1 \\ ⋮ \\ a_{n-1}
\end{bmatrix},
\begin{bmatrix}
a_0 &amp;amp; a_1 &amp;amp; ⋯ &amp;amp; a_{n-1}
\end{bmatrix},
\begin{bmatrix}
a_0 &amp;amp; 0 &amp;amp; ⋯ &amp;amp; 0 \\
0 &amp;amp; a_1 &amp;amp; ⋯ &amp;amp; 0 \\
⋮ &amp;amp; ⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\ 
0 &amp;amp; 0 &amp;amp; ⋯ &amp;amp; a_{n-1}
\end{bmatrix}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;row-major order, column-mjor order, z-order&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Row-_and_column-major_order&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\F^{n⋅m} ⇄ \F^{n×m}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\begin{bmatrix}
a_0 &amp;amp; a_1 &amp;amp; ⋯ &amp;amp; a_{n-1} \\
a_n &amp;amp; a_{n+1} &amp;amp; ⋯ &amp;amp; a_{2⋅n - 1} \\
⋮ &amp;amp; ⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\ 
a_{(m-1)⋅n} &amp;amp; a_{(m-1)⋅n + 1} &amp;amp; ⋯ &amp;amp; a_{n⋅m-1}
\end{bmatrix},
\begin{bmatrix}
a_0 &amp;amp; a_n &amp;amp; ⋯ &amp;amp; a_{(m-1)⋅n-1} \\
a_1 &amp;amp; a_{n+1} &amp;amp; ⋯ &amp;amp; a_{(m-1)⋅n - 1} \\
⋮ &amp;amp; ⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\ 
a_{n-1} &amp;amp; a_{2⋅n - 1} &amp;amp; ⋯ &amp;amp; a_{n⋅m-1}
\end{bmatrix}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Z-order_curve&lt;&#x2F;p&gt;
&lt;p&gt;CRT order. As in Good-Thomas FFT.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
n → (\Mod{n}_{m_1},\Mod{n}_{m_2})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Permutation Matrix&lt;&#x2F;p&gt;
&lt;p&gt;Rader&#x27;s permutation  https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rader%27s_FFT_algorithm&lt;&#x2F;p&gt;
&lt;p&gt;The multiplicative group is cyclic&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\F_p^× ≅ C_{p-1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Permutations</title>
        <published>2023-09-21T00:00:00+00:00</published>
        <updated>2023-09-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/permutation/"/>
        <id>https://2π.com/23/permutation/</id>
        
        <content type="html" xml:base="https://2π.com/23/permutation/">&lt;h1 id=&quot;permutations&quot;&gt;Permutations&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\ceil#1{\delim\lceil{#1}\rceil}
\gdef\unit#1{\ \text{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;n!&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;@dabo&#x2F;rkP8Pcf9t&quot;&gt;CB22&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The challenge is to construct a data structure for storing a permutation that takes less space than the trivial data structure, specifically 1.44 n fewer bits, while retaining the ability to quickly evaluate the permutation.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Take a permutation over &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt; elements. This can be represented as a vector of &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt; &lt;span class=&quot;math math-inline&quot;&gt;32&lt;&#x2F;span&gt;-bit integers, taking &lt;span class=&quot;math math-inline&quot;&gt;17.2\unit{GB}&lt;&#x2F;span&gt;. In theory it can be stored in&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ceil{\log_{256} 2^{32}! } = 16.4 \unit{GB}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can do better if we build an &lt;em&gt;approximate&lt;&#x2F;em&gt; lookup that returns a set of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; elements, one of which is the permutation. Split the permutation in blocks of size &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. If we ignore the order within the blocks, they can be stored in &lt;span class=&quot;math math-inline&quot;&gt;\ceil{\log_{256} {2^{32} \choose n} }&lt;&#x2F;span&gt; bytes. If we pick a blocksize of &lt;span class=&quot;math math-inline&quot;&gt;1427&lt;&#x2F;span&gt; we get &lt;span class=&quot;math math-inline&quot;&gt;4096\unit{B}&lt;&#x2F;span&gt;, a disk block.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cr.yp.to&#x2F;papers&#x2F;controlbits-20200923.pdf&quot;&gt;Ber20&lt;&#x2F;a&gt; Bernstein 2020. Verified fast formulas for control bits for permutation networks.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;@dabo&#x2F;rkP8Pcf9t&quot;&gt;CB22&lt;&#x2F;a&gt; Cohen, Boneh (2022). How to Store a Permutation Compactly.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;0902.1038.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;0902.1038.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Snarkpack</title>
        <published>2023-09-21T00:00:00+00:00</published>
        <updated>2023-09-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/snarkpack/"/>
        <id>https://2π.com/23/snarkpack/</id>
        
        <content type="html" xml:base="https://2π.com/23/snarkpack/">&lt;h1 id=&quot;snarkpack&quot;&gt;Snarkpack&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\e{\operatorname{e}}
\gdef\k#1{\mathbf{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Recall a &lt;a href=&quot;&#x2F;22&#x2F;groth16&#x2F;#verifying&quot;&gt;Groth16 verification&lt;&#x2F;a&gt; with verification key &lt;span class=&quot;math math-inline&quot;&gt;\p{\k D,\k E,\k F,\k G,\k L_i}&lt;&#x2F;span&gt; and proof &lt;span class=&quot;math math-inline&quot;&gt;\p{w_i, A, B, C}&lt;&#x2F;span&gt;. It&#x27;s made to sum to zero and signs are absorbed into the constants.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0 = \e(A, B) + \e(\k E, \k F) + \e\p{ \sum_{i ∊ [0, p)} w_i ⋅ \k L_i, \k G} + \e\p{C, \k D}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; proofs &lt;span class=&quot;math math-inline&quot;&gt;\p{w_{ij}, A_j, B_j, C_j}&lt;&#x2F;span&gt; and linearly combine them using &lt;span class=&quot;math math-inline&quot;&gt;r_j&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
0 &amp;amp; = \sum_j r_j ⋅ \p{\e(A_j, B_j) + \e(\k E, \k F) + \e\p{ \sum_{i ∊ [0, p)} w_{ij} ⋅ \k L_i, \k G} + \e\p{C_j, \k D} } \\
&amp;amp; = \sum_j \e\p{r_j ⋅ A_j, B_j} + \e\p{\sum_j r_j ⋅ \k E, \k F} + \e\p{\sum_j \sum_{i ∊ [0, p)} r_j ⋅ w_{ij} ⋅ \k L_i, \k G} + \e\p{\sum_{i ∊ [0, p)} r_j ⋅ C, \k D} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Can we proof soundness if the prover only provided &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i ∊ [0, p)}  r_j ⋅ A_j&lt;&#x2F;span&gt; and&#x2F;or the equivalent for &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;? Extreme case&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0 = \e(A, B) + \e(\k E, \k F) + \e\p{\sum_j \sum_{i ∊ [0, p)} r_j ⋅ w_i ⋅ \k L_i, \k G} + \e\p{C, \k D}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;r_j&lt;&#x2F;span&gt; is derived by pseudorandom function from &lt;span class=&quot;math math-inline&quot;&gt;w_{ij}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;529&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;529&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>zkp update</title>
        <published>2023-09-21T00:00:00+00:00</published>
        <updated>2023-09-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/24/folding/"/>
        <id>https://2π.com/24/folding/</id>
        
        <content type="html" xml:base="https://2π.com/24/folding/">&lt;h1 id=&quot;zkp-update&quot;&gt;zkp update&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\ps#1{\delim\{{#1}\}}
\gdef\F{\mathbb F}
\gdef\set#1{\mathcal #1}
\gdef\vec#1{\bm #1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;customizable-constraint-system-ccs&quot;&gt;Customizable Constraint System (CCS)&lt;&#x2F;h2&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;552.pdf&quot;&gt;STW23&lt;&#x2F;a&gt; a CCS is a set of sets of matrices &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt; such that a witness &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; satisfies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{\set T ∈ \set S}\ 
\bigodot_{M ∈ \set T}\ 
M ⋅ \vec w
= \vec 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\bigodot&lt;&#x2F;span&gt; is the Hadamard product.&lt;&#x2F;p&gt;
&lt;p&gt;A R1CS constraint is a triplet of matrices &lt;span class=&quot;math math-inline&quot;&gt;(A,B,C)&lt;&#x2F;span&gt; such that a witness &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; satisfies &lt;span class=&quot;math math-inline&quot;&gt;\p{A⋅\vec w} ∘ \p{B⋅\vec w} = C⋅\vec w&lt;&#x2F;span&gt;. A R1CS becomes &lt;span class=&quot;math math-inline&quot;&gt;\ps{\ps{A,B},\ps{-C}}&lt;&#x2F;span&gt;. For transformation of Plonkish and AIR constraints see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2023&#x2F;552.pdf&quot;&gt;STW23&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; CCS is closed under conjunction. Given two CCS constraints &lt;span class=&quot;math math-inline&quot;&gt;\set S_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\set S_2&lt;&#x2F;span&gt; with matrices of size &lt;span class=&quot;math math-inline&quot;&gt;m_1×n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m_2×n&lt;&#x2F;span&gt; respectively. Convert all matrices to &lt;span class=&quot;math math-inline&quot;&gt;\p{m_1 + m_2} × n&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;\begin{bmatrix}M \\ 0\end{bmatrix}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\begin{bmatrix}0 \\ M\end{bmatrix}&lt;&#x2F;span&gt; respectively. The conjoined CSS is now the union.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; The degree of the CCS is &lt;span class=&quot;math math-inline&quot;&gt;\max_{\set T ∈ \set S} \delim\vert{\set T}\vert&lt;&#x2F;span&gt; and the rank is the number of rows in the matrices. Can we reduce the degree by increasing the rank? For example we can reduce &lt;span class=&quot;math math-inline&quot;&gt;\ps{\ps{A, B}, \ps{C}}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\ps{\ps{D, D}, \ps{E}}&lt;&#x2F;span&gt; at doubling rank.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;CCS+&lt;&#x2F;strong&gt; extends this with a lookup argument. In addition to the above there is a set of indices &lt;span class=&quot;math math-inline&quot;&gt;\set I&lt;&#x2F;span&gt; and a set of field elements &lt;span class=&quot;math math-inline&quot;&gt;\set T&lt;&#x2F;span&gt;. The witness additional satisfies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatornamewithlimits{\large \forall}_{i∈\set I}\ 
w_i ∈ \set T
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; How do we conjoin table lookup arguments?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sum-check&quot;&gt;Sum-check&lt;&#x2F;h2&gt;
&lt;p&gt;Introduced in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;users.cs.fiu.edu&#x2F;~giri&#x2F;teach&#x2F;5420&#x2F;f01&#x2F;LundIPS.pdf&quot;&gt;LFKN92&lt;&#x2F;a&gt;. Given multivariate polynomial &lt;span class=&quot;math math-inline&quot;&gt;G ∈ \F[X_1,…,X_n]&lt;&#x2F;span&gt; and domain &lt;span class=&quot;math math-inline&quot;&gt;\set B = \set B_1 × ⋯ × \set B_n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\set B_i \subseteq \F&lt;&#x2F;span&gt;. Typically &lt;span class=&quot;math math-inline&quot;&gt;\set B = \ps{0,1}^n&lt;&#x2F;span&gt;. We want to proof&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
h = \sum_{\vec x ∈ \set B} G\p{\vec x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The prover commits to &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt; such that the verifier has oracle access to evaluate &lt;span class=&quot;math math-inline&quot;&gt;G(\vec x)&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \F^n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Prover sends &lt;span class=&quot;math math-inline&quot;&gt;G_1 ∈ \F[X]&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
G_1(X) = \sum_{\vec x ∈ \set B_2×⋯×\set B_n} G\p{X, \vec x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;verifier checks&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
h = \sum_{x ∈ \set B_1} G_1\p{x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;verifier sends random &lt;span class=&quot;math math-inline&quot;&gt;r ∈ \F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;prover sends&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
G_2(X) = \sum_{\vec x ∈ \set B_3×⋯×\set B_n} G\p{r, X, \vec x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;verifier checks that degree of &lt;span class=&quot;math math-inline&quot;&gt;G_2&lt;&#x2F;span&gt; equals degree of &lt;span class=&quot;math math-inline&quot;&gt;X_2&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt; and&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
G_1(r) = \sum_{x ∈ \set B_2} G_2\p{x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;repeat until prover sends&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
G_n(X) = G\p{\vec r, X}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;. Verifier takes a random &lt;span class=&quot;math math-inline&quot;&gt;r ∈ \F&lt;&#x2F;span&gt; and checks&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
G_n(r) = G(\vec r)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;using any means to compute &lt;span class=&quot;math math-inline&quot;&gt;G\p{\vec r}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;See Justin Thaler&#x27;s notes on Sum-Check: https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;sumcheck.pdf&lt;&#x2F;p&gt;
&lt;p&gt;Small field optimization https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;small-sumcheck.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;zkproof.org&#x2F;2020&#x2F;03&#x2F;16&#x2F;sum-checkprotocol&#x2F;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gkr&quot;&gt;GKR&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;wp-content&#x2F;uploads&#x2F;2008&#x2F;01&#x2F;GoldwasserKR08a.pdf&quot;&gt;GKR08&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;gkrnotes.pdf
https:&#x2F;&#x2F;people.cs.georgetown.edu&#x2F;jthaler&#x2F;GKRNote.pdf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;logup&quot;&gt;logUp&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;cached-quotients&quot;&gt;Cached Quotients&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;lasso-lookups&quot;&gt;Lasso lookups&lt;&#x2F;h2&gt;
&lt;p&gt;For fixed sparse matrix &lt;span class=&quot;math math-inline&quot;&gt;\mathrm M&lt;&#x2F;span&gt; and committed vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec v&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; show:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathrm M ⋅ \vec v = \vec a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Discrete Convolutions</title>
        <published>2023-09-19T00:00:00+00:00</published>
        <updated>2023-09-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/convolution/"/>
        <id>https://2π.com/23/convolution/</id>
        
        <content type="html" xml:base="https://2π.com/23/convolution/">&lt;h1 id=&quot;discrete-convolutions&quot;&gt;Discrete Convolutions&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\Mod#1{\ \operatorname{mod}\ #1}
\gdef\F{\mathbb F}
\gdef\M{\mathsf{\small M}}
\gdef\A{\mathsf{\small A}}
\gdef\Mc{\mathsf{\small M^c}}
\gdef\NTT{\mathsf{\small NTT}}
\gdef\LCV{\mathsf{\small LCV}}
\gdef\CCV{\mathsf{\small CCV}}
\gdef\NCV{\mathsf{\small NCV}}
\gdef\CRT{\mathsf{\small CRT}}
\gdef\ω{\text{ω}}
\gdef\O{\mathcal{O}}
\gdef\T{\mathsf{T}}
\gdef\E{\mathrm{E}}
\gdef\diag{\operatorname{diag}}
\gdef\I{\operatorname{I}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given two sequence &lt;span class=&quot;math math-inline&quot;&gt;a_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b_i&lt;&#x2F;span&gt; their &lt;em&gt;discrete convolution&lt;&#x2F;em&gt;, denoted &lt;span class=&quot;math math-inline&quot;&gt;a * b&lt;&#x2F;span&gt;, is a sequence &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c_i = \sum_j a_j ⋅ b_{i - j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In practice the sequences are finite and variations of convolution depend on how the boundary is handled. In a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Convolution#Discrete_convolution&quot;&gt;linear convolution&lt;&#x2F;a&gt; the sequences are zero-extended where missing. In a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Circular_convolution#Discrete_sequences&quot;&gt;cyclic convolution&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; have the same length &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and indices are taken modulo &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, i.e. they are periodic. If &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; is periodic except for the sign changing every period it is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Negacyclic_convolution&quot;&gt;negacyclic convolution&lt;&#x2F;a&gt;. Finally, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cross-correlation&quot;&gt;correlation&lt;&#x2F;a&gt;, denoted &lt;span class=&quot;math math-inline&quot;&gt;c = a \star b&lt;&#x2F;span&gt;, is the same but with &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; reversed, i.e. &lt;span class=&quot;math math-inline&quot;&gt;c_i = \sum_j a_j ⋅ b_{i + j}&lt;&#x2F;span&gt;. In linear algebra, linear and cyclic convolution are equivalent to multiplying by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Toeplitz_matrix&quot;&gt;Toeplitz&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Circulant_matrix&quot;&gt;circulant&lt;&#x2F;a&gt; matrix respectively. In digital signal processing, linear convolutions are known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Finite_impulse_response&quot;&gt;finite impulse response&lt;&#x2F;a&gt; filters. In machine learning, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Convolutional_neural_network&quot;&gt;convolutional neural networks&lt;&#x2F;a&gt; make use of linear convolutions. They also show up in many &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;23&#x2F;convolution&#x2F;ntt&quot;&gt;FFT and NTT&lt;&#x2F;a&gt; algorithms.&lt;&#x2F;p&gt;
&lt;p&gt;In algebra, discrete convolutions appears as polynomial multiplication. Given &lt;span class=&quot;math math-inline&quot;&gt;A, B, C ∈ \F[X]&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;C(X) = A(X) ⋅ B(X)&lt;&#x2F;span&gt;. Write all three coefficient form like  &lt;span class=&quot;math math-inline&quot;&gt;A(x) = a_0 + a_1 ⋅ X + a_2⋅ X^2 ⋯&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;c = a * b&lt;&#x2F;span&gt;. This is the core of the large &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.numberworld.org&#x2F;y-cruncher&#x2F;internals&#x2F;multiplication.html&quot;&gt;integer multiplication&lt;&#x2F;a&gt; problem. To see this consider that a number like &lt;span class=&quot;math math-inline&quot;&gt;123&lt;&#x2F;span&gt; equals the polynomial &lt;span class=&quot;math math-inline&quot;&gt;3 + 2 ⋅ X + 1 ⋅ X^2&lt;&#x2F;span&gt; evaluated at &lt;span class=&quot;math math-inline&quot;&gt;X=10&lt;&#x2F;span&gt;. To multiply two large numbers one multiplies the polynomials and then does carry propagation. The resulting inner multiplications will have argument of size equal to the chosen base. When this base is itself large the method can be employed recursively.&lt;&#x2F;p&gt;
&lt;p&gt;Using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_ring&quot;&gt;polynomials (quotient) rings&lt;&#x2F;a&gt; we can concisely define linear (&lt;span class=&quot;math math-inline&quot;&gt;\LCV&lt;&#x2F;span&gt;), cyclic (&lt;span class=&quot;math math-inline&quot;&gt;\CCV&lt;&#x2F;span&gt;) and negacyclic (&lt;span class=&quot;math math-inline&quot;&gt;\NCV&lt;&#x2F;span&gt;) convolution as multiplication in &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&#x2F;\p{X^n -1}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&#x2F;\p{X^n +1}&lt;&#x2F;span&gt; respectively:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
&amp;amp;\LCV &amp;amp;\hspace{3em} C(X) &amp;amp;= A(X) ⋅ B(X) \\
&amp;amp;\CCV &amp;amp;             C(X) &amp;amp;= A(X) ⋅ B(X) \Mod{X^n - 1} \\
&amp;amp;\NCV &amp;amp;             C(X) &amp;amp;= A(X) ⋅ B(X) \Mod{X^n + 1} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A direct computation of &lt;span class=&quot;math math-inline&quot;&gt;n×m&lt;&#x2F;span&gt; linear convolution takes &lt;span class=&quot;math math-inline&quot;&gt;\p{n⋅m -n -m +1}⋅\A +  n⋅m⋅\M&lt;&#x2F;span&gt;. For a (nega) cyclic convolution this is &lt;span class=&quot;math math-inline&quot;&gt;n⋅\p{n - 1}⋅\A + n^2⋅\M&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;toom-cook-methods&quot;&gt;Toom-Cook methods&lt;&#x2F;h2&gt;
&lt;p&gt;Polynomials can be represented in many bases. The most common is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Monomial_basis&quot;&gt;monomial basis&lt;&#x2F;a&gt;, i.e. coefficient form. But they can also be represented by their evaluations on an (arbitrary) set of points &lt;span class=&quot;math math-inline&quot;&gt;\{x_i\}&lt;&#x2F;span&gt;, called a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lagrange_polynomial&quot;&gt;Lagrange basis&lt;&#x2F;a&gt;. The Lagrange bases have the unique advantage that polynomial multiplication becomes a simple &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hadamard_product_(matrices)&quot;&gt;element-wise product&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C(x_i) = A(x_i) ⋅ B(x_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Computing this takes only &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; multiplication operations, where &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is the number of terms in &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;. To use it for convolutions we also need to convert between monomial basis and lagrange basis (i.e. coefficients and evaluations). This is a basis transformation in the linear algebra sense, so we can represent it as a so-called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vandermonde_matrix&quot;&gt;Vandermonde matrix&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
V = \begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; ⋯ \\[.7em]
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; ⋯ \\[.7em]
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; ⋯ \\[.7em]
⋮ &amp;amp; ⋮ &amp;amp; ⋮ &amp;amp; ⋱
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can now write the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Toom%E2%80%93Cook_multiplication#Details&quot;&gt;Toom-Cook&lt;&#x2F;a&gt; convolution algorithm using matrix-vector products &lt;span class=&quot;math math-inline&quot;&gt;⋅&lt;&#x2F;span&gt; and element-wise products &lt;span class=&quot;math math-inline&quot;&gt;∘&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c = V^{-1} ⋅\p{\p{V⋅a} ∘ \p{V⋅b}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The evaluation points &lt;span class=&quot;math math-inline&quot;&gt;\{x_i\}&lt;&#x2F;span&gt; are arbitrary, so which points do we pick to make computations as easy as possible? Some great first candidates are &lt;span class=&quot;math math-inline&quot;&gt;\{0, 1, -1\}&lt;&#x2F;span&gt;, which respectively result in the first coefficient, the sum of the coefficients and the alternating sum of the coefficients; no multiplications required.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;point-at-infinity&quot;&gt;Point at infinity&lt;&#x2F;h3&gt;
&lt;p&gt;Convolutions are symmetrical under reversing all the sequences. In the polynomial version this means reversing the order of the coefficients, or equivalently &lt;span class=&quot;math math-inline&quot;&gt;P&amp;#39;(X) = P(X^{-1})⋅X^{n-1}&lt;&#x2F;span&gt;. Each previous evaluation point has a corresponding point &lt;span class=&quot;math math-inline&quot;&gt;x&amp;#39; = x^{-1}&lt;&#x2F;span&gt; in the reverse polynomials, except for &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; which has no inverse. Instead, we get a new evaluation point &lt;span class=&quot;math math-inline&quot;&gt;x&amp;#39;= 0&lt;&#x2F;span&gt; that has no pre-image. Evaluating at the new point &lt;span class=&quot;math math-inline&quot;&gt;P&amp;#39;(0)&lt;&#x2F;span&gt; gives &lt;span class=&quot;math math-inline&quot;&gt;p_{n-1}&lt;&#x2F;span&gt; much like &lt;span class=&quot;math math-inline&quot;&gt;P(0) = p_0&lt;&#x2F;span&gt;. These are both trivial to compute, so we like to add both to our evaluation set. Somewhat informally we refer to the &lt;span class=&quot;math math-inline&quot;&gt;x&amp;#39;=0&lt;&#x2F;span&gt; point as the &#x27;point at infinity&#x27; &lt;span class=&quot;math math-inline&quot;&gt;x=∞&lt;&#x2F;span&gt;. Fortunately there is an easy way to add it to a Vandermonde matrix: coefficient reversal is identical to reversing a row in the matrix, so the row corresponding to &lt;span class=&quot;math math-inline&quot;&gt;x=∞&lt;&#x2F;span&gt; is the row corresponding &lt;span class=&quot;math math-inline&quot;&gt;x=0&lt;&#x2F;span&gt; reversed, i.e. &lt;span class=&quot;math math-inline&quot;&gt;\begin{bmatrix} 0 &amp;amp; 0 &amp;amp; ⋯ &amp;amp; 1 \end{bmatrix}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;karatsuba&quot;&gt;Karatsuba&lt;&#x2F;h3&gt;
&lt;p&gt;Consider a &lt;span class=&quot;math math-inline&quot;&gt;2×2&lt;&#x2F;span&gt; linear convolution. The result is &lt;span class=&quot;math math-inline&quot;&gt;c = [a_0\!⋅\!b_0,\ a_0\!⋅\!b_1\!+\!a_1\!⋅\!b_0,\ a_1\!⋅\!b_1]&lt;&#x2F;span&gt; which takes four multiplications when evaluated directly. If we pick the basis &lt;span class=&quot;math math-inline&quot;&gt;\{0, 1, ∞\}&lt;&#x2F;span&gt; we end up with the following algorithm for a &lt;span class=&quot;math math-inline&quot;&gt;2×2&lt;&#x2F;span&gt; linear convolution:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
V &amp;amp;= \begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 \\
1 &amp;amp; 1 &amp;amp; 1 \\
0 &amp;amp; 0 &amp;amp; 1 \\
\end{bmatrix} &amp;amp;\hspace{2em}
V^{-1} &amp;amp;= \begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 \\
-1 &amp;amp; 1 &amp;amp; -1 \\
0 &amp;amp; 0 &amp;amp; 1 \\
\end{bmatrix} &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\begin{bmatrix} c_0 \\ c_1 \\ c_2 \end{bmatrix} &amp;amp;=
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 \\
-1 &amp;amp; 1 &amp;amp; -1 \\
0 &amp;amp; 0 &amp;amp; 1 \\
\end{bmatrix} ⋅ \p{
\p{
\begin{bmatrix}
1 &amp;amp; 0 \\
1 &amp;amp; 1 \\
0 &amp;amp; 1 \\
\end{bmatrix} ⋅
\begin{bmatrix} a_0 \\ a_1\end{bmatrix}
} ∘ \p{
\begin{bmatrix}
1 &amp;amp; 0 \\
1 &amp;amp; 1 \\
0 &amp;amp; 1 \\
\end{bmatrix} ⋅
\begin{bmatrix} b_0 \\ b_1\end{bmatrix}
}
}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that when we trim the &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; matrix we should keep the &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; in the last column for the point at infinity. Writing out all the multiplications we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
y_0 &amp;amp;= a_0 ⋅ b_0                      &amp;amp;\hspace{2em} c_0 &amp;amp;= y_0\\
y_1 &amp;amp;= \p{a_0 + a_1} ⋅ \p{b_0 + b_1}  &amp;amp; c_1 &amp;amp;= y_1 - y_0 - y_2\\
y_2 &amp;amp;= a_1 ⋅ b_1                      &amp;amp; c_2 &amp;amp;= y_2 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We now have three multiplications instead of four, though we went from one addition to four. This specific instance of Toom-Cook is known as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Karatsuba_algorithm&quot;&gt;Karatsuba algorithm&lt;&#x2F;a&gt;. It is the core of the first sub-quadratic method for multiplication and led to the development of Toom-Cook and other methods.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;toom-3&quot;&gt;Toom-3&lt;&#x2F;h3&gt;
&lt;p&gt;For a &lt;span class=&quot;math math-inline&quot;&gt;3×3&lt;&#x2F;span&gt; linear convolution we can use the points &lt;span class=&quot;math math-inline&quot;&gt;\{0,1,-1,-2,∞\}&lt;&#x2F;span&gt;, these are all the easy ones with the addition of &lt;span class=&quot;math math-inline&quot;&gt;-2&lt;&#x2F;span&gt;. The choice of &lt;span class=&quot;math math-inline&quot;&gt;-2&lt;&#x2F;span&gt; leads to further optimizations due to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;marco.bodrato.it&#x2F;papers&#x2F;Bodrato2007-OptimalToomCookMultiplicationForBinaryFieldAndIntegers.pdf&quot;&gt;Bod07&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
V &amp;amp;= {\small\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\[.2em]
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1 \\[.2em]
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp; 1 \\[.2em]
1 &amp;amp; -2 &amp;amp; 4 &amp;amp; -8 &amp;amp; 16 \\[.2em]
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 \\
\end{bmatrix}} &amp;amp;\hspace{2em}
V^{-1} &amp;amp;= {\small\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\[.2em]
\frac{1}{2} &amp;amp; \frac{1}{3} &amp;amp; -1 &amp;amp; \frac{1}{6} &amp;amp; -2 \\[.2em]
-1 &amp;amp; \frac{1}{2} &amp;amp; \frac{1}{2} &amp;amp; 0 &amp;amp; -1 \\[.2em]
\frac{1}{2} &amp;amp; -2 &amp;amp; -\frac{1}{2} &amp;amp; -\frac{1}{6} &amp;amp; 2 \\[.2em]
0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1 \\
\end{bmatrix}} &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\begin{bmatrix} c_0 \\ c_1 \\ c_2 \\ c_3 \\ c_4 \end{bmatrix} &amp;amp;=
V^{-1} ⋅ \p{
\p{
{\small\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 \\
1 &amp;amp; 1 &amp;amp; 1 \\
1 &amp;amp; -1 &amp;amp; 1 \\
1 &amp;amp; -2 &amp;amp; 4 \\
0 &amp;amp; 0 &amp;amp; 1 \\
\end{bmatrix}} ⋅
\begin{bmatrix} a_0 \\ a_1 \\ a_2 \end{bmatrix}
} ∘ \p{
{\small\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 \\
1 &amp;amp; 1 &amp;amp; 1 \\
1 &amp;amp; -1 &amp;amp; 1 \\
1 &amp;amp; -2 &amp;amp; 4 \\
0 &amp;amp; 0 &amp;amp; 1 \\
\end{bmatrix}} ⋅
\begin{bmatrix} b_0 \\ b_1 \\ b_2 \end{bmatrix}
}
}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Both &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;V^{-1}&lt;&#x2F;span&gt; allow for more efficient evaluation than direct. Take &lt;span class=&quot;math math-inline&quot;&gt;t = a_0 + a_2&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;a&amp;#39; = V⋅a&lt;&#x2F;span&gt; can be computed as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a_0&amp;#39; &amp;amp;= a_0 \\
a_1&amp;#39; &amp;amp;= t + a_1 \\
a_2&amp;#39; &amp;amp;= t - a_1 \\
a_3&amp;#39; &amp;amp;= 2⋅\p{a_2&amp;#39; + a_2} - a_0 \\
a_4&amp;#39; &amp;amp;= a_2 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;using add for doubling, this gives &lt;span class=&quot;math math-inline&quot;&gt;5⋅\A&lt;&#x2F;span&gt; instead of &lt;span class=&quot;math math-inline&quot;&gt;7⋅\A + \Mc&lt;&#x2F;span&gt;. Similarly &lt;span class=&quot;math math-inline&quot;&gt;V^{-1} ⋅ y&lt;&#x2F;span&gt; can be computed in &lt;span class=&quot;math math-inline&quot;&gt;9⋅\A + 3⋅\Mc&lt;&#x2F;span&gt; instead of &lt;span class=&quot;math math-inline&quot;&gt;14⋅\A + 9⋅\Mc&lt;&#x2F;span&gt; using&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{split}
\begin{aligned}
t_1 &amp;amp;= \frac 12 ⋅ \p{y_1 - y_2} \\
t_2 &amp;amp;= y_2 - y_0 \\
t_3 &amp;amp;= \frac 13 ⋅ \p{y_3 - y_1}
\end{aligned}
\end{split}
\hspace{2em}
\begin{split}
\begin{aligned}
c_0 &amp;amp;= y_0 \\
c_2 &amp;amp;= t_2 + t_1 - y_4 \\
c_3 &amp;amp;= \frac 12 ⋅ \p{t_2 + t_3} + 2⋅y_4 \\
c_1 &amp;amp;= t_1 - c_3 \\
c_4 &amp;amp;= y_4 \\
\end{aligned}
\end{split}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This brings the total to &lt;span class=&quot;math math-inline&quot;&gt;19⋅\A + 3⋅\Mc + 5⋅\M&lt;&#x2F;span&gt; compared to &lt;span class=&quot;math math-inline&quot;&gt;4⋅\A + 9⋅\M&lt;&#x2F;span&gt; for direct convolution.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Are there algorithms to find the optimal evaluation for a given matrix?&lt;&#x2F;p&gt;
&lt;p&gt;For larger sizes &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gmplib.org&#x2F;manual&#x2F;Higher-degree-Toom_0027n_0027half&quot;&gt;GMP&lt;&#x2F;a&gt; uses the point set &lt;span class=&quot;math math-inline&quot;&gt;\{0, ∞, +1, -1, \pm 2^i, \pm 2^{-i} \}&lt;&#x2F;span&gt;. This gives some implementation optimization opportunities, but doing the evaluation&#x2F;interpolation step efficiently becomes increasingly difficult for larger sets. Without evaluation tricks this would result in &lt;span class=&quot;math math-inline&quot;&gt;\p{}⋅\A + \p{}⋅\Mc + \p{2⋅n - 1}⋅\M&lt;&#x2F;span&gt; for an &lt;span class=&quot;math math-inline&quot;&gt;n×n&lt;&#x2F;span&gt; linear convolution.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\Mc&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\p{2⋅n - 5}⋅\p{n - 1}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt;.
&lt;span class=&quot;math math-inline&quot;&gt;\p{2⋅n - 3}⋅(2⋅n - 1)&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;V^{-1}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;convolution-theorem&quot;&gt;Convolution theorem&lt;&#x2F;h3&gt;
&lt;p&gt;If we pick a &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th order root of unity &lt;span class=&quot;math math-inline&quot;&gt;\ω_n&lt;&#x2F;span&gt; and uses its powers as &lt;span class=&quot;math math-inline&quot;&gt;\{\ω_n^0, \ω_n^1,…,\ω_n^{n-1}\}&lt;&#x2F;span&gt; as evaluation points, then our Vandermonde matrix &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; also becomes a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;DFT_matrix&quot;&gt;DFT Matrix&lt;&#x2F;a&gt; and the evaluation&#x2F;interpolation steps become Fourier transforms &lt;span class=&quot;math math-inline&quot;&gt;\NTT_n&lt;&#x2F;span&gt;. This result is known as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Convolution_theorem#Functions_of_a_discrete_variable_(sequences)&quot;&gt;convolution theorem&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c = \NTT_n^{-1}\p{\NTT_n\p{a} ∘ \NTT_n\p{b} }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This was first used for very large integer multiplication with the carefully optimized &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sch%C3%B6nhage%E2%80%93Strassen_algorithm&quot;&gt;Schönhage–Strassen&lt;&#x2F;a&gt; algorithm. This algorithm was further improved leading to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hal.science&#x2F;hal-02070778&#x2F;file&#x2F;nlogn.pdf&quot;&gt;Harvey-van der Hoeven&lt;&#x2F;a&gt; algorithm which runs in &lt;span class=&quot;math math-inline&quot;&gt;\O\p{n⋅\log n}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bilinear-algorithms&quot;&gt;Bilinear algorithms&lt;&#x2F;h2&gt;
&lt;p&gt;We can generalize the algorithms considered so far as special cases of &lt;em&gt;bilinear algorithms&lt;&#x2F;em&gt; of the form&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c = C⋅\p{\p{A ⋅ a} ∘ \p{B ⋅ b} }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;A∈\F^{\ r × n_a}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;B∈\F^{\ r × n_b}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B∈\F^{\ n_c × r}&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; called the &lt;em&gt;bilinear rank&lt;&#x2F;em&gt;. To motivate this generalization consider the following bilinear algorithm for &lt;span class=&quot;math math-inline&quot;&gt;3×3&lt;&#x2F;span&gt; linear convolution due to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;core&#x2F;books&#x2F;fast-algorithms-for-signal-processing&#x2F;E35F46175F3558980873443CA8A6A4FD&quot;&gt;Bla10&lt;&#x2F;a&gt; (§5.4):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\small
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0 \\
-1 &amp;amp; -1 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 \\
-1 &amp;amp; 1 &amp;amp; -1 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 \\
0 &amp;amp; -1 &amp;amp; -1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 1\\
0 &amp;amp; 0 &amp;amp; 1 &amp;amp; 0 &amp;amp; 0 &amp;amp; 0\\
\end{bmatrix} ⋅ \p{
\p{
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 1 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 1 \\
1 &amp;amp; 1 &amp;amp; 0 \\
1 &amp;amp; 0 &amp;amp; 1 \\
0 &amp;amp; 1 &amp;amp; 1 \\
\end{bmatrix} ⋅
\begin{bmatrix} a_0 \\ a_1 \\ a_2 \end{bmatrix}
} ∘ \p{
\begin{bmatrix}
1 &amp;amp; 0 &amp;amp; 0 \\
0 &amp;amp; 1 &amp;amp; 0 \\
0 &amp;amp; 0 &amp;amp; 1 \\
1 &amp;amp; 1 &amp;amp; 0 \\
1 &amp;amp; 0 &amp;amp; 1 \\
0 &amp;amp; 1 &amp;amp; 1 \\
\end{bmatrix} ⋅
\begin{bmatrix} b_0 \\ b_1 \\ b_2 \end{bmatrix}
}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It has one rank higher than Toom-3, but at &lt;span class=&quot;math math-inline&quot;&gt;13⋅\A + 6⋅\M&lt;&#x2F;span&gt; it has fewer additions and no multiplications by constants. It can also not be formulated as evaluation on some set of points. (&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Can it be formulated as a Winograd factorization?)&lt;&#x2F;p&gt;
&lt;p&gt;Usually A, B and C are sparse by construction. The number of operations required for such matrices are at most&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{m - n} ⋅ \A + k⋅\Mc
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is the number of rows, &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; is the number of non-zero elements and &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; the number of elements not equal to &lt;span class=&quot;math math-inline&quot;&gt;0,1&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;-1&lt;&#x2F;span&gt;. Note that this is an upper bound, as in the example of&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-matrix-exchange-theorem&quot;&gt;The Matrix Exchange Theorem&lt;&#x2F;h3&gt;
&lt;p&gt;In Toom-Cook we have nice &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; matrices, but &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; becomes unwieldy. Fortunately, there is a trick to swap &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt;. This is useful as we can often precompute &lt;span class=&quot;math math-inline&quot;&gt;A⋅a&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;B⋅b&lt;&#x2F;span&gt;. Without loss of generality we&#x27;ll assume swapping &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Start with the observation that &lt;span class=&quot;math math-inline&quot;&gt;x ∘ y  = \diag\p{x}⋅y&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\diag : \F^{\,n} →\F^{\,n×n}&lt;&#x2F;span&gt; is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Diagonal_matrix#Vector-to-matrix_diag_operator&quot;&gt;vector-to-diagonal-matrix operator&lt;&#x2F;a&gt;. Furthermore, given matrices &lt;span class=&quot;math math-inline&quot;&gt;A,B&lt;&#x2F;span&gt; and diagonal matrix &lt;span class=&quot;math math-inline&quot;&gt;D&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;A⋅D⋅B = \p{B⋅\E}^{\T}⋅D⋅\p{\E⋅A}^{\T}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\E&lt;&#x2F;span&gt; is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exchange_matrix&quot;&gt;exchange matrix&lt;&#x2F;a&gt; (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;core&#x2F;books&#x2F;fast-algorithms-for-signal-processing&#x2F;E35F46175F3558980873443CA8A6A4FD&quot;&gt;Bla10&lt;&#x2F;a&gt; 5.6.1). (&lt;strong&gt;To do&lt;&#x2F;strong&gt;. This requires further restrictions such that the matrix is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Persymmetric_matrix&quot;&gt;persymmetric&lt;&#x2F;a&gt;) Note that for any matrix &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\E⋅M&lt;&#x2F;span&gt; is just &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt; with the rows in reverse order and &lt;span class=&quot;math math-inline&quot;&gt;M⋅\E&lt;&#x2F;span&gt; has the columns in reversed. Applying this to our bilinear algorithm results in&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
c &amp;amp;= C ⋅\p{\p{A⋅a} ∘ \p{B⋅b}} \\
&amp;amp;= C ⋅\diag\p{A⋅a} ⋅ B ⋅ b \\
&amp;amp;=  \p{B⋅\E}^{\T}⋅\diag\p{A⋅a} ⋅\p{\E ⋅ C}^{\T} ⋅b \\
&amp;amp;=  \p{B⋅\E}^{\T}⋅\p{ \p{A⋅a} ∘ \p{\p{\E ⋅ C}^{\T} ⋅b }} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;thus we have a new bilinear algorithm where &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; are swapped, transposed and have their rows&#x2F;columns reversed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Does this apply to all kinds of convolutions?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;correlations&quot;&gt;Correlations&lt;&#x2F;h3&gt;
&lt;p&gt;Given an algorithm &lt;span class=&quot;math math-inline&quot;&gt;(A, B, C)&lt;&#x2F;span&gt; for linear convolution, an algorithm for correlation is constructed by &lt;span class=&quot;math math-inline&quot;&gt;(A, C, B)&lt;&#x2F;span&gt;. This is the Matrix Interchange theorem in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;core&#x2F;books&#x2F;fast-algorithms-for-signal-processing&#x2F;E35F46175F3558980873443CA8A6A4FD&quot;&gt;Bla10&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;two-dimensional-convolutions&quot;&gt;Two-dimensional convolutions&lt;&#x2F;h2&gt;
&lt;p&gt;Given a &lt;span class=&quot;math math-inline&quot;&gt;n×m&lt;&#x2F;span&gt; convolution &lt;span class=&quot;math math-inline&quot;&gt;(A_1, B_1, C_1)&lt;&#x2F;span&gt; and a &lt;span class=&quot;math math-inline&quot;&gt;k×l&lt;&#x2F;span&gt; convolution &lt;span class=&quot;math math-inline&quot;&gt;(A_2, B_2, C_2)&lt;&#x2F;span&gt; we can construct a two-dimensional &lt;span class=&quot;math math-inline&quot;&gt;(n,k)×(m,l)&lt;&#x2F;span&gt; convolution as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{A_1⊗A_2, B_1⊗B_2, C_1⊗C_2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the inputs are vectorized with inner dimensions &lt;span class=&quot;math math-inline&quot;&gt;k,l&lt;&#x2F;span&gt;, i.e. &lt;span class=&quot;math math-inline&quot;&gt;(i,j)\mapsto i⋅k +j&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;i⋅l + j&lt;&#x2F;span&gt; respectively. This result holds for linear, cyclic and negacyclic convolutions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Does this hold for general polynomial product mod m? Does this hold in general for bilinear maps?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;overlap-add&quot;&gt;Overlap-add&lt;&#x2F;h3&gt;
&lt;p&gt;Furthermore, we can use this to construct a &lt;span class=&quot;math math-inline&quot;&gt;(n⋅k)×(m⋅l)&lt;&#x2F;span&gt; linear convolution by recombining the outputs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X) &amp;amp;= P_0(X) + P_1(X) ⋅ X^2 \\
Q(X) &amp;amp;= Q_0(X) + Q_1(X) ⋅ X^2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X)⋅Q(X) =
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;agrawal-cooley&quot;&gt;Agrawal-Cooley&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;modular-reduction&quot;&gt;Modular reduction&lt;&#x2F;h3&gt;
&lt;p&gt;Given a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P(X) = \sum_i p_i⋅X^i&lt;&#x2F;span&gt; and a monic modulus &lt;span class=&quot;math math-inline&quot;&gt;M(X) = \sum_i m_i⋅X^i&lt;&#x2F;span&gt; we want to compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(X) = P(X) \Mod M(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
q_0 \\ q_1 \\ ⋮ \\ q_{m-1}
\end{bmatrix}
\left[
\begin{array}{c|c}
\I_m &amp;amp; \begin{array}{ccccc}
m_0 &amp;amp; m_{m-2} &amp;amp; m_{m-3} &amp;amp; ⋯ &amp;amp; \\
m_1 &amp;amp; m_0 &amp;amp; m_{m-2} &amp;amp; ⋯ &amp;amp; \\
m_2 &amp;amp; m_1 &amp;amp; m_0 \\
⋮ &amp;amp; ⋮ &amp;amp; ⋮ &amp;amp; ⋱ \\
m_{m-2} &amp;amp; m_{m-3} &amp;amp; m_{m-4} &amp;amp; ⋯ &amp;amp;
\end{array}
\end{array}
\right] ⋅
\begin{bmatrix}
p_0 \\ p_1 \\ ⋮ \\ p_{n-1}
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left[
\begin{array}{c|c}
\I_m &amp;amp;  \operatorname{Toeplitz}\p{\begin{bmatrix}
m_0 &amp;amp; m_1 &amp;amp; ⋯ &amp;amp; m_{m-2}
\end{bmatrix}}
\end{array}
\right]
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where the Toeplitz matrix is extended with however many columns necessary.&lt;&#x2F;p&gt;
&lt;p&gt;In particular this can be used to turn linear convolution algorithms into (nega)cyclic by reducing modulo &lt;span class=&quot;math math-inline&quot;&gt;X^n \pm 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;winograd-convolution&quot;&gt;Winograd Convolution&lt;&#x2F;h2&gt;
&lt;p&gt;A generalization of Toom-Cook can be made be realizing that evaluating a polynomial at a point &lt;span class=&quot;math math-inline&quot;&gt;P(x_i)&lt;&#x2F;span&gt; is the same as reducing it modulo &lt;span class=&quot;math math-inline&quot;&gt;X - x_i&lt;&#x2F;span&gt;. We are then solving the system of equations&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C(X) = A(X) ⋅ B(X) \mod{X- x_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and then reconstructing &lt;span class=&quot;math math-inline&quot;&gt;C(X)&lt;&#x2F;span&gt; from the residues mod &lt;span class=&quot;math math-inline&quot;&gt;X-x_i&lt;&#x2F;span&gt;. This is a special case of the Chinese Remainder Theorem (&lt;span class=&quot;math math-inline&quot;&gt;\CRT&lt;&#x2F;span&gt;). Generalizing we pick a set of coprime moduli polynomials &lt;span class=&quot;math math-inline&quot;&gt;\{M_i(X)\}&lt;&#x2F;span&gt;, their product &lt;span class=&quot;math math-inline&quot;&gt;M(X) = \prod_i M_i(X)&lt;&#x2F;span&gt; and a CRT basis &lt;span class=&quot;math math-inline&quot;&gt;\{E_i(X)\}&lt;&#x2F;span&gt; (see appendix), compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C_i(X) = \p{A(X) ⋅ B(X) \Mod{M_i(X)}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C(X) = \sum_i C_i(X) ⋅ E_i(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;M(X) = X^n - 1&lt;&#x2F;span&gt; we have cyclic convolution, and with &lt;span class=&quot;math math-inline&quot;&gt;M(X) = X^n + 1&lt;&#x2F;span&gt; negacyclic.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;R_i(X)&lt;&#x2F;span&gt; is a multiple of &lt;span class=&quot;math math-inline&quot;&gt;M_i(X)&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;E_i(X)&lt;&#x2F;span&gt; is a multiple of &lt;span class=&quot;math math-inline&quot;&gt;M(X)&lt;&#x2F;span&gt;, which reflects the fact that &lt;span class=&quot;math math-inline&quot;&gt;\CRT&lt;&#x2F;span&gt; is only unique up to &lt;span class=&quot;math math-inline&quot;&gt;\Mod{M(X)}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Another generalization of point evaluations is to include derivatives at those points. How does this generalization combine with CRT?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Can all bilinear algorithms for convolutions be interpreted as Winograd convolutions? Does this extend to non-convolution bilinear algorithms?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;recursion&quot;&gt;Recursion&lt;&#x2F;h3&gt;
&lt;p&gt;This method allows for recursion. For example to compute a &lt;span class=&quot;math math-inline&quot;&gt;2⋅n&lt;&#x2F;span&gt; sized cyclic convolution we can pick a basis &lt;span class=&quot;math math-inline&quot;&gt;M(X) = (X^n + 1) ⋅ (X^n - 1)&lt;&#x2F;span&gt; and get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
C(X) &amp;amp;= A(X) ⋅ B(X) \mod{X^n - 1} \\
C(X) &amp;amp;= A(X) ⋅ B(X) \mod{X^n + 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{split}\begin{aligned}
E_0(X) &amp;amp;= R_0(X) ⋅\p{X^n + 1} \\
E_1(X) &amp;amp;= R_1(X) ⋅\p{X^n - 1}
\end{aligned}\end{split}\hspace{3em}
\begin{split}\begin{aligned}
R_0(X) &amp;amp;= \p{X^n + 1}^{-1} \mod{X^n - 1} \\
R_1(X) &amp;amp;= \p{X^n - 1}^{-1} \mod{X^n + 1}
\end{aligned}\end{split}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X^n + 1 \Mod\p{X^n - 1} = 2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X^n - 1 \Mod\p{X^n + 1} = -2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So &lt;span class=&quot;math math-inline&quot;&gt;R_0(X) = \frac 12&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;R_1(X) = -\frac 12&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
E_0(X) &amp;amp;= \frac 12 ⋅\p{X^n + 1} &amp;amp;\hspace{2em}
E_1(X) &amp;amp;= -\frac 12 ⋅\p{X^n - 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;re-introducing-the-point-at-infinity&quot;&gt;Re-introducing the point at infinity&lt;&#x2F;h3&gt;
&lt;p&gt;We can add a &lt;span class=&quot;math math-inline&quot;&gt;M_i(X) = X - ∞&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X^{n_c - 1} ⋅ C(X^{-1}) = \p{X^{n_a - 1} ⋅ A(X^{-1})} ⋅ \p{X^{n_b - 1} ⋅ B(X^{-1})} \mod{X - 0}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;larger-convolutions&quot;&gt;Larger convolutions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;nested-convolutions&quot;&gt;Nested Convolutions&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;agarwal-cooley&quot;&gt;Agarwal-Cooley&lt;&#x2F;h3&gt;
&lt;h2 id=&quot;lower-bounds&quot;&gt;Lower bounds&lt;&#x2F;h2&gt;
&lt;p&gt;Linear convolution can not be computed with fewer than &lt;span class=&quot;math math-inline&quot;&gt;\p{n_a + n_b - 1}⋅\M&lt;&#x2F;span&gt; (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;core&#x2F;books&#x2F;fast-algorithms-for-signal-processing&#x2F;E35F46175F3558980873443CA8A6A4FD&quot;&gt;Bla10&lt;&#x2F;a&gt; thm 5.8.3)&lt;&#x2F;p&gt;
&lt;p&gt;The polynomial product &lt;span class=&quot;math math-inline&quot;&gt;A(X)⋅B(X) \Mod{M(X)}&lt;&#x2F;span&gt; can not be computed with less than &lt;span class=&quot;math math-inline&quot;&gt;\p{2⋅n - t}⋅\M&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; is the number of prime factors of &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&lt;&#x2F;span&gt;. (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;core&#x2F;books&#x2F;fast-algorithms-for-signal-processing&#x2F;E35F46175F3558980873443CA8A6A4FD&quot;&gt;Bla10&lt;&#x2F;a&gt; thm 5.8.5)&lt;&#x2F;p&gt;
&lt;p&gt;Specifically, cyclic convolution can not be computed with fewer then &lt;span class=&quot;math math-inline&quot;&gt;\p{2⋅n - t}⋅\M&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; is the number of prime factors of &lt;span class=&quot;math math-inline&quot;&gt;X^n -1&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1910.13367&quot;&gt;JS20&lt;&#x2F;a&gt; Ju, Solomonik (2020). Derivation and Analysis of Fast Bilinear Algorithms for Convolution. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jucaleb4&#x2F;Bilinear-Algorithms-for-Convolution&quot;&gt;Github&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;marco.bodrato.it&#x2F;papers&#x2F;Bodrato2007-OptimalToomCookMultiplicationForBinaryFieldAndIntegers.pdf&quot;&gt;Bod07&lt;&#x2F;a&gt; Bodrato (2007). Towards Optimal Toom-Cook Multiplication for Univariate and Multivariate Polynomials in Characteristic 2 and 0.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cambridge.org&#x2F;core&#x2F;books&#x2F;fast-algorithms-for-signal-processing&#x2F;E35F46175F3558980873443CA8A6A4FD&quot;&gt;Bla10&lt;&#x2F;a&gt; Blahut (2010). Fast Algorithms for Signal Processing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gbv.de&#x2F;dms&#x2F;goettingen&#x2F;229527833.pdf&quot;&gt;TAL97&lt;&#x2F;a&gt; Tolimieri, An, Lu (1997). Algorithms for Discrete Fourier Transform and Convolution.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;appendix-solving-the-chinese-remainder-theorem&quot;&gt;Appendix: Solving the Chinese Remainder Theorem&lt;&#x2F;h2&gt;
&lt;p&gt;Given a  set of coprime moduli &lt;span class=&quot;math math-inline&quot;&gt;m_i&lt;&#x2F;span&gt; and values &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;x_i = x \Mod{m_i}&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;, we want to reconstruct &lt;span class=&quot;math math-inline&quot;&gt;x \Mod{m}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;m = \prod_i m_i&lt;&#x2F;span&gt;. To do this we will construct a basis &lt;span class=&quot;math math-inline&quot;&gt;e_i&lt;&#x2F;span&gt; similar to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lagrange_polynomial&quot;&gt;Lagrange basis&lt;&#x2F;a&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = \sum_i x_i ⋅ e_i \quad \Mod{m}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;e_i \Mod{m_j}&lt;&#x2F;span&gt; equals &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; when &lt;span class=&quot;math math-inline&quot;&gt;i≠1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; when &lt;span class=&quot;math math-inline&quot;&gt;i=j&lt;&#x2F;span&gt;. The former implies &lt;span class=&quot;math math-inline&quot;&gt;e_i = r_i ⋅ \prod_{i≠j} m_j&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;r_j&lt;&#x2F;span&gt;. The latter implies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
r_i  = \Bigl(\prod_{i≠j} m_j\Bigr)^{-1} \quad\Mod{m_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There are multiple solutions &lt;span class=&quot;math math-inline&quot;&gt;r_i&amp;#39; = r_i + k⋅m_i&lt;&#x2F;span&gt; and this reflects multiple solutions &lt;span class=&quot;math math-inline&quot;&gt;x&amp;#39;= x + k⋅m&lt;&#x2F;span&gt;. By convention the smallest is used. We can write the CRT basis concisely using &lt;span class=&quot;math math-inline&quot;&gt;[-]_m&lt;&#x2F;span&gt; for modular reduction as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
e_i  = \frac{m}{m_i}⋅\left[\frac{m_i}{m}\right]_{m_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If the moduli are not coprime we can correct with &lt;span class=&quot;math math-inline&quot;&gt;m = \operatorname{lcm}\p{m_i}&lt;&#x2F;span&gt;. (&lt;strong&gt;Question&lt;&#x2F;strong&gt; does the above solution using &lt;span class=&quot;math math-inline&quot;&gt;\frac{m}{m_i}&lt;&#x2F;span&gt; still hold?) Note that in this case solutions may not exist. For example if &lt;span class=&quot;math math-inline&quot;&gt;m_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m_1&lt;&#x2F;span&gt; have a common factor &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;x_0 ≠ x_1 \Mod d&lt;&#x2F;span&gt; there is no solution. (&lt;strong&gt;Question&lt;&#x2F;strong&gt; what does the above solution produce in this case?).&lt;&#x2F;p&gt;
&lt;p&gt;The CRT establishes a ring isomorphism&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\F&#x2F;m ≅ \F&#x2F;m_0 × \F&#x2F;m_1 × ⋯
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with the maps &lt;span class=&quot;math math-inline&quot;&gt;x \mapsto (\left[x\right]_{m_0}, \left[x\right]_{m_1},… )&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(x_0, x_1, …) \mapsto x_0⋅e_0 + x_1⋅e_1+⋯&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; How does this generalize to include derivatives?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-applications-to-proof-systems&quot;&gt;Appendix: applications to proof systems&lt;&#x2F;h2&gt;
&lt;p&gt;Note the similarity between bilinear algorithms and an R1CS predicate &lt;span class=&quot;math math-inline&quot;&gt;φ(w) ⇔ \p{A ⋅ w} ∘ \p{B ⋅ w} = C⋅w&lt;&#x2F;span&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; is invertible this can be restated as a bilinear algorithm &lt;span class=&quot;math math-inline&quot;&gt;β(a,b) = C^{-1}⋅\p{\p{A ⋅ a} ∘ \p{B ⋅ b} }&lt;&#x2F;span&gt; and we have &lt;span class=&quot;math math-inline&quot;&gt;φ(w) ⇔ β(w,w) = w&lt;&#x2F;span&gt;. Applying this to the matrix exchange theorem we get that a given R1CS &lt;span class=&quot;math math-inline&quot;&gt;(A, B, C)&lt;&#x2F;span&gt; is equivalent to &lt;span class=&quot;math math-inline&quot;&gt;\p{A, \p{\E ⋅ C^{-1}}^{\T}, \p{\p{B⋅\E}^{\T}}^{-1}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Since linear convolutions is equivalent to polynomial multiplication, a polynomial commitment scheme allows for an efficient proof of convolution. To proof &lt;span class=&quot;math math-inline&quot;&gt;c = a*b&lt;&#x2F;span&gt;, proof &lt;span class=&quot;math math-inline&quot;&gt;C(τ) = A(τ)⋅B(τ)&lt;&#x2F;span&gt; at a random point &lt;span class=&quot;math math-inline&quot;&gt;τ∈\F&lt;&#x2F;span&gt;. To proof a size &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; (nega)cyclic convolution test that the following holds for &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; term polynomials &lt;span class=&quot;math math-inline&quot;&gt;A, B, C, Q&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C(τ) + Q(τ)⋅\p{τ^n \pm 1}= A(τ)⋅B(τ)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we have a proof for reduction from FFT to convolution this could be used to proof FFTs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-bilinear-maps&quot;&gt;Appendix: bilinear maps&lt;&#x2F;h2&gt;
&lt;p&gt;Given vectors spaces &lt;span class=&quot;math math-inline&quot;&gt;U, V, W&lt;&#x2F;span&gt; over a base field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, a bilinear map is a function &lt;span class=&quot;math math-inline&quot;&gt;f: U × V → W&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f(u_1 + u_2, v) &amp;amp;= f(u_1, v) + f(u_2, v) &amp;amp; f(λ⋅u, v) &amp;amp;= λ⋅f(u,v)\\
f(u, v_1 + v_2) &amp;amp;= f(u, v_1) + f(u, v_2) &amp;amp; f(u, λ⋅v) &amp;amp;= λ⋅f(u,v) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bilinear algorithms are bilinear maps, so convolutions and polynomial modular multiplication are bilinear maps. Other examples of bilinear maps are matrix multiplications and the cross product. When &lt;span class=&quot;math math-inline&quot;&gt;W = \F&lt;&#x2F;span&gt;, it is also called a bilinear form with further examples such as inner products.&lt;&#x2F;p&gt;
&lt;p&gt;Given bases a bilinear map can be written as a tensor &lt;span class=&quot;math math-inline&quot;&gt;u, v, w&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_k(u, v) = \sum f_{ijk} ⋅ u_i ⋅ v_j
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this a bilinear algorithm follows. For each non-zero element of &lt;span class=&quot;math math-inline&quot;&gt;f_{ijk}&lt;&#x2F;span&gt; create rows in &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; with all zeros except for a single &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; in columns i and j respectively. To &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; we add a column with the value &lt;span class=&quot;math math-inline&quot;&gt;f_{ijk}&lt;&#x2F;span&gt; in row &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;. This has complexity &lt;span class=&quot;math math-inline&quot;&gt;m⋅ \Mc+n⋅\M&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is the number of nonzero entries and &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; the number of nontrivial entries.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-polynomial-composition&quot;&gt;Appendix: Polynomial composition&lt;&#x2F;h2&gt;
&lt;p&gt;Given two polynomials &lt;span class=&quot;math math-inline&quot;&gt;P(X) = \sum_i p_i ⋅ X^i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q(X) = \sum_i q_i ⋅ X^i&lt;&#x2F;span&gt;, define the composition &lt;span class=&quot;math math-inline&quot;&gt;R(X) = P(Q(X))&lt;&#x2F;span&gt; where the coefficients of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; are given by:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
R(X) &amp;amp;= P(Q(X)) \\
&amp;amp;= \sum_i p_i ⋅ \p{ \sum_j q_j ⋅ X^j }^i
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Multinomial theorem.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X)^i &amp;amp;= \p{ \sum_j p_j ⋅ X^j }^i
&amp;amp;= \sum_j \frac{i!}{j_1! j_2! j_3!⋯} ⋅ p_{j_1} ⋅ p_{j_2} ⋅ ⋯ X^{j_1 + j_2 + ⋯}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X)^i &amp;amp;= \p{ \sum_j q_j ⋅ X^j }^i
&amp;amp;= \sum_j \frac{i!}{j_1! j_2! j_3!⋯} ⋅
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;to-do&quot;&gt;To do&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2201.10369.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;2201.10369.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cr.yp.to&#x2F;lineartime&#x2F;multapps-20080515.pdf&quot;&gt;https:&#x2F;&#x2F;cr.yp.to&#x2F;lineartime&#x2F;multapps-20080515.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;504.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;504.pdf&lt;&#x2F;a&gt; page 5 describes how to turn convolution theorem into negacyclic.&lt;&#x2F;p&gt;
&lt;p&gt;Fast modular composition. p. 338 in Modern Computer Algebra.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;relate.cs.illinois.edu&#x2F;course&#x2F;cs598evs-f20&#x2F;
https:&#x2F;&#x2F;relate.cs.illinois.edu&#x2F;course&#x2F;cs598evs-f20&#x2F;f&#x2F;lectures&#x2F;03-lecture.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1707.04618&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.nature.com&#x2F;articles&#x2F;s41586-022-05172-4&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;doc.sagemath.org&#x2F;html&#x2F;en&#x2F;reference&#x2F;polynomial_rings&#x2F;sage&#x2F;rings&#x2F;polynomial&#x2F;convolution.html
https:&#x2F;&#x2F;jucaleb4.github.io&#x2F;files&#x2F;conv_ba.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;jucaleb4.github.io&#x2F;files&#x2F;poster1.pdf&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Users and Secrets</title>
        <published>2023-07-12T00:00:00+00:00</published>
        <updated>2023-07-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/users-secrets/"/>
        <id>https://2π.com/23/users-secrets/</id>
        
        <content type="html" xml:base="https://2π.com/23/users-secrets/">&lt;h1 id=&quot;users-and-secrets&quot;&gt;Users and Secrets&lt;&#x2F;h1&gt;
&lt;p&gt;Cryptography often relies on the user keeping a secret, for example private keys.
A private key works as long as the user is the one and the only one that knows it. This immediately leads to the two failure modes of the user losing the key and someone else obtaining it. This is static state, there is also the dynamic element of creating this state and terminating this state.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m assuming ideal cryptography. The algorithms provide unbreakable guarantees and entropy generation and disposal is done perfectly. This is not entirely realistic, but this area has seen so much more research than what we will be discussing that it is not worth going into here. I&#x27;ll just say that an implementation following industry best practices can be expected to live up to these ideals under normal circumstances.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;secret-keys&quot;&gt;Secret keys&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;private-keys&quot;&gt;Private keys&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;ol&gt;
&lt;li&gt;Loss of secret. No-one knows the secret.
&lt;ol&gt;
&lt;li&gt;Involuntary: Hardware failure, forgot password, accidental deletion, remote destroy (as part of theft), wiping phone (recovering from backup).&lt;&#x2F;li&gt;
&lt;li&gt;Voluntary: Deliberate deletion.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Leak of secret. Someone else also knows the secret.
&lt;ol&gt;
&lt;li&gt;Involuntary: Malware on device, backdoors, social engineering. Side channel attacks.
&lt;ol&gt;
&lt;li&gt;Physical attacks
&lt;ol&gt;
&lt;li&gt;Shoulder surfing.&lt;&#x2F;li&gt;
&lt;li&gt;Cold boot attacks.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Break of cryptography. (i.e. solving discrete logarithm problem)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Voluntary:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Access breach. Someone else can do things with the secret, short of knowing it.
&lt;ol&gt;
&lt;li&gt;Involuntary: Malware, social engineering, back doors.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Transfer of private key. Someone else
&lt;ol&gt;
&lt;li&gt;Involuntary: Theft of unlocked phone. Device theft with breach of encryption.&lt;&#x2F;li&gt;
&lt;li&gt;Voluntary: Transfer of (unlockable) device. Transfer of accounts. Transfer of secret.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Loss of user. The user should no longer know the secret.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The trend here seems to be Smart Contract Wallets which avoids secrets and instead allows users to set up their own authentication process (which will likely involve secrets again).&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Secure Conditions:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Private key secrecy&lt;&#x2F;strong&gt;: The user must not share their private key with anyone. The private key must be kept secret at all times.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Secure storage&lt;&#x2F;strong&gt;: The private key should be stored in a secure way, which could involve strong encryption, secure physical storage (for physical keys or hardware tokens), or secure cryptographic hardware (like a hardware security module).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Secure usage&lt;&#x2F;strong&gt;: When the private key is used to sign or decrypt data, this should also be done in a secure environment to prevent leaks.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Failure Modes:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If the secure conditions are not met, several things can go wrong:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Key exposure&lt;&#x2F;strong&gt;: If the private key is leaked or discovered, all security guarantees are lost. An attacker with the private key can read encrypted data, tamper with signed data, and impersonate the key owner.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Poor key generation&lt;&#x2F;strong&gt;: If the key isn&#x27;t generated securely (e.g., it&#x27;s too short, not random enough, or based on a predictable process), an attacker might be able to guess or calculate the private key.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Insecure storage or use&lt;&#x2F;strong&gt;: If the private key is stored or used insecurely (e.g., it&#x27;s stored unencrypted on a hard drive, or it&#x27;s used in a way that leaks information), an attacker might be able to steal or deduce the private key.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>BN254 Point Compression for L2s</title>
        <published>2023-07-05T00:00:00+00:00</published>
        <updated>2023-07-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/bn254-compression/"/>
        <id>https://2π.com/23/bn254-compression/</id>
        
        <content type="html" xml:base="https://2π.com/23/bn254-compression/">&lt;h1 id=&quot;bn254-point-compression-for-l2s&quot;&gt;BN254 Point Compression for L2s&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\floor#1{\delim\lfloor{#1}\rfloor}
\gdef\mod#1{\delim[{#1}]}
\gdef\Z{\mathbb{Z}}
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\i{\mathrm{i}}
\gdef\op#1{\small \mathsf{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A Groth16 proof has two &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; points and one &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt;. In the BN254 pairing curve these take 64 and 128 bytes respectively uncrompressed totaling 256 bytes for a proof. With compression points will take only 32 and 64 bytes respectively, halving the size of a proof.&lt;&#x2F;p&gt;
&lt;p&gt;On Ethereum calldata costs &lt;span class=&quot;math math-inline&quot;&gt;16&lt;&#x2F;span&gt; gas per byte, so any compression would need to perform better than that. This gives a budget of 512 and 1024 gas for &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; point compression respectively. This will be hard to achieve. On Optimism the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;community.optimism.io&#x2F;docs&#x2F;developers&#x2F;build&#x2F;transaction-fees&#x2F;#the-l2-execution-fee&quot;&gt;cost of calldata&lt;&#x2F;a&gt; is higher by a factor&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\mathtt{l1\_gas\_price}}{\mathtt{l2\_gas\_price}}⋅\mathtt{dynamic\_overhead}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where the &lt;code&gt;dynamic_overhead&lt;&#x2F;code&gt; is set to &lt;code&gt;0.684&lt;&#x2F;code&gt; and the gas price ratio &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dune.com&#x2F;remco&#x2F;optimism-l1-l2-gas-cost-ratio&quot;&gt;fluctuates wildly&lt;&#x2F;a&gt; with the last half year ranging between &lt;span class=&quot;math math-inline&quot;&gt;50&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;20\,000&lt;&#x2F;span&gt;. Taking the lower bound this puts the compression budget at 550 gas per byte, or 17k gas per &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; point and double for &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt;. This seems doable, let&#x27;s do it!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-field&quot;&gt;The field &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The base field &lt;span class=&quot;math math-inline&quot;&gt;\F_1 = \Z&#x2F;p\Z&lt;&#x2F;span&gt; are the numbers modulo &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
p &amp;amp;= 36⋅t^4 + 36⋅t^3 + 24⋅t^2 + 6⋅t + 1 &amp;amp;\hspace{2em}
t &amp;amp;= 4965661367192848881
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;!--
0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
t = 4965661367192848881
t = 0x44e992b44a6909f1
--&gt;
&lt;p&gt;Addition and multiplications are trivially implemented using EVMs &lt;code&gt;addmod&lt;&#x2F;code&gt; and &lt;code&gt;mulmod&lt;&#x2F;code&gt; operations at 8 gas each. &lt;span class=&quot;math math-inline&quot;&gt;\floor{\frac{2^{256}-1}{p-1}} = 5&lt;&#x2F;span&gt; so we can add up to five elements using &lt;code&gt;add&lt;&#x2F;code&gt; without overflowing. Negation can be done using &lt;span class=&quot;math math-inline&quot;&gt;p-n&lt;&#x2F;span&gt; but the result will be unreduced in range &lt;span class=&quot;math math-inline&quot;&gt;[1,p]&lt;&#x2F;span&gt;. &lt;span class=&quot;math math-inline&quot;&gt;\floor{\frac{2^{256}-1}{p}} = 5&lt;&#x2F;span&gt; so we can also add up to five unreduced negations without overflowing.&lt;&#x2F;p&gt;
&lt;p&gt;Exponentiation can be done using repeated multiplication. Efficient strategies for specific exponents can be found using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mmcloughlin&#x2F;addchain&#x2F;tree&#x2F;e40ce6aef373db2e2eb814c3345606ba221b6fb7&quot;&gt;addchain&lt;&#x2F;a&gt; so the exact cost depends on the exponent. Exponentiation can also be done using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-198&quot;&gt;&lt;code&gt;modexp&lt;&#x2F;code&gt; precompile&lt;&#x2F;a&gt; which for &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2565&quot;&gt;costs&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;200&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;1349&lt;&#x2F;span&gt; gas, depending on the exponent.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inversion-in&quot;&gt;Inversion in &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;By Fermat&#x27;s little theorem, in &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;a = a^p&lt;&#x2F;span&gt;. Dividing both sides by &lt;span class=&quot;math math-inline&quot;&gt;a^2&lt;&#x2F;span&gt; we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a^{-1} = a^{p-2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Computing this takes &lt;span class=&quot;math math-inline&quot;&gt;247⋅\op{Square}_{\F_1} + 56⋅\op{Mul}_{\F_1}&lt;&#x2F;span&gt; using an addition chain generated with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mmcloughlin&#x2F;addchain&#x2F;tree&#x2F;e40ce6aef373db2e2eb814c3345606ba221b6fb7&quot;&gt;addchain&lt;&#x2F;a&gt;. Implemented using &lt;code&gt;mulmod&lt;&#x2F;code&gt; this would take at least &lt;span class=&quot;math math-inline&quot;&gt;2\,424&lt;&#x2F;span&gt; gas. The &lt;code&gt;modexp&lt;&#x2F;code&gt; precompile costs &lt;span class=&quot;math math-inline&quot;&gt;1349&lt;&#x2F;span&gt; gas.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Inversion using half-extended GCD?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;square-roots-in&quot;&gt;Square roots in &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;a = a^p&lt;&#x2F;span&gt; taking the square root of both sides we would get &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{a} = a^{\frac{p}{2}}&lt;&#x2F;span&gt; but &lt;span class=&quot;math math-inline&quot;&gt;\frac{p}{2}&lt;&#x2F;span&gt; is not an integer so this does not lead to a usable method. Instead &lt;span class=&quot;math math-inline&quot;&gt;\frac{p-1}{2}&lt;&#x2F;span&gt; is an integer. By Fermat&#x27;s little theorem in &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;a^p=a&lt;&#x2F;span&gt;. Dividing both sides by &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; we get &lt;span class=&quot;math math-inline&quot;&gt;a^{p-1}=1&lt;&#x2F;span&gt; and taking the square root on both sides we get &lt;span class=&quot;math math-inline&quot;&gt;a^{\frac{p-1}{2}} = \pm 1&lt;&#x2F;span&gt;. We also have &lt;span class=&quot;math math-inline&quot;&gt;\mod{p}_4 = 3&lt;&#x2F;span&gt; so &lt;span class=&quot;math math-inline&quot;&gt;\frac{p+1}{4}&lt;&#x2F;span&gt; is an integer. Observe&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\pm a^{\frac{p+1}{4}}}^2 = a^{\frac{p+1}{2}} = a^{\frac{p-1}{2}}⋅a = \pm a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So if &lt;span class=&quot;math math-inline&quot;&gt;a^{\frac{p+1}{2}} = 1&lt;&#x2F;span&gt; we have then &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{a} = \pm a^{\frac{p+1}{4}}&lt;&#x2F;span&gt;. It can be shown that if &lt;span class=&quot;math math-inline&quot;&gt;a^{\frac{p+1}{2}} = -1&lt;&#x2F;span&gt; the square root does not exist, so this method covers all square roots. In fact, only half of the elements in &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt; have a square root, and if it exists for &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; it is absent for &lt;span class=&quot;math math-inline&quot;&gt;-a&lt;&#x2F;span&gt; and vice versa.&lt;&#x2F;p&gt;
&lt;p&gt;The exponential &lt;span class=&quot;math math-inline&quot;&gt;\frac{p+1}{4}&lt;&#x2F;span&gt; takes &lt;span class=&quot;math math-inline&quot;&gt;246⋅\op{Square}_{\F_1} + 54⋅\op{Mul}_{\F_1}&lt;&#x2F;span&gt; using an addition chain generated with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mmcloughlin&#x2F;addchain&#x2F;tree&#x2F;e40ce6aef373db2e2eb814c3345606ba221b6fb7&quot;&gt;addchain&lt;&#x2F;a&gt;, which takes at least &lt;span class=&quot;math math-inline&quot;&gt;2\,400&lt;&#x2F;span&gt; gas using &lt;code&gt;mulmod&lt;&#x2F;code&gt;. Using &lt;code&gt;modexp&lt;&#x2F;code&gt; the exponent takes &lt;span class=&quot;math math-inline&quot;&gt;1338&lt;&#x2F;span&gt; gas.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-field-1&quot;&gt;The field &lt;span class=&quot;math math-inline&quot;&gt;\F_2&lt;&#x2F;span&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Construct the extension field &lt;span class=&quot;math math-inline&quot;&gt;\F_2 = \F_1[\i]&#x2F;(\i^2+1)&lt;&#x2F;span&gt;. That is, each element is written &lt;span class=&quot;math math-inline&quot;&gt;x_0 + x_1 ⋅ \i&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\i^2 = -1&lt;&#x2F;span&gt;, much like the complex numbers. In fact, we get all of our complex arithmetic identities:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\p{a + b⋅\i} + \p{c + d⋅\i} &amp;amp;= \p{a + c} + \p{b + d}⋅\i \\
\p{a + b⋅\i} - \p{c + d⋅\i} &amp;amp;= \p{a - c} + \p{b - d}⋅\i \\
\p{a + b⋅\i} ⋅ \p{c + d⋅\i} &amp;amp;= \p{a⋅c - b⋅d} + \p{a⋅d+b⋅c}⋅\i \\
\p{a + b⋅\i}^2 &amp;amp;= \p{a^2 - b^2} + \p{2⋅a⋅b}⋅\i \\
\p{a + b⋅\i}^{-1} &amp;amp;= \p{\frac{a}{a^2 + b^2}} + \p{\frac{b}{a^2 + b^2}}⋅\i \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Multiplication as above requires &lt;span class=&quot;math math-inline&quot;&gt;2⋅\op{Add}_{\F_1} + 4⋅\op{Mul}_{\F_1}&lt;&#x2F;span&gt;. It can be done with fewer multiplications using Karatsuba&#x27;s method. Take &lt;span class=&quot;math math-inline&quot;&gt;u = a⋅c&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;v = b⋅d&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;s=\p{a+b}⋅\p{c+d}&lt;&#x2F;span&gt;, then the result is &lt;span class=&quot;math math-inline&quot;&gt;\p{u-v}+\p{s-u-v}⋅\i&lt;&#x2F;span&gt;. This requires &lt;span class=&quot;math math-inline&quot;&gt;5⋅\op{Add}_{\F_1} + 3⋅\op{Mul}_{\F_1}&lt;&#x2F;span&gt;. Since &lt;code&gt;addmod&lt;&#x2F;code&gt; and &lt;code&gt;mulmod&lt;&#x2F;code&gt; cost the same in EVM, this is not a worthwhile trade-off. (&lt;strong&gt;To do.&lt;&#x2F;strong&gt; We can change some to cheaper &lt;code&gt;add&lt;&#x2F;code&gt;s)&lt;&#x2F;p&gt;
&lt;p&gt;Squaring as above requires &lt;span class=&quot;math math-inline&quot;&gt;\op{Add}_{\F_1} + 2⋅\op{Square}_{\F_1} + \op{Mul}_{\F_1} + \op{Double}_{\F_1}&lt;&#x2F;span&gt;. Factoring &lt;span class=&quot;math math-inline&quot;&gt;a^2 + b^2&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;\p{a+b}⋅\p{a-b}&lt;&#x2F;span&gt; we can exchange one  &lt;span class=&quot;math math-inline&quot;&gt;\op{Square}_{\F_1}&lt;&#x2F;span&gt; for an &lt;span class=&quot;math math-inline&quot;&gt;\op{Add}_{\F_1}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;square-roots-in-1&quot;&gt;Square roots in &lt;span class=&quot;math math-inline&quot;&gt;\F_2&lt;&#x2F;span&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Square root is the hard part. We can again take inspiration from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Consensys&#x2F;gnark-crypto&#x2F;blob&#x2F;441dc0ffe639294b8d09e394f24ba7575577229c&#x2F;ecc&#x2F;bn254&#x2F;internal&#x2F;fptower&#x2F;e2.go#L216-L244&quot;&gt;Gnark&lt;&#x2F;a&gt; and see that it uses algorithm 9 from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2012&#x2F;685&quot;&gt;ARH12&lt;&#x2F;a&gt;. This amounts to computing&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
α   &amp;amp;= a^{\frac{q-1}{2}} &amp;amp;\hspace{2em}
\sqrt{a} &amp;amp;= \pm a^{\frac{q+1}{4}} ⋅ \begin{cases}
\i &amp;amp; α = -1 \\
\p{1 + α}^{\frac{q-1}{2}} &amp;amp; α ≠ -1 \\
\end{cases}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a lot of exponentiation in &lt;span class=&quot;math math-inline&quot;&gt;\F_2&lt;&#x2F;span&gt;, for which we cannot use the affordable precompile. So instead we consider a more traditional approach, algorithm 8 from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2012&#x2F;685&quot;&gt;ARH12&lt;&#x2F;a&gt;. Give &lt;span class=&quot;math math-inline&quot;&gt;x+y⋅\i&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;x,y∈\F_1&lt;&#x2F;span&gt; we are looking for &lt;span class=&quot;math math-inline&quot;&gt;a,b∈\F_1&lt;&#x2F;span&gt; such that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x + y⋅\i &amp;amp;= \p{a + b⋅\i}^2 \\
&amp;amp;= \p{a^2 - b^2} + \p{2⋅a⋅b}⋅\i \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which gives the system of quadratic equations&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x &amp;amp;= a^2 - b^2 \\
y &amp;amp;= 2⋅a⋅b \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The solution to this is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a &amp;amp;= \pm \sqrt{\frac{x\pm \sqrt{x^2 + y^2}}{2}} \\
b &amp;amp;= \frac{y}{2⋅a} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Show me&lt;&#x2F;summary&gt;
&lt;p&gt;we take &lt;span class=&quot;math math-inline&quot;&gt;b = \frac{y}{2⋅a}&lt;&#x2F;span&gt; and substitute this back in the first equation and apply the quadratic formula&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x &amp;amp;= a^2 - \p{\frac{y}{2⋅a}}^2 \\
x &amp;amp;= a^2 - \frac{y^2}{4⋅a^2} \\
4⋅a^2⋅x &amp;amp;= 4⋅a^4 - y^2 \\
0 &amp;amp;= \p{-y^2} - 4⋅x ⋅\p{a^2}+ 4⋅\p{a^2}^2  \\
a^2 &amp;amp;= \frac{-\p{- 4⋅x}\pm \sqrt{\p{- 4⋅x}^2-4⋅\p{4}⋅\p{-y^2}}}{8} \\
a^2 &amp;amp;= \frac{4⋅x \pm \sqrt{16⋅x^2+16⋅y^2}}{8} \\
a^2 &amp;amp;= \frac{x\pm \sqrt{x^2 + y^2}}{2} \\
a &amp;amp;= \pm \sqrt{\frac{x\pm \sqrt{x^2 + y^2}}{4}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;p&gt;The inner &lt;span class=&quot;math math-inline&quot;&gt;\pm&lt;&#x2F;span&gt; needs to have a specific value, only one will result in a square for the outer square root. There does not seem to be an efficient method of computing this sign other than trying both values. Since trying is expensive (involves a &lt;code&gt;modexp&lt;&#x2F;code&gt;) it is better to provide it as a hint. The outer &lt;span class=&quot;math math-inline&quot;&gt;\pm&lt;&#x2F;span&gt; reflects the two possible solutions of the quadratic equation.&lt;&#x2F;p&gt;
&lt;p&gt;Computing the square root requires two &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt; square roots and one &lt;span class=&quot;math math-inline&quot;&gt;\F_1&lt;&#x2F;span&gt; inversion, which can be done using three calls to &lt;code&gt;modexp&lt;&#x2F;code&gt; costing &lt;span class=&quot;math math-inline&quot;&gt;4\,025&lt;&#x2F;span&gt; gas total.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compressing-points&quot;&gt;Compressing &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; points&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; elliptic curve are the &lt;span class=&quot;math math-inline&quot;&gt;(x, y)∈\F_1^2&lt;&#x2F;span&gt; satisfying a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hyperelliptic.org&#x2F;EFD&#x2F;g1p&#x2F;auto-shortw.html&quot;&gt;short Weierstrass equation&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
y^2 = x^3 + 3
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One such solution is &lt;span class=&quot;math math-inline&quot;&gt;(1, 2)&lt;&#x2F;span&gt;, which is the chosen generator for this group.&lt;&#x2F;p&gt;
&lt;p&gt;Give an &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; coordinate we can recover the &lt;span class=&quot;math math-inline&quot;&gt;y&lt;&#x2F;span&gt; coordinate by taking the square root of &lt;span class=&quot;math math-inline&quot;&gt;x^3+3&lt;&#x2F;span&gt;. This has either two solutions &lt;span class=&quot;math math-inline&quot;&gt;y, -y&lt;&#x2F;span&gt; or none. This means that we can distinguish the point as (when fully reduced) exactly one will be &lt;span class=&quot;math math-inline&quot;&gt;&amp;gt;\frac{p}{2}&lt;&#x2F;span&gt; and exactly one will be an odd number.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compressing-points-1&quot;&gt;Compressing &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; points&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; elliptic curve are the &lt;span class=&quot;math math-inline&quot;&gt;(x, y)∈\F_2^2&lt;&#x2F;span&gt; satisfying a short Weierstrass equation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
y^2 = x^3 + \frac{3}{9+\i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\frac{3}{9+\i} = \frac{27}{82} - \frac{3}{82} ⋅ \i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Given an &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; coordinate we can recover &lt;span class=&quot;math math-inline&quot;&gt;y&lt;&#x2F;span&gt; the same as before, but now with math happening in &lt;span class=&quot;math math-inline&quot;&gt;\F_2&lt;&#x2F;span&gt;. Given &lt;span class=&quot;math math-inline&quot;&gt;x = a + b ⋅ \i&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x^3 &amp;amp;= \p{a + b ⋅ \i}^3 \\
&amp;amp;= \p{a^3 - 3 ⋅a ⋅b^2} + \p{3 ⋅a^2 ⋅b  - b^3}⋅\i \\
&amp;amp;= a^3 + 3 ⋅ a^2 ⋅ b⋅\i + 3⋅ a ⋅ b^2 ⋅\i^2 + b^3 ⋅\i^3 \\
&amp;amp;= \p{a^3 - 3⋅ a ⋅ b^2} + \p{3 ⋅ a^2 ⋅ b - b^3}⋅\i \\
x^3 + \frac{3}{9+\i} &amp;amp;= \p{\frac{27}{82}+a^3 - 3⋅ a ⋅ b^2} - \p{\frac{3}{82} + b^3 - 3 ⋅ a^2 ⋅ b}⋅\i \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;y&lt;&#x2F;span&gt; coordinate is a square root of this value. As before, &lt;span class=&quot;math math-inline&quot;&gt;-y&lt;&#x2F;span&gt; is also a solution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compressing-two-points&quot;&gt;Compressing two points&lt;&#x2F;h2&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nur.nu.edu.kz&#x2F;bitstream&#x2F;handle&#x2F;123456789&#x2F;1633&#x2F;Adilet%20Otemissov_capstone_report.pdf&quot;&gt;Ote15&lt;&#x2F;a&gt; an efficient method for storing two points on the same curve &lt;span class=&quot;math math-inline&quot;&gt;y^2=x^3 + a⋅x + b&lt;&#x2F;span&gt; is presented. (As mentioned by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;Zac_Aztec&#x2F;status&#x2F;1678142850725298177?s=20&quot;&gt;Zac Williamson&lt;&#x2F;a&gt;). Given two points &lt;span class=&quot;math math-inline&quot;&gt;(x_1, y_1), (x_2, y_2)&lt;&#x2F;span&gt; on a curve compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A &amp;amp;= \frac{x_1 - x_2}{y_1 - y_2} &amp;amp;\hspace{2em}
B &amp;amp;= y_1 - y_2 &amp;amp;\hspace{2em}
C &amp;amp;= x_2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;we can recover the two points by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_1 &amp;amp;= A⋅B + C &amp;amp;\hspace{1em}
x_2 &amp;amp;= C &amp;amp;\hspace{1em}
y_1 &amp;amp;= \frac{A⋅\p{\p{x_1 + x_2}^2 - x_1⋅x_2 + a} + B}{2} &amp;amp;\hspace{1em}
y_2 &amp;amp;= y_1 - B
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For the special case &lt;span class=&quot;math math-inline&quot;&gt;y_1 = y_2&lt;&#x2F;span&gt; we can instead store &lt;span class=&quot;math math-inline&quot;&gt;(x_1, x_2, y_1)&lt;&#x2F;span&gt;. An extra bit is required to distinguish these cases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation-and-benchmark&quot;&gt;Implementation and benchmark&lt;&#x2F;h2&gt;
&lt;p&gt;An implementation of the above &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; compression is done in Solidity in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;evm-groth16&#x2F;blob&#x2F;main&#x2F;src&#x2F;Verifier.sol&quot;&gt;Verifier.sol&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Decompressing &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; points takes &lt;span class=&quot;math math-inline&quot;&gt;2\,390&lt;&#x2F;span&gt; gas so becomes worthwhile at &lt;span class=&quot;math math-inline&quot;&gt;75&lt;&#x2F;span&gt; gas&#x2F;byte.&lt;&#x2F;li&gt;
&lt;li&gt;Decompressing &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; points takes &lt;span class=&quot;math math-inline&quot;&gt;7\,605&lt;&#x2F;span&gt; gas so becomes worthwhile at &lt;span class=&quot;math math-inline&quot;&gt;118&lt;&#x2F;span&gt; gas&#x2F;byte.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These numbers are close enough that we can consider doing both &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; compression. For a Groth16 verification this adds &lt;span class=&quot;math math-inline&quot;&gt;11\,366&lt;&#x2F;span&gt; gas overhead, so becomes worthwhile at &lt;span class=&quot;math math-inline&quot;&gt;89&lt;&#x2F;span&gt; gas&#x2F;byte. This is not economical on Ethereum, but it is on Optimism.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;safety&quot;&gt;Safety&lt;&#x2F;h2&gt;
&lt;p&gt;This compression method takes in existing proofs, so zero-knowledge is unaffected. After decompression it calls the original verifier, so soundness is unaffected. This leaves completeness, which is only preserved if the method works for all valid proofs. This can be accomplished by making sure the method works on all points in &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt;, taking care to handle zero values and the point at infinity correctly. (Although it is at best extremely unlikely a valid proof will contain those.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-abusing-ecadd&quot;&gt;Appendix: Abusing ECADD?&lt;&#x2F;h2&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;a,b,c,d ∈ \F_1&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;(a, b),(c,d) ∈ \G_1&lt;&#x2F;span&gt; the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-196&quot;&gt;&lt;code&gt;ecadd&lt;&#x2F;code&gt; precompile&lt;&#x2F;a&gt; returns for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1108&quot;&gt;150 gas&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x &amp;amp;= \p{\frac{d-b}{c-a}}^2-a-c \\
y &amp;amp;= \p{2⋅a + c}⋅\p{\frac{d-b}{c-a}}- \p{\frac{d-b}{c-a}}^3 - b \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;if &lt;span class=&quot;math math-inline&quot;&gt;(a, b)≠(c,d)&lt;&#x2F;span&gt;, or else&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x &amp;amp;= \p{\frac{3⋅a^2}{2⋅b}}^2-2⋅a \\
y &amp;amp;= \p{3⋅a}⋅\p{\frac{3⋅a^2}{2⋅b}}-\p{\frac{3⋅a^2}{2⋅b}}^3-b \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This contains an inversion for much cheaper than we can do, but it seems hard to extract this.
The first case could maybe be abused to compute &lt;span class=&quot;math math-inline&quot;&gt;\frac{1}{a^2}&lt;&#x2F;span&gt;, but turning this in to a problem with valid &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; points is going to be challenging.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2005&#x2F;133&quot;&gt;BN05&lt;&#x2F;a&gt; Baretto, Naehrig (2005). Pairing-Friendly Elliptic Curves of Prime Order.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2010&#x2F;134&quot;&gt;Shi10&lt;&#x2F;a&gt; Shirase (2010). Barreto-Naehrig Curve With Fixed Coefficient.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2010&#x2F;354&quot;&gt;BDMO10&lt;&#x2F;a&gt; Beuchat et al. (2010). High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2012&#x2F;685&quot;&gt;ARH12&lt;&#x2F;a&gt; Adj, Ridrígues-Henríquez (2012). Square root computation over even extension fields.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;ttps:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;348&quot;&gt;DLZZ22&lt;&#x2F;a&gt; Dai, Lin, Zhao, Zhou (2022). Fast Subgroup Membership Testings for &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_T&lt;&#x2F;span&gt; on Pairing-friendly Curves.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2206.07145&quot;&gt;AGO22&lt;&#x2F;a&gt; Adiguzel-Goktas, Ozdemir (2022). Square Root Computation In Finite Fields.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;@jpw&#x2F;bn254&quot;&gt;Wan22&lt;&#x2F;a&gt; Wang (2022). BN254 For The Rest Of Us.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-196&quot;&gt;EIP-196&lt;&#x2F;a&gt;: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-197&quot;&gt;EIP-197&lt;&#x2F;a&gt;: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-198&quot;&gt;EIP-198&lt;&#x2F;a&gt;: Big integer modular exponentiation.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1108&quot;&gt;EIP-1108&lt;&#x2F;a&gt;: Reduce alt_bn128 precompile gas costs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2565&quot;&gt;EIP-2565&lt;&#x2F;a&gt;: ModExp Gas Cost.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;EspressoSystems&#x2F;solidity-bn254&#x2F;blob&#x2F;1be188e4e21c483cf996cf8fd7b1b8227eda46f2&#x2F;src&#x2F;BN254.sol&quot;&gt;BN254.sol&lt;&#x2F;a&gt; by Espresso Systems.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;witnet&#x2F;elliptic-curve-solidity&#x2F;blob&#x2F;347547890840fd501809dfe0b855206407136ec0&#x2F;contracts&#x2F;EllipticCurve.sol#L120&quot;&gt;EllipticCurve.sol&lt;&#x2F;a&gt; by The Witnet Project.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;musalbas&#x2F;solidity-BN256G2&#x2F;blob&#x2F;45a07eecabf7402d12897a975135caba7a4254f2&#x2F;BN256G2.sol&quot;&gt;BN256G2.sol&lt;&#x2F;a&gt; by Mustafa Al-Bassam.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;asanso&#x2F;bls_solidity_python&#x2F;blob&#x2F;master&#x2F;contracts&#x2F;BLS.sol&quot;&gt;BLS.sol&lt;&#x2F;a&gt;  by Antonio Sanso. See also the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;fast-mathbb-g-2-subgroup-check-in-bn254&#x2F;13974&quot;&gt;Ethresearch post&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;010.pdf&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Groth16 Batch Verification</title>
        <published>2023-07-05T00:00:00+00:00</published>
        <updated>2023-07-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/groth16-batch/"/>
        <id>https://2π.com/23/groth16-batch/</id>
        
        <content type="html" xml:base="https://2π.com/23/groth16-batch/">&lt;h1 id=&quot;groth16-batch-verification&quot;&gt;Groth16 Batch Verification&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\e{\operatorname{e}}
\gdef\Z{\mathrm{Z}}
\gdef\U{\mathrm{U}}
\gdef\V{\mathrm{V}}
\gdef\W{\mathrm{W}}
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\ga#1{\delim[{#1}]_1}
\gdef\gb#1{\delim[{#1}]_2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;constraints&quot;&gt;Constraints&lt;&#x2F;h3&gt;
&lt;p&gt;Recall &lt;a href=&quot;&#x2F;22&#x2F;groth16&quot;&gt;Groth16&lt;&#x2F;a&gt;. For a given circuit with &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; variables, &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; constraints and &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; public inputs we encode the circuit as &lt;span class=&quot;math math-inline&quot;&gt;3⋅n+1&lt;&#x2F;span&gt; polynomials &lt;span class=&quot;math math-inline&quot;&gt;\U_i, \V_i, \W_i, \Z ∈ \F[X]&lt;&#x2F;span&gt; each with &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; terms (i.e. degree &lt;span class=&quot;math math-inline&quot;&gt;m-1&lt;&#x2F;span&gt;). A witness &lt;span class=&quot;math math-inline&quot;&gt;x ∈\F^n&lt;&#x2F;span&gt; is correct if for some &lt;span class=&quot;math math-inline&quot;&gt;H(X) ∈ \F[X]&lt;&#x2F;span&gt; it satisfies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\sum_{i∈[0,n)} x_i ⋅ \U_i(X)} ⋅ \p{\sum_{i∈[0,n)} x_i ⋅ \V_i(X)} =
\p{\sum_{i∈[0,n)} x_i ⋅ \W_i(X)} + H(X) ⋅\Z(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For a given circuit and setup we have &lt;span class=&quot;math math-inline&quot;&gt;\ga{α}, \gb{β}, L_i, \gb{γ}, \ga{δ}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Consider a proof &lt;span class=&quot;math math-inline&quot;&gt;(x_i, A, B, C)&lt;&#x2F;span&gt;. To verify it we check&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0 = \e\p{A, B} - \e\p{\ga{α}, \gb{β}} - \e\p{\sum_{i∈[0,p)}x_i⋅L_i, \gb{γ}} - \e\p{C, \gb{δ}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;linear-combinations&quot;&gt;Linear combinations&lt;&#x2F;h2&gt;
&lt;p&gt;Consider many proofs &lt;span class=&quot;math math-inline&quot;&gt;(x_{ij}, A_j, B_j, C_j)&lt;&#x2F;span&gt;. Take a random linear product of verifications with &lt;span class=&quot;math math-inline&quot;&gt;r_j ∈ \F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
0 &amp;amp;= \sum_j r_j⋅ \p{\e\p{A_j, B_j} -\e\p{\ga{α}, \gb{β}} - \e\p{\sum_{i∈[0,p)}x_{ij}⋅L_i, \gb{γ}} - \e\p{C_j, \gb{δ}} }\\
&amp;amp;= \sum_j r_j⋅ \e\p{A_j, B_j} - \e\p{\sum_j r_j⋅\ga{α}, \gb{β}}- \e\p{\sum_{i∈[0,p)}\p{\sum_j x_{ij}⋅r_j}⋅L_i, \gb{γ}} - \e\p{\sum_j r_j⋅C_j, \gb{δ}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The problem is &lt;span class=&quot;math math-inline&quot;&gt;\sum_j r_j⋅ \e\p{A_j, B_j}&lt;&#x2F;span&gt; is not computable in &lt;span class=&quot;math math-inline&quot;&gt;\G_1, \G_2&lt;&#x2F;span&gt; but requires operations in &lt;span class=&quot;math math-inline&quot;&gt;\G_3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If we simply forced the sum inside we&#x27;d get many cross terms:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e\p{\sum_j r_j⋅ A_j, \sum_j r_j⋅ B_j} &amp;amp;= \sum_i \sum_j  r_i⋅ r_j⋅ \e\p{A_i, B_j}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;529.pdf&quot;&gt;Snarkpack&lt;&#x2F;a&gt; solves this using a target inner pairing product (TIPP) protocol to provide the verifier with &lt;span class=&quot;math math-inline&quot;&gt;\sum_j r_j⋅ \e\p{A_j, B_j}&lt;&#x2F;span&gt; and proof that it was constructed correctly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;attempt-at-alternative&quot;&gt;Attempt at alternative&lt;&#x2F;h2&gt;
&lt;p&gt;What if instead we embrace the cross terms and try to make it work?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e\p{\sum_j r^j⋅ A_j, \sum_j s_j⋅ B_j} &amp;amp;= \sum_i \sum_j  r^i⋅ s_j⋅ \e\p{A_i, B_j}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;poor-man-s-snarkpack&quot;&gt;Poor man&#x27;s snarkpack&lt;&#x2F;h2&gt;
&lt;p&gt;We can also simply not aggregate the &lt;span class=&quot;math math-inline&quot;&gt;\e{A,B}&lt;&#x2F;span&gt; pair:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\sum_j \e\p{r^j⋅ A_j, B_j} &amp;amp;= \e\p{\sum_j r^j⋅\ga{α}, \gb{β}} + \e\p{\sum_{i∈[0,p)}\p{\sum_j x_{ij}⋅r^j}⋅L_i, \gb{γ}} + \e\p{\sum_j r^j⋅C_j, \gb{δ}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This should trivially work and save 75% of the pairings, at the cost of &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; operations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;poor-man-s-turbo&quot;&gt;Poor man&#x27;s turbo&lt;&#x2F;h2&gt;
&lt;p&gt;The aggregator computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
C &amp;amp;= \sum_j r^j ⋅ C_j \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The verifier checks&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\sum_j \e\p{r^j⋅ A_j, B_j} &amp;amp;= \e\p{\p{\sum_j r^j}⋅\ga{α}, \gb{β}} + \e\p{\sum_{i∈[0,p)}\p{\sum_j x_{ij}⋅r^j}⋅L_i, \gb{γ}} + \e\p{C, \gb{δ}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This requires &lt;span class=&quot;math math-inline&quot;&gt;2⋅(n-1)&lt;&#x2F;span&gt; times &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Add}_{\F}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;p⋅n&lt;&#x2F;span&gt; times &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Mul}_{\F}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;n+p+1&lt;&#x2F;span&gt; times &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Mul}_{\G_1}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;n+3&lt;&#x2F;span&gt; times &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Pair}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This construction preserves completeness and zero-knowledge, but does it preserve soundness?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; If this works it could also be applied to SnarkPack.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attempted-soundness-proof&quot;&gt;Attempted Soundness Proof&lt;&#x2F;h3&gt;
&lt;p&gt;As before, but now with additional formal parameters &lt;span class=&quot;math math-inline&quot;&gt;r_j&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\sum_j r^j⋅ A_j⋅ B_j &amp;amp;= \sum_j r^j⋅α⋅β + \sum_j r^j ⋅\sum_{i∈[0,p)} x_{ij}⋅\p{β⋅\U_i​(τ)+α⋅\V_i​(τ)+\W_i​(τ)} +C⋅δ
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where we have multiple &lt;span class=&quot;math math-inline&quot;&gt;A, B&lt;&#x2F;span&gt; values&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_j &amp;amp;= A_{τj}(τ) + A_{αj}(τ)⋅α + A_{βj}(τ)⋅β + A_{δj} ⋅ δ +  A_{γj} ⋅ γ + A_{Zj}(τ)⋅{\footnotesize \frac{\Z(τ)}{δ}} \\[0.5em]
&amp;amp;\phantom{=}+ \sum_{i∈[0,p)} A_{ij}⋅{\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ}} +  \sum_{i∈[p,m)} A_{ij}⋅ {\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{δ} } \\[2em]
B_j &amp;amp;= B_{τj}(τ) + B_{βj}⋅β + B_{δj} ⋅ δ + B_{γj} ⋅ γ \\[0.2em]
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The aggregator constructs a &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; while having knowledge of the &lt;span class=&quot;math math-inline&quot;&gt;r_j&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
C &amp;amp;= C_τ(r, τ) + C_α(r, τ)⋅α + C_β(r,τ)⋅β + C_δ(r) ⋅ δ +  C_γ(r) ⋅ γ + C_Z(r,τ)⋅{\footnotesize \frac{\Z(τ)}{δ}} \\[0.5em]
&amp;amp;\phantom{=}+ \sum_{i∈[0,p)} C_i(r)⋅{\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ}} +  \sum_{i∈[p,m)} C_i(r)⋅ {\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{δ} }
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where each function &lt;span class=&quot;math math-inline&quot;&gt;f(r, τ)&lt;&#x2F;span&gt; can is of the form &lt;span class=&quot;math math-inline&quot;&gt;f_0(r) + f_1(r)⋅τ + f_2(r)⋅τ^2+⋯&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The steps where the RHS is constant factor on &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; and are much the same as before:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_{αj}(τ) ⋅ B_{βj} &amp;amp;= 1 &amp;amp;\hspace{2em}&amp;amp;\p{α⋅β⋅τ^i⋅r^j} \\
A_{βj}(τ) ⋅ B_{βj} &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{β^2⋅τ^i⋅r^j} \\
A_{αj}(τ) ⋅ B_{γj} &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{α⋅γ⋅τ^i⋅r^j} \\
&amp;amp;\hspace{0.7em}⋮
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So we again get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_j &amp;amp;= A_{τj}(τ) + A_{αj}⋅α + A_{δj} ⋅ δ \\
B_j &amp;amp;= B_{τj}(τ) + A_{αj}^{-1} ⋅ β + B_{δj} ⋅ δ
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Looking at monomials&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\sum_j r^j ⋅ A_{αj} ⋅ B_{τj}(τ) &amp;amp;= \sum_j \sum_{i∈[0,p)} r^j⋅x_{ij} ⋅ \V_i(τ) +  \sum_{i∈[p,m)} C_i(r) ⋅ \V_i(τ)
&amp;amp;\hspace{2em}&amp;amp;\p{α⋅τ^i⋅r^j} \\
\sum_j r^j ⋅ A_{αj}^{-1} ⋅ A_{τj}(τ) &amp;amp;= \sum_j \sum_{i∈[0,p)} r^j⋅x_{ij} ⋅ \U_i(τ) +  \sum_{i∈[p,m)} C_i(r) ⋅ \U_i(τ)
&amp;amp;\hspace{2em}&amp;amp;\p{β⋅τ^i⋅r^j}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Defining&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat x_i =\begin{cases}
\sum_j r^j ⋅ x_{ij} &amp;amp; i∈[0,p) \\
C_i(r) &amp;amp; i∈[p,m)
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;we can rewrite these as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\sum_j r^j ⋅ A_{αj} ⋅ B_{τj}(τ) &amp;amp;= \sum_{i∈[0,m)}  \hat x_i ⋅ \V_i(τ) \\
\sum_j r^j ⋅ A_{αj}^{-1} ⋅ A_{τj}(τ) &amp;amp;= \sum_{i∈[0,m)} \hat x_i ⋅ \U_i(τ)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Finally looking at the monomials in &lt;span class=&quot;math math-inline&quot;&gt;τ^i⋅r^j&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
\sum_j r^j ⋅ A_{τj}(τ) ⋅ B_{τj}(τ) &amp;amp;=
\sum_j r^j ⋅\sum_{i∈[0,p)} x_{ij}⋅\W_i​(τ)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;\sum_{i∈[p,m)} C_i(r)⋅\W_i(τ)&lt;&#x2F;li&gt;
&lt;li&gt;C_Z(r,τ)⋅\Z(τ)
\end{aligned}
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Simplifiying using &lt;span class=&quot;math math-inline&quot;&gt;\hat x&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
\sum_j r^j ⋅ A_{τj}(τ) ⋅ B_{τj}(τ) &amp;amp;=
\sum_{i∈[0,p)} \hat x_i⋅\W_i​(τ)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;C_Z(r,τ)⋅\Z(τ)
\end{aligned}
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Looking at the left hand side:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\sum_j r^j ⋅ A_{τj}(τ) ⋅ B_{τj}(τ) &amp;amp;=
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Assume for the moment &lt;span class=&quot;math math-inline&quot;&gt;\U_i, \V_i, \W_i&lt;&#x2F;span&gt; are all linearly independent Then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\sum_j r^j ⋅ A_{αj} ⋅ B_{τj}(τ) &amp;amp;= \sum_j \sum_{i∈[0,p)} r^j⋅x_{ij} ⋅ \V_i(τ) +  \sum_{i∈[p,m)} C_i(r) ⋅ \V_i(τ)
&amp;amp;\hspace{2em}&amp;amp;\p{α⋅τ^i⋅r^j} \\
\sum_j r^j ⋅ A_{αj}^{-1} ⋅ A_{τj}(τ) &amp;amp;= \sum_j \sum_{i∈[0,p)} r^j⋅x_{ij} ⋅ \U_i(τ) +  \sum_{i∈[p,m)} C_i(r) ⋅ \U_i(τ)
&amp;amp;\hspace{2em}&amp;amp;\p{β⋅τ^i⋅r^j}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;We are looking for&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{j∈[0,k)} r^j⋅
\p{\sum_{i∈[0,n)} x_{ij} ⋅ \U_i(X)} ⋅ \p{\sum_{i∈[0,n)} x_{ij} ⋅ \V_i(X)} =
\sum_{\substack{i∈[0,n)\\j∈[0,k)}} r^j ⋅ x_{ij} ⋅ \W_i(X) + \sum_j r^j ⋅ H_j(X) ⋅\Z(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Can we define &lt;span class=&quot;math math-inline&quot;&gt;H(X) = \sum_j r^j ⋅ H(X)&lt;&#x2F;span&gt; and forgo breaking it down?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{j∈[0,k)} r^j⋅
\p{\sum_{i∈[0,n)} x_{ij} ⋅ \U_i(X)} ⋅ \p{\sum_{i∈[0,n)} x_{ij} ⋅ \V_i(X)} =
\sum_{\substack{i∈[0,n)\\j∈[0,k)}} r^j ⋅ x_{ij} ⋅ \W_i(X) + H(X) ⋅\Z(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Groth16 Soundness Proof</title>
        <published>2023-07-04T00:00:00+00:00</published>
        <updated>2023-07-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/groth16-soundness/"/>
        <id>https://2π.com/23/groth16-soundness/</id>
        
        <content type="html" xml:base="https://2π.com/23/groth16-soundness/">&lt;h1 id=&quot;groth16-soundness-proof&quot;&gt;Groth16 Soundness Proof&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\set#1{\delim\{{#1}\}}
\gdef\e{\operatorname{e}}
\gdef\g{\mathrm{g}}
\gdef\Z{\mathrm{Z}}
\gdef\U{\mathrm{U}}
\gdef\V{\mathrm{V}}
\gdef\W{\mathrm{W}}
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;constraints&quot;&gt;Constraints&lt;&#x2F;h3&gt;
&lt;p&gt;Recall &lt;a href=&quot;&#x2F;22&#x2F;groth16&quot;&gt;Groth16&lt;&#x2F;a&gt;. For a given circuit with &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; variables, &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; constraints and &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; public inputs we encode the circuit as &lt;span class=&quot;math math-inline&quot;&gt;3⋅n+1&lt;&#x2F;span&gt; polynomials &lt;span class=&quot;math math-inline&quot;&gt;\U_i, \V_i, \W_i, \Z ∈ \F[X]&lt;&#x2F;span&gt; each with &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; terms (i.e. degree &lt;span class=&quot;math math-inline&quot;&gt;m-1&lt;&#x2F;span&gt;). A witness &lt;span class=&quot;math math-inline&quot;&gt;x ∈\F^n&lt;&#x2F;span&gt; is correct if for some &lt;span class=&quot;math math-inline&quot;&gt;H(X) ∈ \F[X]&lt;&#x2F;span&gt; it satisfies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\sum_{i∈[0,n)} x_i ⋅ \U_i(X)} ⋅ \p{\sum_{i∈[0,n)} x_i ⋅ \V_i(X)} =
\p{\sum_{i∈[0,n)} x_i ⋅ \W_i(X)} + H(X) ⋅\Z(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;setup&quot;&gt;Setup&lt;&#x2F;h3&gt;
&lt;p&gt;During the setup we generate random scalars &lt;span class=&quot;math math-inline&quot;&gt;τ,α,β,γ,δ&lt;&#x2F;span&gt; from &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; and compute a set of &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; group elements and promptly forget the original scalars. This leaves us with the following group elements, known to prover and verifier:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
δ ⋅ \g_1 \\
\set{τ^0, τ^1, τ^2, …, τ^{2 ⋅ m - 2}} ⋅ \g_1 \\
α ⋅ \set{ τ^0, τ^1, τ^2, …, τ^{m - 1} } ⋅ \g_1 \\
β ⋅ \set{τ^0, τ^1, τ^2, …, τ^{m - 1}} ⋅ \g_1 \\
δ^{-1} ⋅ \Z(τ) ⋅ \set{τ^0, τ^1, τ^2, …, τ^{m - 2}} ⋅ \g_1 \\
γ^{-1} ⋅ \set{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}_{i∈[0,p)} ⋅ \g_1 \\
δ^{-1} ⋅ \set{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}_{i∈[p,n)} ⋅ \g_1 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\set{β, γ, δ} ⋅ \g_2 \\
\set{τ^0, τ^1, τ^2, …, τ^{m - 1} } ⋅ \g_2 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;soundness&quot;&gt;Soundness&lt;&#x2F;h2&gt;
&lt;p&gt;To proof soundness we need to show that a verifying proof implies the existence of a witness &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;. To do this, we start with what we know. We know the (alleged) prover only knows &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; values from the setup and can only compute linear combinations of them. So any &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; value it creates like &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; has the form (ignoring the &lt;span class=&quot;math math-inline&quot;&gt;\g_1&lt;&#x2F;span&gt; factors)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A &amp;amp;= A_τ(τ) + A_α(τ)⋅α + A_β(τ)⋅β + A_δ ⋅ δ +  A_γ ⋅ γ + A_Z(τ)⋅{\footnotesize \frac{\Z(τ)}{δ}} \\[0.5em]
&amp;amp;\phantom{=}+ \sum_{i∈[0,p)} A_i⋅{\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ}} +  \sum_{i∈[p,m)} A_i⋅ {\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{δ} } \\[2em]
B &amp;amp;= B_τ(τ) + B_β⋅β + B_δ ⋅ δ + B_γ ⋅ γ \\[0.2em]
C &amp;amp;= C_τ(τ) + C_α(τ)⋅α + C_β(τ)⋅β + C_δ ⋅ δ +  C_γ ⋅ γ + C_Z(τ)⋅{\footnotesize \frac{\Z(τ)}{δ}} \\[0.5em]
&amp;amp;\phantom{=}+ \sum_{i∈[0,p)} C_i⋅{\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ}} +  \sum_{i∈[p,m)} C_i⋅ {\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{δ} }
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;A_τ(X)&lt;&#x2F;span&gt; has degree at most &lt;span class=&quot;math math-inline&quot;&gt;2⋅m-2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;A_α, A_β&lt;&#x2F;span&gt; degree at most &lt;span class=&quot;math math-inline&quot;&gt;m-1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;A_Z&lt;&#x2F;span&gt; degree at most &lt;span class=&quot;math math-inline&quot;&gt;m-2&lt;&#x2F;span&gt;, similarly for &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;. &lt;span class=&quot;math math-inline&quot;&gt;B(X)&lt;&#x2F;span&gt; is of degree at most &lt;span class=&quot;math math-inline&quot;&gt;m-1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In the Groth16 paper no distinction is made between &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; elements and all values are modeled as linear combinations over the (distrete logarithm) of all of them. This hedges against potential easy-to-compute isomorphisms between &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt;. I&#x27;m not doing this to simplify the soundness proof.&lt;&#x2F;p&gt;
&lt;p&gt;We also know that &lt;span class=&quot;math math-inline&quot;&gt;(w_i, A,B,C)&lt;&#x2F;span&gt; pass the verification check, so&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A⋅B = α⋅β + \sum_{i∈[0,p)} x_i ⋅ \p{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)} + C⋅δ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; is large we can invoke the Schwartz–Zippel lemma and consider both sides as multivariate rational functions in formal parameters &lt;span class=&quot;math math-inline&quot;&gt;τ,α,β,γ,δ&lt;&#x2F;span&gt;. We can then group by monomials. Consider equating the following monomials:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_α(τ) ⋅ B_β &amp;amp;= 1 &amp;amp;\hspace{2em}&amp;amp;\p{α⋅β⋅τ^i} \\
A_β(τ) ⋅ B_β &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{β^2⋅τ^i} \\
A_α(τ) ⋅ B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{α⋅γ⋅τ^i} \\
A_β(τ) ⋅ B_γ + A_γ ⋅ B_β &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{β⋅γ⋅τ^i} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From the first line it follows that &lt;span class=&quot;math math-inline&quot;&gt;A_α(τ)&lt;&#x2F;span&gt; is a non-zero constant and &lt;span class=&quot;math math-inline&quot;&gt;B_β = A_α^{-1}&lt;&#x2F;span&gt;. Then by the second and third line &lt;span class=&quot;math math-inline&quot;&gt;A_β(τ)=0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B_γ = 0&lt;&#x2F;span&gt;. By the fourth &lt;span class=&quot;math math-inline&quot;&gt;A_γ = 0&lt;&#x2F;span&gt;. Then looking at the following monomials&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\p{\sum_{i∈[0,p)} A_i⋅\p{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}} ⋅ B_β &amp;amp;= 0
&amp;amp;\hspace{2em}&amp;amp;\p{β⋅γ^{-1}⋅τ^i} \\[2em]
\p{A_Z(τ)⋅ \Z(τ) +  \sum_{i∈[p,m)} A_i⋅\p{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}} ⋅ B_β &amp;amp;= 0
&amp;amp;\hspace{2em}&amp;amp;\p{β⋅δ^{-1}⋅τ^i} \\[2em]
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We see that these sub-expression from &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; sum to zero. Substituting all this into &lt;span class=&quot;math math-inline&quot;&gt;A, B&lt;&#x2F;span&gt; gives&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A &amp;amp;= A_τ(τ) + A_α⋅α + A_δ ⋅ δ \\
B &amp;amp;= B_τ(τ) + A_α^{-1} ⋅ β + B_δ ⋅ δ
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Looking at monomials&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_α ⋅ B_τ(τ) &amp;amp;= \sum_{i∈[0,p)} x_i ⋅ \V_i(τ) +  \sum_{i∈[p,m)} C_i ⋅ \V_i(τ)
&amp;amp;\hspace{2em}&amp;amp;\p{α⋅τ^i} \\
A_α^{-1} ⋅ A_τ(τ) &amp;amp;= \sum_{i∈[0,p)} x_i ⋅ \U_i(τ) +  \sum_{i∈[p,m)} C_i ⋅ \U_i(τ)
&amp;amp;\hspace{2em}&amp;amp;\p{β⋅τ^i}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Defining&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat x_i=\begin{cases}
x_i &amp;amp; i∈[0,p) \\
C_i &amp;amp; i∈[p,m)
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;we can write&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_τ(τ) &amp;amp;= A_α ⋅ \sum_{i∈[0,m)} \hat x_i⋅\U_i(τ) \\
B_τ(τ) &amp;amp;= A_α^{-1} ⋅ \sum_{i∈[0,m)} \hat x_i⋅\V_i(τ) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Looking at the monomials &lt;span class=&quot;math math-inline&quot;&gt;τ^i&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\p{\sum_{i∈[0,m)} \hat x_i⋅\U_i(τ)} ⋅ \p{\sum_{i∈[0,m)} \hat x_i⋅\V_i(τ)}
= \sum_{i∈[0,p)} \hat x_i ⋅ \W_i(τ)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;C_Z(τ)⋅\Z(τ)
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;which shows that &lt;span class=&quot;math math-inline&quot;&gt;\hat x&lt;&#x2F;span&gt; is a satisfying witness.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;attempts-to-get-rid-of-the-constant&quot;&gt;Attempts to get rid of the constant&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;d like to get rid of the constant pairing &lt;span class=&quot;math math-inline&quot;&gt;\e\p{α⋅\g_1, β⋅\g_2}&lt;&#x2F;span&gt;. In EVM this requires and additional pairing instead of a target group addition.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attempt-i&quot;&gt;Attempt I&lt;&#x2F;h3&gt;
&lt;p&gt;Give the verifier &lt;span class=&quot;math math-inline&quot;&gt;\frac{α⋅β}{γ}⋅\g_1&lt;&#x2F;span&gt; to add to the public input point. Since &lt;span class=&quot;math math-inline&quot;&gt;x_0 = 1&lt;&#x2F;span&gt; by convention, this can be done with no extra computation. It also doesn&#x27;t change the verification equation or the prover algorithm so completeness and zero-knowledge are preserved. However, it does change an attackers abilities as it can now also construct &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; elements containing an additional term.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A&amp;#39; &amp;amp;= A + A_{αβγ} ⋅ \frac{α⋅β}{γ}\\
C&amp;#39; &amp;amp;= C + C_{αβγ} ⋅ \frac{α⋅β}{γ}\\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We need to check if soundness still holds.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_{αβγ}⋅B_β &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{α⋅β^2⋅γ^{-1}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this either &lt;span class=&quot;math math-inline&quot;&gt;A_{αβγ} = 0&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;B_β = 0&lt;&#x2F;span&gt;. Since &lt;span class=&quot;math math-inline&quot;&gt;A_{αβγ} = 0&lt;&#x2F;span&gt; mimics the previous soundness proof, let&#x27;s proceed with &lt;span class=&quot;math math-inline&quot;&gt;B_β = 0&lt;&#x2F;span&gt; instead and see if it results in contradiction.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_{αβγ}⋅B_γ &amp;amp;= 1 &amp;amp;\hspace{2em}&amp;amp;\p{α⋅β} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this follows &lt;span class=&quot;math math-inline&quot;&gt;A_{αβγ} = B_γ^{-1}&lt;&#x2F;span&gt; and specifically both are non-zero.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_γ⋅B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{γ^2} \\
A_α(τ)⋅B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{α⋅γ} \\
A_β(τ)⋅B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{β⋅γ} \\
B_τ(τ)⋅B_γ^{-1} &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{α.β⋅γ^{-1}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this follows that &lt;span class=&quot;math math-inline&quot;&gt;A_γ, A_α,A_β,B_τ&lt;&#x2F;span&gt; are all &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_τ(τ)⋅B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{γ} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this follows that &lt;span class=&quot;math math-inline&quot;&gt;A_τ = 0&lt;&#x2F;span&gt;. Finally we have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\p{\sum_{i∈[p,m)} A_i ⋅ \V_i(τ)}⋅B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{α⋅δ^{-1}⋅γ} \\
\p{\sum_{i∈[p,m)} A_i ⋅ \U_i(τ)}⋅B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{β⋅δ^{-1}⋅γ} \\
\p{\sum_{i∈[p,m)} A_i ⋅ \W_i(τ)}⋅B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{δ^{-1}⋅γ} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So all these sum to zero, we then get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A_Z(τ) ⋅ \Z(τ)⋅B_γ &amp;amp;= 0 &amp;amp;\hspace{2em}&amp;amp;\p{β⋅δ^{-1}⋅γ} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So &lt;span class=&quot;math math-inline&quot;&gt;A_Z(τ) ⋅ \Z(τ) = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;re now left with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A &amp;amp;= A_δ ⋅δ + B_γ^{-1}⋅\frac{α⋅β}{γ} + \sum_{i∈[0,p)} A_i⋅ \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ} \\
B &amp;amp;= B_δ ⋅ δ + B_γ ⋅ γ
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s look at &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; a bit&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
0 &amp;amp;= C_τ(τ) &amp;amp;\hspace{2em}&amp;amp;\p{δ} \\
0 &amp;amp;= C_α(τ) &amp;amp;\hspace{2em}&amp;amp;\p{α⋅δ} \\
0 &amp;amp;= C_β(τ) &amp;amp;\hspace{2em}&amp;amp;\p{β⋅δ} \\
A_δ ⋅ B_δ &amp;amp;= C_δ &amp;amp;\hspace{2em}&amp;amp;\p{δ^2} \\
A_δ ⋅ B_γ &amp;amp;= C_γ &amp;amp;\hspace{2em}&amp;amp;\p{δ⋅γ} \\
B_γ^{-1} ⋅ B_δ &amp;amp;= C_{αβγ} &amp;amp;\hspace{2em}&amp;amp;\p{α⋅β⋅δ⋅γ^{-1}} \\
\p{\sum_{i∈[0,p)} A_i ⋅ \V_i(τ)}⋅B_δ &amp;amp;= \sum_{i∈[0,p)} C_i ⋅ \V_i(τ) &amp;amp;\hspace{2em}&amp;amp;\p{α⋅δ⋅γ^{-1}} \\
\p{\sum_{i∈[0,p)} A_i ⋅ \U_i(τ)}⋅B_δ &amp;amp;= \sum_{i∈[0,p)} C_i ⋅ \U_i(τ) &amp;amp;\hspace{2em}&amp;amp;\p{β⋅δ⋅γ^{-1}} \\
\p{\sum_{i∈[0,p)} A_i ⋅ \W_i(τ)}⋅B_δ &amp;amp;= \sum_{i∈[0,p)} C_i ⋅ \W_i(τ) &amp;amp;\hspace{2em}&amp;amp;\p{δ⋅γ^{-1}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This gives us&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
C &amp;amp;= A_δ ⋅ B_δ ⋅ δ +  A_δ ⋅ B_γ ⋅ γ + B_γ^{-1} ⋅ B_δ ⋅ \frac{α⋅β}{γ}+  C_Z(τ)⋅{\footnotesize \frac{\Z(τ)}{δ}} \\[0.5em]
&amp;amp;\phantom{=}+ B_δ ⋅\sum_{i∈[0,p)} A_i⋅{\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ}} +  \sum_{i∈[p,m)} C_i⋅ {\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{δ} }
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
B_δ⋅B_γ^{-1} &amp;amp;= B_β⋅B_γ^{-1} &amp;amp;\hspace{2em}&amp;amp;\p{α⋅β⋅δ⋅γ^{-1}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So &lt;span class=&quot;math math-inline&quot;&gt;B_β = B_δ&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
B_γ ⋅ \sum_{i∈[0,p)} A_i ⋅ \V_i(τ) &amp;amp;= \sum_{i∈[0,p)} x_i ⋅ \V_i(τ) + \sum_{i∈[p,m)} C_i ⋅ \V_i(τ)  &amp;amp;\hspace{2em}&amp;amp;\p{α} \\
B_γ ⋅ \sum_{i∈[0,p)} A_i ⋅ \U_i(τ) &amp;amp;= \sum_{i∈[0,p)} x_i ⋅ \U_i(τ) + \sum_{i∈[p,m)} C_i ⋅ \U_i(τ)  &amp;amp;\hspace{2em}&amp;amp;\p{β} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The obvious solution to this is &lt;span class=&quot;math math-inline&quot;&gt;A_i = B_γ^{-1} ⋅ x_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;C_i = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Are there non-obvious solutions?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
B_γ ⋅ \sum_{i∈[0,p)} A_i ⋅ \W_i(τ) &amp;amp;= C_Z(τ) ⋅ \Z(τ) + \sum_{i∈[0,p)} x_i ⋅ \W_i(τ) + \sum_{i∈[p,m)} C_i ⋅ \W_i(τ)  &amp;amp;\hspace{2em}&amp;amp;\p{τ} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;from this it follows &lt;span class=&quot;math math-inline&quot;&gt;C_Z = 0&lt;&#x2F;span&gt;. This dismisses the last term without creating a witness. Instead we found a way to generate &#x27;proofs&#x27; for any public input &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
A &amp;amp;= A_δ ⋅δ + B_γ^{-1}⋅\p{\frac{α⋅β}{γ} + \sum_{i∈[0,p)} x_i⋅ \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ}} \
B &amp;amp;= B_δ ⋅ δ + B_γ ⋅ γ \
C &amp;amp;= A_δ ⋅ B_δ ⋅ δ +  A_δ ⋅ B_γ ⋅ γ + B_γ^{-1} ⋅ B_δ \p{\frac{α⋅β}{γ}&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;\sum_{i∈[0,p)} x_i⋅{\footnotesize \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ}} }
\end{aligned}
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The simplest instance of this is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A &amp;amp;= \frac{α⋅β}{γ} + \sum_{i∈[0,p)} x_i⋅ \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{γ} \\
B &amp;amp;= γ \\
C &amp;amp;= 0
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attempt-ii&quot;&gt;Attempt II&lt;&#x2F;h3&gt;
&lt;p&gt;What if we gave &lt;span class=&quot;math math-inline&quot;&gt;\frac{α⋅β}{δ}⋅\g_1&lt;&#x2F;span&gt; instead? This can be added by the prover or verifier to &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;. It is not possible to construct&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i∈[0,p)} x_i⋅ \frac{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)}{δ}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;using the provided setup variables, so the previous break will not work.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attempt-iii&quot;&gt;Attempt III&lt;&#x2F;h3&gt;
&lt;p&gt;Since adding to &lt;span class=&quot;math math-inline&quot;&gt;L&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; is not an option, so if it is at all possible the constant will need to be folded into &lt;span class=&quot;math math-inline&quot;&gt;A⋅B&lt;&#x2F;span&gt; somehow. The challenge here is that adding any term to either produces many cross-terms.&lt;&#x2F;p&gt;
&lt;p&gt;Since there is no &lt;span class=&quot;math math-inline&quot;&gt;α⋅\g_2&lt;&#x2F;span&gt; we can try &lt;span class=&quot;math math-inline&quot;&gt;\frac{α⋅β}{α}⋅\g_1&lt;&#x2F;span&gt;. But this is just &lt;span class=&quot;math math-inline&quot;&gt;β⋅\g_1&lt;&#x2F;span&gt; which we already had. This suggests simply removing &lt;span class=&quot;math math-inline&quot;&gt;α⋅β&lt;&#x2F;span&gt; from the verification equation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A ⋅ B = \sum_{i∈[0,p)} x_i ⋅ \p{β ⋅ \U_i(τ) + α ⋅ \V_i(τ) + \W_i(τ)} + C⋅δ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Number Theoretic Transforms</title>
        <published>2023-06-21T00:00:00+00:00</published>
        <updated>2023-06-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/ntt/"/>
        <id>https://2π.com/23/ntt/</id>
        
        <content type="html" xml:base="https://2π.com/23/ntt/">&lt;h1 id=&quot;number-theoretic-transforms&quot;&gt;Number Theoretic Transforms&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\F{\mathbb F}
\gdef\i{\mathrm i}
\gdef\mod#1{\delim[{#1}]}
\gdef\M{\mathsf{\small M}}
\gdef\A{\mathsf{\small A}}
\gdef\Mc{\mathsf{\small M^c}}
\gdef\Ac{\mathsf{\small A^c}}
\gdef\NTT{\mathsf{\small NTT}}
\gdef\CCV{\mathsf{\small CCV}}
\gdef\Z{\mathrm{Z}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;NTTs, FFTs, convolutions, multiplication, interpolation, Chinese remainder theorem, Lagrange basis, Representation theory, FRI. It&#x27;s all the same thing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fourier_transform_on_finite_groups#Relationship_with_representation_theory&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fourier_transform_on_finite_groups#Relationship_with_representation_theory&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Prime length FRI using Rader?&lt;&#x2F;p&gt;
&lt;p&gt;A lot of research on them has been done in DSP. But there the more sophisticated methods are not as popular because&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Exchanging muls for adds is not very worthwhile.&lt;&#x2F;li&gt;
&lt;li&gt;Numerical accuracy is challenging.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Neither of these holds in finite fields.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\ω{\text{ω}}
\gdef\MF{\mathrm{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The number theoretic transform (NTT) of a sequence &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; of length &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; over a field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; is defined as a sequence &lt;span class=&quot;math math-inline&quot;&gt;f_k&lt;&#x2F;span&gt; of length &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
f_k = \sum_{i∈[0,n)} x_i ⋅ \ω_n^{i⋅k}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\ω_n&lt;&#x2F;span&gt; is a primitive &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Root_of_unity&quot;&gt;root of unity&lt;&#x2F;a&gt;. When &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; is the complex numbers the roots are &lt;span class=&quot;math math-inline&quot;&gt;\ω_n = \mathrm{e}^{\frac{2⋅\mathrm{π}⋅\mathrm{i}}{n}}&lt;&#x2F;span&gt; and the transform is called the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Discrete_Fourier_transform&quot;&gt;discrete Fourier transform&lt;&#x2F;a&gt; (DFT) and its implementations &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fast_Fourier_transform&quot;&gt;fast Fourier transform&lt;&#x2F;a&gt; (FFT). In a prime order finite field &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; with generator &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; the roots are &lt;span class=&quot;math math-inline&quot;&gt;\ω_n = g^{\frac{p-1}{n}}&lt;&#x2F;span&gt;. Note that the roots are not unique and &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^k&lt;&#x2F;span&gt; is also a valid &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th root of unity whenever &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; a coprime.&lt;&#x2F;p&gt;
&lt;p&gt;The roots are just numbers and satisfy all the algebraic properties such that &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^0 = 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^{a + b} = \ω_n^a⋅\ω_n^b&lt;&#x2F;span&gt;. In addition they have some unique properties such as &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^n = 1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\ω_{k⋅n}^k = \ω_n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i∈[0,n)} \ω_n^i = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\sum_{i∈[0,n)} \ω_n^{a⋅i} = \begin{cases}
n &amp;amp; a = 0 \\
0 &amp;amp; a ≠ 0
\end{cases}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From these it follows that &lt;span class=&quot;math math-inline&quot;&gt;\ω_2 = -1&lt;&#x2F;span&gt;, which is why the &lt;span class=&quot;math math-inline&quot;&gt;n=2&lt;&#x2F;span&gt; case is particularly efficient:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f_0 &amp;amp;= x_0 + x_1 &amp;amp;
f_1 &amp;amp;= x_0 - x_1
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ntt-is-almost-it-s-own-inverse&quot;&gt;NTT is Almost it&#x27;s own Inverse&lt;&#x2F;h3&gt;
&lt;p&gt;The inverse of the NTT is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x_i = \frac 1n \sum_{k∈[0,n)} f_k ⋅ \ω_n^{-i⋅k}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Proof&lt;&#x2F;summary&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\frac 1n \sum_{k∈[0,n)} f_k ⋅ \ω_n^{-i⋅k}
&amp;amp;= \frac 1n \sum_{k∈[0,n)} \p{\sum_{j∈[0,n)} x_j ⋅ \ω_n^{j⋅k}} ⋅ \ω_n^{-i⋅k} \\
&amp;amp;= \frac 1n \sum_{k∈[0,n)} \sum_{j∈[0,n)} x_j ⋅ \ω_n^{j⋅k-i⋅k} \\
&amp;amp;= \frac 1n \sum_{j∈[0,n)} x_j \sum_{k∈[0,n)} \ω_n^{\p{j-i}⋅k} \\
&amp;amp;= \frac 1n \sum_{j∈[0,n)} x_j \p{\begin{cases}
n &amp;amp; i = j \\
0 &amp;amp; i ≠ j
\end{cases}} \\
&amp;amp;= \frac 1n x_i ⋅ n \\
&amp;amp;= x_i \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;p&gt;The factor of &lt;span class=&quot;math math-inline&quot;&gt;\frac 1n&lt;&#x2F;span&gt; is constant can be applied to the output (as in the sum above) or brought inside the sum and applied to the input. It can even be applied together with the &lt;span class=&quot;math math-inline&quot;&gt;\ω&lt;&#x2F;span&gt; factors to save operations, but this requires a bit more care to correctly propagate through the various algorithms presented below.&lt;&#x2F;p&gt;
&lt;p&gt;The other difference with a regular &lt;span class=&quot;math math-inline&quot;&gt;\NTT&lt;&#x2F;span&gt; is the factor of &lt;span class=&quot;math math-inline&quot;&gt;-1&lt;&#x2F;span&gt; in the exponent of &lt;span class=&quot;math math-inline&quot;&gt;\ω&lt;&#x2F;span&gt;. Since for each &lt;span class=&quot;math math-inline&quot;&gt;\ω_n&amp;#39; = \ω_n^{-1}&lt;&#x2F;span&gt; is also a primitive &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th root of unity we can use the regular algorithm with a different root. Instead of changing the root, we can also substitute &lt;span class=&quot;math math-inline&quot;&gt;i&amp;#39; = \mod{-i}_n&lt;&#x2F;span&gt;. This has the effect of reversing the order of all but the &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;-th index element in the output sequence. By symmetry with &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; this can also be done on the input elements.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ntt-is-matrix-multiplication&quot;&gt;NTT is Matrix Multiplication&lt;&#x2F;h3&gt;
&lt;p&gt;This equation can also be seen as a multiplying the vector &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;DFT_matrix&quot;&gt;DFT matrix&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\MF_n&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;(\MF_n)_{ij} = \ω_n^{i⋅j}&lt;&#x2F;span&gt;, i.e.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
f_0 \\ f_1 \\ f_2 \\ ⋮ \\ f_{n-1}
\end{bmatrix} =
\begin{bmatrix}
ω^0 &amp;amp; ω^0 &amp;amp; ω^0 &amp;amp; ⋯ &amp;amp; w^0 \\
ω^0 &amp;amp; ω^1 &amp;amp; ω^2 &amp;amp; ⋯ &amp;amp; w^{n -1}\\
ω^0 &amp;amp; ω^2 &amp;amp; ω^4 &amp;amp; ⋯ &amp;amp; w^{2⋅(n-1)}\\
⋮ &amp;amp; ⋮ &amp;amp; ⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\
ω^0 &amp;amp; ω^{n-1} &amp;amp; ω^{2⋅(n-1)} &amp;amp; ⋯ &amp;amp; ω^{(n-1)^2} \\
\end{bmatrix}⋅
\begin{bmatrix}
x_0 \\ x_1 \\ x_2 \\ ⋮ \\ x_{n-1}
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The matrix is symmetric, &lt;span class=&quot;math math-inline&quot;&gt;\MF_n^\mathsf{T}=\MF_n&lt;&#x2F;span&gt;, and has inverse &lt;span class=&quot;math math-inline&quot;&gt;(\MF_n^{-1})_{ij} = \frac 1n ⋅ \ω_n^{-i⋅j}&lt;&#x2F;span&gt;. It is also a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vandermonde_matrix&quot;&gt;Vandermonde matrix&lt;&#x2F;a&gt; on the basis &lt;span class=&quot;math math-inline&quot;&gt;(\ω_n^0,…, \ω_n^{n-1})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ntt-is-polynomial-evaluation&quot;&gt;NTT is Polynomial Evaluation&lt;&#x2F;h3&gt;
&lt;p&gt;We can also interpret the NTT equation as evaluating a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P∈\F[X]&lt;&#x2F;span&gt; with coefficients &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; in points &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^k&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X) &amp;amp;= \sum_{i∈[0,n)} x_{i} ⋅ X^i &amp;amp;\text{and}&amp;amp;&amp;amp; f_k = P\p{\ω_n^k}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ntt-is-polynomial-interpolation&quot;&gt;NTT is Polynomial Interpolation&lt;&#x2F;h3&gt;
&lt;p&gt;If we interpret &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; as a set of values of some polynomial &lt;span class=&quot;math math-inline&quot;&gt;P∈\F[X]&lt;&#x2F;span&gt; on the basis &lt;span class=&quot;math math-inline&quot;&gt;(\ω_n^0,…, \ω_n^{n-1})&lt;&#x2F;span&gt;. Then we can construct the polynomial using Lagrange interpolation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = \sum_{i∈[0,n)} x_i ⋅ L_{n,i}(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lagrange_polynomial&quot;&gt;Lagrange polynomials&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;L_{n,i}(X)&lt;&#x2F;span&gt; are&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_{n,i}(X) = \prod_{j∈[0,n)\setminus i} \frac{X - \ω_n^j}{\ω_n^i - \ω_n^j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ntt-is-chinese-remainder-theorem&quot;&gt;NTT is Chinese Remainder Theorem&lt;&#x2F;h3&gt;
&lt;p&gt;Another way of evaluating a polynomial at &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; is by reducing it modulo the monomial &lt;span class=&quot;math math-inline&quot;&gt;(X - x)&lt;&#x2F;span&gt;, which leads to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f_k = \mod{P}_{\p{X - \ω_n^k}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The product of all these moduli is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cyclotomic_polynomial&quot;&gt;Cyclotomic polynomial&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\prod_{k∈[0,n)} \p{X - \ω_n^k} = X^n - 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we know two factors &lt;span class=&quot;math math-inline&quot;&gt;n = a⋅b&lt;&#x2F;span&gt; then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X^n - 1 = \p{X^a - 1}⋅\p{X^b - 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X^{a + b} - X^a - X^b + 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ntt-is-a-ring-isomorphism&quot;&gt;NTT is a ring isomorphism&lt;&#x2F;h2&gt;
&lt;p&gt;The vector space &lt;span class=&quot;math math-inline&quot;&gt;\F^n&lt;&#x2F;span&gt; forms a ring under vector addition and Hadamard product. The &lt;span class=&quot;math math-inline&quot;&gt;\NTT&lt;&#x2F;span&gt; is a ring isomorphism between &lt;span class=&quot;math math-inline&quot;&gt;\F^n&lt;&#x2F;span&gt; and the ring &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&#x2F;\p{X^n - 1}&lt;&#x2F;span&gt;. The fastest known algorithms for multiplying in &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&lt;&#x2F;span&gt; work by finding a sufficiently large &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; to lower the problem to &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&#x2F;\p{X^n - 1}&lt;&#x2F;span&gt; and then use &lt;span class=&quot;math math-inline&quot;&gt;\NTT&lt;&#x2F;span&gt; to transform to &lt;span class=&quot;math math-inline&quot;&gt;\F^n&lt;&#x2F;span&gt;, apply the Hadamard product, and transform back.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;ntt-diagonalized-shift-invariant-operators&quot;&gt;NTT Diagonalized shift-invariant operators&lt;&#x2F;h2&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;S_n&lt;&#x2F;span&gt; the &lt;span class=&quot;math math-inline&quot;&gt;n×n&lt;&#x2F;span&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Shift_matrix&quot;&gt;shift matrix&lt;&#x2F;a&gt;. For a (not necessarily primitive) &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; th-root of unity &lt;span class=&quot;math math-inline&quot;&gt;ω&lt;&#x2F;span&gt; the vector &lt;span class=&quot;math math-inline&quot;&gt;\begin{bmatrix} ω^0, ω^1, ω^1, …, ω^{n-1}\end{bmatrix}&lt;&#x2F;span&gt; is an eigenvector of &lt;span class=&quot;math math-inline&quot;&gt;S_n&lt;&#x2F;span&gt; with eigenvalue &lt;span class=&quot;math math-inline&quot;&gt;ω&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ω ⋅ \begin{bmatrix} ω^0 \\ ω^1 \\ ω^1 \\ ⋮ \\ ω^{n-1}\end{bmatrix} =
\begin{bmatrix} ω^1 \\ ω^2 \\  ⋮ \\ ω^{n-1} \\ ω^0\end{bmatrix} =
S_n ⋅ \begin{bmatrix} ω^0 \\ ω^1 \\ ω^1 \\ ⋮ \\ ω^{n-1}\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Matrices that commute have the same eigenbasis (up to eigenspaces). So the NTT matrix is an eigenbasis for the shift matrix and any matrix that commutes with it. All matrices diagonalized by the FFT are the ones that commute with the shift operator.&lt;&#x2F;p&gt;
&lt;p&gt;When talking about time series, shift-invariance means time invariance.&lt;&#x2F;p&gt;
&lt;p&gt;See https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=37915044&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Companion_matrix&quot;&gt;companion matrix&lt;&#x2F;a&gt; of &lt;span class=&quot;math math-inline&quot;&gt;X^n -1&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;S_n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Question: What do companion matrices of cyclic polynomials look like?&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Triangular_matrix#Simultaneous_triangularisability&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Commuting_matrices&lt;&#x2F;p&gt;
&lt;p&gt;Circulant matrices form a commutative ring, as they are closed under summation. So to the diagonal matrices.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hilbert%27s_Nullstellensatz&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;If we know two factors &lt;span class=&quot;math math-inline&quot;&gt;n = 2 ⋅ m&lt;&#x2F;span&gt; then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X^n - 1 = \p{X^m - 1} ⋅ \p{X^m + 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{X^m - 1} ⋅ \p{X^m + 1} = X^{2⋅m} - 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chinese_remainder_theorem&quot;&gt;Chinese remainder theorem&lt;&#x2F;a&gt; we can reconstruct &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; from these remainders&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
M &amp;amp;= \prod_{i∈[0,n)} m_i  &amp;amp; M_i &amp;amp;= \frac{M}{m_i} &amp;amp;
\mod{x}_M = \mod{ \sum_{i∈[0,n)} \frac{M}{m_i} ⋅ \mod{x⋅\frac{m_i}{M} }_{m_i}  }_M
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mod{P}_{\p{X^n -1}} = \mod{ \sum_{i∈[0,n)} \frac{\p{X^n -1}}{\p{X - \ω_n^i}} ⋅ \mod{P⋅\frac{\p{X - \ω_n^i}}{\p{X^n -1}} }_{\p{X - \ω_n^i}}  }_{\p{X^n -1}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P = \sum_{k∈[0,n)} f_k⋅\prod_{k∈[0,n)} \p{X - \ω_n^k}   \,\operatorname{mod}\, \prod_{k∈[0,n)} \p{X - \ω_n^k}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-cooley-tukey-algorithm&quot;&gt;The Cooley-Tukey algorithm&lt;&#x2F;h2&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;n = a ⋅ b&lt;&#x2F;span&gt; we can rewrite &lt;span class=&quot;math math-inline&quot;&gt;i = i_a + i_b ⋅ a&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;i_a∈[0,a)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;i_b∈[0,b)&lt;&#x2F;span&gt;. This creates a correspondence &lt;span class=&quot;math math-inline&quot;&gt;[0,n) ≃ [0,a)×[0,b)&lt;&#x2F;span&gt;. An alternative correspondence is &lt;span class=&quot;math math-inline&quot;&gt;k = k_b + k_a ⋅ b&lt;&#x2F;span&gt;. If we substitute these in the definition of NTT we get:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_{k_b + k_a ⋅ b} = \sum_{i_a∈[0,a)}\sum_{i_b∈[0,b)} x_{i_a + i_b ⋅ a} ⋅ \ω_n^{\p{i_a + i_b ⋅ a}⋅\p{k_b + k_a ⋅ b}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Expanding the exponent of &lt;span class=&quot;math math-inline&quot;&gt;\ω_n&lt;&#x2F;span&gt; we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ω_n^{\p{i_a + i_b ⋅ a}⋅\p{k_b + k_a ⋅ b}} =
\ω_n^{i_a ⋅ k_b} ⋅
\ω_n^{i_b ⋅ k_b ⋅ a} ⋅
\ω_n^{i_a ⋅ k_a ⋅ b} ⋅
\ω_n^{i_b ⋅ k_a ⋅ a ⋅ b}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using &lt;span class=&quot;math math-inline&quot;&gt;\ω_{l⋅m}^l = \ω_m&lt;&#x2F;span&gt; we get &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^a = \ω_b&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^b = \ω_a&lt;&#x2F;span&gt;, combined with &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^{a⋅b} = \ω_n^n = 1&lt;&#x2F;span&gt; this simplifies the exponent to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ω_n^{\p{i_a + i_b ⋅ a}⋅\p{k_b + k_a ⋅ b}} = \ω_b^{i_b ⋅ k_b} ⋅ \ω_n^{i_a ⋅ k_b} ⋅ \ω_a^{i_a ⋅ k_a}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Substituting this back in&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_{k_b + k_a ⋅ b} = \sum_{i_a∈[0,a)}\sum_{i_b∈[0,b)} x_{i_a + i_b ⋅ a} ⋅ \ω_b^{i_b ⋅ k_b} ⋅
\ω_n^{i_a ⋅ k_b} ⋅
\ω_a^{i_a ⋅ k_a}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This allows us to introduce some brackets&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_{k_b + k_a ⋅ b} = \sum_{i_a∈[0,a)}
\delim[{
\p{\sum_{i_b∈[0,b)} x_{i_a + i_b ⋅ a} ⋅
\ω_b^{i_b ⋅ k_b}} ⋅
\ω_n^{i_a ⋅ k_b}
}]⋅\ω_a^{i_a ⋅ k_a}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can now see that the sum in parenthesis is an NTT of size &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; operating over subsequences of &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;. This then gets multiplied by an extra factor &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^{i_a ⋅ k_b}&lt;&#x2F;span&gt;, known as a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Twiddle_factor&quot;&gt;twiddle factor&lt;&#x2F;a&gt;. The outer sum over the square brackets is again an NTT, this time of size &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;. This is the core of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cooley%E2%80%93Tukey_FFT_algorithm&quot;&gt;Cooley-Tukey algorithm&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s instructive to visualize &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; as a &lt;span class=&quot;math math-inline&quot;&gt;b×a&lt;&#x2F;span&gt;-sized matrix in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Row-_and_column-major_order&quot;&gt;row-major order&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = \begin{bmatrix}
x_0 &amp;amp; x_1 &amp;amp; x_2 &amp;amp; ⋯ &amp;amp; x_{a-1} \\
x_a &amp;amp; x_{1+a} &amp;amp; x_{2+a} &amp;amp; ⋯ &amp;amp; x_{(a-1) + a} \\
x_{2⋅a} &amp;amp; x_{1 + 2⋅a} &amp;amp; x_{2 + 2⋅a} &amp;amp; ⋯ &amp;amp; x_{(a-1) + 2⋅  a} \\
⋮ &amp;amp;⋮ &amp;amp;⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\
x_{(b-1)⋅a} &amp;amp; x_{1 + (b-1)⋅a} &amp;amp; x_{3 + (b-1)⋅a} &amp;amp; ⋯ &amp;amp; x_{(a-1) + (b-1)⋅a}
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We then transform all the columns in this matrix using a &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;-sized NTT. To apply the twiddle factors, these can also be written as a &lt;span class=&quot;math math-inline&quot;&gt;b × a&lt;&#x2F;span&gt; matrix with &lt;span class=&quot;math math-inline&quot;&gt;W_{ij} = \ω_n^{i⋅j}&lt;&#x2F;span&gt; which can then be applied by a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hadamard_product_(matrices)&quot;&gt;pointwise product&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
W =
\begin{bmatrix}
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; ⋯ &amp;amp; 1 \\
1 &amp;amp; \ω &amp;amp; \ω^2 &amp;amp; ⋯ &amp;amp; \ω^{a-1} \\
1 &amp;amp; \ω^2 &amp;amp; \ω^4 &amp;amp; ⋯ &amp;amp; \ω^{\p{a-1}⋅2} \\
⋮ &amp;amp;⋮ &amp;amp;⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\
1 &amp;amp; \ω^{b-1} &amp;amp; \ω^{2⋅\p{b-1}} &amp;amp; ⋯ &amp;amp; \ω^{\p{a-1}⋅\p{b -1}} \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The next  step is to transform all the rows using a &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;-sized NTT. All the values are now computed, but they are not yet in the correct order. The output order, &lt;span class=&quot;math math-inline&quot;&gt;f_{k_b + k_a ⋅ b}&lt;&#x2F;span&gt;, corresponds to a &lt;span class=&quot;math math-inline&quot;&gt;a×b&lt;&#x2F;span&gt; sized matrix in row-major order. Fortunately it is just the transpose of the matrix we have computed.&lt;&#x2F;p&gt;
&lt;p&gt;In summary the steps are&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Reinterpreted as a &lt;span class=&quot;math math-inline&quot;&gt;b×a&lt;&#x2F;span&gt; matrix in row-major order.&lt;&#x2F;li&gt;
&lt;li&gt;Apply &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;-sized NTTs to all the columns in &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Multiply each element by its twiddle factor &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^{i⋅j}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Apply &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;-sized NTTs to all the rows.&lt;&#x2F;li&gt;
&lt;li&gt;Transpose the matrix to have the output in row-major order.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The first and fifth step are commonly omitted and the algorithm is known as the &lt;em&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bailey%27s_FFT_algorithm&quot;&gt;four-step NTT&lt;&#x2F;a&gt;&lt;&#x2F;em&gt; or &lt;em&gt;Bailey&#x27;s FFT&lt;&#x2F;em&gt;. It has the implementation drawback that the NTTs in the second step are over values discontinuous in memory. We can solve this by doing two more transpositions after steps 1 and 2 to get the &lt;em&gt;six-step NTT&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If the factors &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; are again composite the Cooley-Tukey algorithm can be applied recursively. A common strategy is to pick a highly composite &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; such as &lt;span class=&quot;math math-inline&quot;&gt;n = 2^k&lt;&#x2F;span&gt; and recursively split it. There are several strategies to do this. If we make &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; as small as possible, it is called &lt;em&gt;decimation-in-time&lt;&#x2F;em&gt; (DIT). If instead we make &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; as small as possible it is &lt;em&gt;decimation-in-frequency&lt;&#x2F;em&gt; (DIF). In both cases the small base case is known as the &lt;em&gt;radix&lt;&#x2F;em&gt;. It is also common to refer to NTT algorithms by their radix as in &#x27;radix-4 NTT&#x27;. Highly optimized small NTTs to be used as base case are known as &lt;em&gt;codelets&lt;&#x2F;em&gt;. These are the subject of ongoing research but this is mostly focussed on the complex numbers.
If we make &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; about the same size it is called a radix-&lt;span class=&quot;math math-inline&quot;&gt;\sqrt{n}&lt;&#x2F;span&gt;. The six-step radix-&lt;span class=&quot;math math-inline&quot;&gt;\sqrt{n}&lt;&#x2F;span&gt; algorithm is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cache-oblivious_algorithm&quot;&gt;cache-oblivious&lt;&#x2F;a&gt; algorithm when combined with an cache-oblivious matrix transpose. This makes it particularly suitable for very large &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. Finally for complex numbers an variant called &lt;em&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Split-radix_FFT_algorithm&quot;&gt;split-radix&lt;&#x2F;a&gt;&lt;&#x2F;em&gt; recurses into a size &lt;span class=&quot;math math-inline&quot;&gt;\frac n2&lt;&#x2F;span&gt; and two &lt;span class=&quot;math math-inline&quot;&gt;\frac n4&lt;&#x2F;span&gt; NTTs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Bower&#x27;s FFT: https:&#x2F;&#x2F;github.com&#x2F;Plonky3&#x2F;Plonky3&#x2F;blob&#x2F;c58f6aa11f6f578a7b9a9a596f51958f9cb8332f&#x2F;dft&#x2F;src&#x2F;radix_2_bowers.rs#L18&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-good-thomas-algorithm&quot;&gt;The Good-Thomas algorithm&lt;&#x2F;h2&gt;
&lt;p&gt;Starting again with a factorization &lt;span class=&quot;math math-inline&quot;&gt;n = a⋅b&lt;&#x2F;span&gt;, let&#x27;s look at all the bijections between &lt;span class=&quot;math math-inline&quot;&gt;[0,n)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;[0,a)×[0,b)&lt;&#x2F;span&gt; of the form&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
i &amp;amp;= \mod{i_a ⋅ e_a + i_b ⋅ e_b}_n \\
k &amp;amp;= \mod{k_a ⋅ e_a&amp;#39; + k_b ⋅ e_b&amp;#39;}_n \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;&#x27;s are parameters and &lt;span class=&quot;math math-inline&quot;&gt;\mod{-}_n&lt;&#x2F;span&gt; denotes reduction modulo &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. We can substitute this into the &lt;span class=&quot;math math-inline&quot;&gt;\ω_n&lt;&#x2F;span&gt; exponent again. Note that modular reduction is already implied by the root of unity.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ω_n^{\p{i_a ⋅ e_a + i_b ⋅ e_b}⋅\p{k_a ⋅ e_a&amp;#39; + k_b ⋅ e_b&amp;#39;}} =
\ω_n^{i_a ⋅ k_a ⋅ e_a ⋅ e_a&amp;#39;} ⋅
\ω_n^{i_b ⋅ k_b ⋅ e_b ⋅ e_b&amp;#39;}
\ω_n^{i_a ⋅ k_b ⋅ e_a ⋅ e_b&amp;#39;} ⋅
\ω_n^{i_b ⋅ k_a ⋅ e_b ⋅ e_a&amp;#39;} ⋅
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In Cooley-Tukey we used the solutions &lt;span class=&quot;math math-inline&quot;&gt;e_a = 1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;e_b = a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;e_a&amp;#39; = b&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;e_b&amp;#39; = 1&lt;&#x2F;span&gt;. This turned the first two roots into &lt;span class=&quot;math math-inline&quot;&gt;\ω_a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\ω_b&lt;&#x2F;span&gt; and got rid of the &lt;span class=&quot;math math-inline&quot;&gt;i_b⋅k_a&lt;&#x2F;span&gt; term. We where left with a &lt;span class=&quot;math math-inline&quot;&gt;i_a⋅k_b&lt;&#x2F;span&gt; term that turned into twiddle factors. Can we get rid of this term? The necessary conditions for this are&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mod{e_b ⋅ e_a&amp;#39;}_n &amp;amp;= 0 &amp;amp;\hspace{2em} \mod{e_a ⋅ e_b&amp;#39;}_n &amp;amp;= 0 \\
\mod{e_a ⋅ e_a&amp;#39;}_n &amp;amp;= b &amp;amp;\hspace{2em} \mod{e_b ⋅ e_b&amp;#39;}_n &amp;amp;= a
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;We also need some conditions to make sure the map is a bijection.&lt;&#x2F;summary&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1109&#x2F;TASSP.1977.1162938&quot;&gt;Bur77&lt;&#x2F;a&gt; it is shown that the map is a bijection iff&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\gcd(a, b) = 1&lt;&#x2F;span&gt; and
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\gcd(e_a, a) = \gcd(e_b, b) = 1&lt;&#x2F;span&gt; and at least one of
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;e_a = α ⋅ a&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;e_b = β ⋅ b&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\gcd(a, b) &amp;gt; 1&lt;&#x2F;span&gt; and either
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;e_a = α ⋅ a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;e_a ≠ β ⋅ b&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\gcd(α, a) = \gcd(e_b, b) = 1&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;e_a ≠ α ⋅ a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;e_a = β ⋅ b&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\gcd(e_a, a) = \gcd(β, b) = 1&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;details&gt;
&lt;p&gt;The simplest solution to this set of constraints is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
e_a &amp;amp;= b &amp;amp;\hspace{2em} a_b &amp;amp;= a \\
e_a&amp;#39; &amp;amp;= \mod{b^{-1}}_a⋅b &amp;amp;\hspace{2em} e_b&amp;#39; &amp;amp;= \mod{a^{-1}}_b⋅a
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The inverses only exist if &lt;span class=&quot;math math-inline&quot;&gt;\gcd(a,b)=1&lt;&#x2F;span&gt;, i.e. we have a factorization of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; into co-prime factors. It is shown in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1109&#x2F;TASSP.1977.1162938&quot;&gt;Bur77&lt;&#x2F;a&gt; and others that all solutions require a co-prime factorization. Proceeding as before we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_{\mod{k_a ⋅ e_a&amp;#39; + k_b ⋅ e_b&amp;#39;}_n} = \sum_{i_a∈[0,a)}
\p{\sum_{i_b∈[0,b)} x_{\mod{i_a ⋅ e_a + i_b ⋅ e_b}_n} ⋅
\ω_b^{i_b ⋅ k_b}} ⋅
\ω_a^{i_a ⋅ k_a}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We have a clean separation into two NTTs of size &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; without twiddle factors. The order of the two NTTs does not matter. This is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Prime-factor_FFT_algorithm&quot;&gt;Good-Thomas&lt;&#x2F;a&gt; or Prime Factor NTT algorithm. It can also be visualized as a matrix, but this time the input and output mapping is no longer a simple reinterpretation in row-major order but a more complex permutation.&lt;&#x2F;p&gt;
&lt;p&gt;Our optimal strategy is now to first use Good-Thomas recursively to break down &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; into co-prime factors. These factors of the form &lt;span class=&quot;math math-inline&quot;&gt;p^n&lt;&#x2F;span&gt; for some prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; can be further reduced using Cooley-Tukey which leaves us with prime-sized NTTs as base cases.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bluestein-algorithm&quot;&gt;Bluestein algorithm&lt;&#x2F;h2&gt;
&lt;p&gt;Start again with the NTT formula&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f_k = \sum_{i∈[0,n)} x_i ⋅ \ω_n^{i⋅k}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and substitute the identity&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
i⋅k = \frac{1}{2}⋅\p{i^2 + k^2 - (i - k)^2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;in the exponent to get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\ω_n^{i⋅k}
&amp;amp;= \ω_n^{\frac{1}{2}⋅\p{i^2 + k^2 - (i - k)^2}} \\
&amp;amp;= \ω_{2⋅n}^{i^2 + k^2 - (i - k)^2} \\
&amp;amp;= \ω_{2⋅n}^{i^2}⋅\ω_{2⋅n}^{k^2}⋅\ω_{2⋅n}^{-(i - k)^2} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We use the fact that &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^{\frac 12} = \ω_{2⋅n}&lt;&#x2F;span&gt; if &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}&lt;&#x2F;span&gt; exists. Substituting this back in the sum and moving factors around we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f_k &amp;amp;= \ω_{2⋅n}^{k^2}⋅\sum_{i∈[0,n)} \p{x_i ⋅ \ω_{2⋅n}^{i^2}} ⋅ \ω_{2⋅n}^{-(i - k)^2}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This formula has the shape&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f_k &amp;amp;= a_k ⋅ \sum_{i∈[0,n)} b_i ⋅ c_{i-k}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Which is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Convolution#Discrete_convolution&quot;&gt;convolution&lt;&#x2F;a&gt; between &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; followed by pointwise multiplication by &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a_i &amp;amp;= \ω_{2⋅n}^{i^2} &amp;amp;\hspace{2em}
b_i &amp;amp;= x_i ⋅ \ω_{2⋅n}^{i^2} &amp;amp;\hspace{2em}
c_i &amp;amp;= \ω_{2⋅n}^{-i^2} &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c_{i+n}
= \ω_{2⋅n}^{-\p{i+n}^2}
= \ω_{2⋅n}^{-i^2-n^2 - 2⋅i⋅n}
= \ω_{2⋅n}^{-i^2}⋅\ω_{2⋅n}^{-n^2}⋅\ω_{2⋅n}^{-2⋅i⋅n}
= c_i ⋅ \ω_{2}^{-n} = \p{-1}^n ⋅ a_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is even, the sequence &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; is cyclic, if &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is odd it is negacyclic.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;. The sign can be absorbed in &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}&lt;&#x2F;span&gt;. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hal.science&#x2F;hal-02070816&#x2F;document&quot;&gt;HH19&lt;&#x2F;a&gt; p 13.&lt;&#x2F;p&gt;
&lt;p&gt;This is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chirp_Z-transform#Bluestein.27s_algorithm&quot;&gt;Bluestein&#x27;s algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Pointwise multiply by &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}^{i^2}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Convolve with &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}^{-i^2}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Pointwise multiply by &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}^{i^2}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Can we use a field extension to add &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}&lt;&#x2F;span&gt; if it does not exist? i.e.
work in &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&#x2F;(X^2-\ω_n)&lt;&#x2F;span&gt;. Then substitute &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a_i &amp;amp;= X^{i^2}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;X^0, X^1, X^4, X^9, X^{16}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rader-s-ntt&quot;&gt;Rader&#x27;s NTT&lt;&#x2F;h2&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is prime then the non-zero numbers &lt;span class=&quot;math math-inline&quot;&gt;[1,n)&lt;&#x2F;span&gt; form a group under multiplication modulo &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. Pick a generator &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; for this group, then &lt;span class=&quot;math math-inline&quot;&gt;g^{-1}&lt;&#x2F;span&gt; is also a generator. We can now rewrite the non-zero indices as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
i &amp;amp;= \mod{g^{i&amp;#39;}}_n &amp;amp;\hspace{2em}
k = \mod{g^{-k&amp;#39;}}_n
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To use this we first split the zero indices out of the NTT equation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f_0 &amp;amp;= \sum_{i∈[0,n)} x_i &amp;amp;\hspace{2em}
f_i &amp;amp;= x_0 + \sum_{i∈[1,n)} x_i ⋅ \ω_n^{i⋅k}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and substitute our index map to get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f_{\mod{g^{-k&amp;#39;}}_n} = x_0 + \sum_{i&amp;#39;∈[1,n)} x_{\mod{g^{i&amp;#39;}}_n} ⋅ \ω_n^{g^{i&amp;#39;-k&amp;#39;}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The sum has the form &lt;span class=&quot;math math-inline&quot;&gt;\sum_{i∈[0,n-1)} a_{i} ⋅ b_{i-k}&lt;&#x2F;span&gt; which is a convolution of size &lt;span class=&quot;math math-inline&quot;&gt;n-1&lt;&#x2F;span&gt;. The &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; term is cyclic, so this is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Circular_convolution#Discrete_sequences&quot;&gt;cyclic convolution&lt;&#x2F;a&gt;. This method for computing NTTs is called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rader%27s_FFT_algorithm&quot;&gt;Rader&#x27;s algorithm&lt;&#x2F;a&gt;. Much like Good-Thomas, it uses primality and clever permutation to avoid twiddle factors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rader-winograd-ntt&quot;&gt;Rader-Winograd NTT&lt;&#x2F;h2&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;n = p^m&lt;&#x2F;span&gt; with odd prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; then the elements not a multiple of &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;, i.e. &lt;span class=&quot;math math-inline&quot;&gt;\mod{i}_p&amp;gt;0&lt;&#x2F;span&gt;, form a group of size &lt;span class=&quot;math math-inline&quot;&gt;p^m -p^{m-1}&lt;&#x2F;span&gt; elements for which we can find a generator &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;TODO&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;encyclopediaofmath.org&#x2F;wiki&#x2F;Winograd_Fourier_transform_algorithm&quot;&gt;https:&#x2F;&#x2F;encyclopediaofmath.org&#x2F;wiki&#x2F;Winograd_Fourier_transform_algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;binary-rader-winograd-ntt&quot;&gt;Binary Rader-Winograd NTT&lt;&#x2F;h2&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;n = 2^m&lt;&#x2F;span&gt; then the elements not a multiple of &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;, i.e. &lt;span class=&quot;math math-inline&quot;&gt;\mod{i}_p&amp;gt;0&lt;&#x2F;span&gt;, form a group of size &lt;span class=&quot;math math-inline&quot;&gt;p^m -p^{m-1}&lt;&#x2F;span&gt; elements for which we can find a generator &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cyclotomic-fast-fourier-transforms&quot;&gt;Cyclotomic Fast Fourier transforms&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cyclotomic_fast_Fourier_transform&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cyclotomic_fast_Fourier_transform&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bruun-s-ntt&quot;&gt;Bruun&#x27;s NTT&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bruun%27s_FFT_algorithm&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bruun%27s_FFT_algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;johnson-burrus-fast-fourier-transform&quot;&gt;Johnson–Burrus fast Fourier transform&lt;&#x2F;h2&gt;
&lt;p&gt;See [Bla10] 12.5. Generalization over Good-Thomas and Winograd nesting.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;summary-of-algorithms&quot;&gt;Summary of &lt;span class=&quot;math math-inline&quot;&gt;\NTT_n&lt;&#x2F;span&gt; algorithms&lt;&#x2F;h2&gt;
&lt;p&gt;All presented methods require the &lt;span class=&quot;math math-inline&quot;&gt;\ω_n&lt;&#x2F;span&gt; to exist and turn the &lt;span class=&quot;math math-inline&quot;&gt;\NTT_n&lt;&#x2F;span&gt; into a simpler sub-problem. Here &lt;span class=&quot;math math-inline&quot;&gt;\NTT&lt;&#x2F;span&gt; is a number theoretic transform, &lt;span class=&quot;math math-inline&quot;&gt;\CCV&lt;&#x2F;span&gt; is a cyclic convolution, &lt;span class=&quot;math math-inline&quot;&gt;\CCV^{-}&lt;&#x2F;span&gt; is a negacyclic convolution, &lt;span class=&quot;math math-inline&quot;&gt;\A&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\M&lt;&#x2F;span&gt; are additions and multiplications in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;\Ac&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\Mc&lt;&#x2F;span&gt; the same but by a constant.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Algorithm&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Requirements&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Sub problems&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;Direct&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;n^2⋅\Mc + n⋅\p{n-1}⋅\A&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;Cooley-Tukey&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;n= a⋅b&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;b⋅\NTT_a + a⋅\NTT_b + n⋅\Mc&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;Good-Thomas&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;n=a⋅b&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\gcd(a,b)=1&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;b⋅\NTT_a + a⋅\NTT_b&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;Bluestein&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}&lt;&#x2F;span&gt; exists&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;\CCV_n^{\p{-1}^n} + 2⋅n⋅\Mc&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;Rader&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; prime&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;\CCV_{n-1} + \p{2⋅n-1}⋅\A&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;Rader-Winograd&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;n=p^m&lt;&#x2F;span&gt;, odd prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;\CCV_{p^m - p^{m−1}} + \p{p^{m-1}+1}⋅\CCV_{p-1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;Binary Rader-Winograd&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;n=2^m&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;2⋅\CCV_{2^{m−2}}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Note: The &lt;span class=&quot;math math-inline&quot;&gt;\Mc&lt;&#x2F;span&gt; values are deceptive. Often these can be efficiently folded into sub problems, or they are special values in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; that are easier to compute. The &lt;span class=&quot;math math-inline&quot;&gt;\A&lt;&#x2F;span&gt;&#x27;s in Radercan also be folded into some of the&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;synthetic-roots-of-unity&quot;&gt;Synthetic roots of unity&lt;&#x2F;h2&gt;
&lt;p&gt;For a given finite field &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; a primitive &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th root of unity exists iff &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; divides &lt;span class=&quot;math math-inline&quot;&gt;q-1&lt;&#x2F;span&gt;. This also holds true for extension fields.&lt;&#x2F;p&gt;
&lt;p&gt;Suppose we want to use Bluesteins algorithm and we have &lt;span class=&quot;math math-inline&quot;&gt;\ω_n&lt;&#x2F;span&gt; but not the required &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n}&lt;&#x2F;span&gt;. We can work around this by taking the extension field &lt;span class=&quot;math math-inline&quot;&gt;\F_{q^2} = \F_q[X]&#x2F;(X^2 - \ω_n)&lt;&#x2F;span&gt; and using &lt;span class=&quot;math math-inline&quot;&gt;\ω_{2⋅n} = X&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In prime fields &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\mod{p}_4 = 3&lt;&#x2F;span&gt; the polynomial &lt;span class=&quot;math math-inline&quot;&gt;X^2+1&lt;&#x2F;span&gt; is irreducible and we can consider the field extension &lt;span class=&quot;math math-inline&quot;&gt;\F_{p^2} = \F_p[X]&#x2F;(X^2 + 1)&lt;&#x2F;span&gt;. We have &lt;span class=&quot;math math-inline&quot;&gt;q^2 - 1 = \p{q+1}⋅\p{q-1}&lt;&#x2F;span&gt;. So the new field must have a primitive root of order &lt;span class=&quot;math math-inline&quot;&gt;q+1&lt;&#x2F;span&gt;. [Hab23]&lt;&#x2F;p&gt;
&lt;p&gt;What if we want to do an NTT of size &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, but don&#x27;t have &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th roots of unity in the field? If out field is &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt; we have at most a 2-nd root of unity, &lt;span class=&quot;math math-inline&quot;&gt;-1&lt;&#x2F;span&gt;. If we want more we need an extension &lt;span class=&quot;math math-inline&quot;&gt;\R&#x2F;(X^2 + 1)&lt;&#x2F;span&gt;. More commonly known as the complex numbers &lt;span class=&quot;math math-inline&quot;&gt;\mathbb{C}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\i^2 = -1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ω_n = \mathrm{e}^{\frac{2⋅\mathrm{π}⋅\mathrm{i}}{n}} = 1 + \frac{2⋅\mathrm{π}}{n}⋅\i
-\frac{1}{2}⋅\p{\frac{2⋅\mathrm{π}}{n}}^2
-\frac{1}{6}⋅\p{\frac{2⋅\mathrm{π}}{n}}^3⋅\i
+\cdots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;By definition &lt;span class=&quot;math math-inline&quot;&gt;\ω_n^n = 1&lt;&#x2F;span&gt;, so to synthetically construct one we consider &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&#x2F;\p{X^n - 1}&lt;&#x2F;span&gt;. But &lt;span class=&quot;math math-inline&quot;&gt;X^n-1&lt;&#x2F;span&gt; is not necessarily ireducable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ntt-by-complex-field-extension&quot;&gt;NTT by Complex Field Extension&lt;&#x2F;h3&gt;
&lt;p&gt;If the &lt;span class=&quot;math math-inline&quot;&gt;X^2 + 1&lt;&#x2F;span&gt; is an irreducable polynomial in &lt;span class=&quot;math math-inline&quot;&gt;𝔽_p&lt;&#x2F;span&gt; then we can define the complex extension field of &lt;span class=&quot;math math-inline&quot;&gt;𝔽_p&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ℂ(𝔽_p) = 𝔽_p[X]&#x2F;(X^2 + 1)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that the polynomial is irreducable exactly when &lt;span class=&quot;math math-inline&quot;&gt;\mod{p}_4 = 3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The polynomials &lt;span class=&quot;math math-inline&quot;&gt;a + b⋅X&lt;&#x2F;span&gt; in this extension field have the property that &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; acts as &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{-1}&lt;&#x2F;span&gt;. So we will adopt the complex number notation &lt;span class=&quot;math math-inline&quot;&gt;\i&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; and write &lt;span class=&quot;math math-inline&quot;&gt;a + b ⋅ i&lt;&#x2F;span&gt; instead.&lt;&#x2F;p&gt;
&lt;p&gt;For a finite field &lt;span class=&quot;math math-inline&quot;&gt;\F_q&lt;&#x2F;span&gt; Roots of unity exist for every divisor of &lt;span class=&quot;math math-inline&quot;&gt;q-1&lt;&#x2F;span&gt;. In a quadratic field extension &lt;span class=&quot;math math-inline&quot;&gt;q-1=p^2-1 = \p{p-1}⋅\p{p+1}&lt;&#x2F;span&gt;. So the we have all the original divisors, plus what&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ntt-by-elliptic-curves&quot;&gt;NTT by Elliptic Curves&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;solvable.group&#x2F;posts&#x2F;ecfft&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;Finding curves &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1403.7887&quot;&gt;SS14&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Find an elliptic curve over &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; with&lt;&#x2F;p&gt;
&lt;p&gt;Take a subgroup of the elliptic curve of desired size &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. Take as &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; coordinates the &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; coordinates of those points. We will interpolate a polynomial on those coordinates.&lt;&#x2F;p&gt;
&lt;p&gt;Next we&#x27;ll need an isogeny to half the elliptic curve size. An isogeny is a surjective morphism between two elliptic curves. If the curves are of the form &lt;span class=&quot;math math-inline&quot;&gt;y^2 = f(x)&lt;&#x2F;span&gt; they can always be written in the standard affine form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ψ(x,y) = \p{\frac{u(x)}{v(x)}, \frac{s(x)}{t(x)}⋅y}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;u,v&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;s,t&lt;&#x2F;span&gt; are coprime.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;the-groups&quot;&gt;The groups &lt;span class=&quot;math math-inline&quot;&gt;\Z_n^\times&lt;&#x2F;span&gt;.&lt;&#x2F;h2&gt;
&lt;p&gt;The multiplicative group of numbers modulo &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\Z_n^\times&lt;&#x2F;span&gt;, is cyclic iff &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;1,2,4,p^k,2⋅p^k&lt;&#x2F;span&gt; for odd prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;. In this case &lt;span class=&quot;math math-inline&quot;&gt;\Z_n^\times ≅ \mathrm{C}_{\mathrm{φ}(n)}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{φ}&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Euler%27s_totient_function&quot;&gt;Euleur&#x27;s totient function&lt;&#x2F;a&gt;. For powers of two &lt;span class=&quot;math math-inline&quot;&gt;\Z_{2^k}^\times ≅ \mathrm{C}_{\mathrm{φ}(n)}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-chinese-remainder-theorem&quot;&gt;The Chinese Remainder Theorem&lt;&#x2F;h2&gt;
&lt;p&gt;Let I and J be ideals of a ring R. Remainder arithmetic modulo I and J means mapping R&#x2F;IJ to (R&#x2F;I) × (R&#x2F;J) by z 7 → (z mod I, z mod J).&lt;&#x2F;p&gt;
&lt;p&gt;The Chinese remainder theorem states that R&#x2F;IJ is isomorphic to (R&#x2F;I)×(R&#x2F;J)
if I and J are coprime, i.e., if there exist u ∈ I and v ∈ J with u + v = 1. The
inverse map is (x, y) 7 → vx + uy.&lt;&#x2F;p&gt;
&lt;p&gt;Applied to a modular basis of polynomials &lt;span class=&quot;math math-inline&quot;&gt;X - x_i&lt;&#x2F;span&gt; this is called evaluation and interpolation.&lt;&#x2F;p&gt;
&lt;p&gt;Applied to a modular basis of polynomials &lt;span class=&quot;math math-inline&quot;&gt;X - \ω_n^i&lt;&#x2F;span&gt; this is the &lt;span class=&quot;math math-inline&quot;&gt;\NTT&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Karatsuba&#x27;s trick is &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&#x2F;(X^2 - X) ≅ \F[X]&#x2F;(X - 1)×\F[X]&#x2F;X&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;R. Tolimieri, M. An, C. Lu, &quot;Algorithms for discrete Fourier transform and convolution&quot;, Springer (1989) pp. 1997.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;D.P. Kolba, T.W. Parks, &quot;Prime factor FFT algorithm using high speed convolution&quot; IEEE Trans. Acoustics, Speech and Signal Processing, ASSP–25 (1977) pp. 281–294&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Blahut (2010). &quot;Fast algorithms for signal processing&quot;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;C. S. Burrus (2012). “Fast Fourier Transforms”.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eng.libretexts.org&#x2F;Bookshelves&#x2F;Electrical_Engineering&#x2F;Signal_Processing_and_Modeling&#x2F;Fast_Fourier_Transforms_(Burrus)&quot;&gt;https:&#x2F;&#x2F;eng.libretexts.org&#x2F;Bookshelves&#x2F;Electrical_Engineering&#x2F;Signal_Processing_and_Modeling&#x2F;Fast_Fourier_Transforms_(Burrus)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;[46,47] C. S. Burrus (1977). “Index mappings for multidimensional formulation of the DFT and convolution.”
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1109&#x2F;TASSP.1977.1162938&quot;&gt;https:&#x2F;&#x2F;doi.org&#x2F;10.1109&#x2F;TASSP.1977.1162938&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;citeseerx.ist.psu.edu&#x2F;document?repid=rep1&amp;amp;type=pdf&amp;amp;doi=12550db10683005f3f612f9b7c736f52a30279fe&quot;&gt;https:&#x2F;&#x2F;citeseerx.ist.psu.edu&#x2F;document?repid=rep1&amp;amp;type=pdf&amp;amp;doi=12550db10683005f3f612f9b7c736f52a30279fe&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cr.yp.to&#x2F;lineartime&#x2F;multapps-20080515.pdf&quot;&gt;https:&#x2F;&#x2F;cr.yp.to&#x2F;lineartime&#x2F;multapps-20080515.pdf&lt;&#x2F;a&gt; Mostly about fast multiplication and related algorithms.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cr.yp.to&#x2F;arith&#x2F;tangentfft-20070919.pdf&quot;&gt;https:&#x2F;&#x2F;cr.yp.to&#x2F;arith&#x2F;tangentfft-20070919.pdf&lt;&#x2F;a&gt; The Tangent FFT. Goes further than split-Radix. Not sure how it generalizes to fields.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cr.yp.to&#x2F;papers&#x2F;m3-20010811-retypeset-20220327.pdf&quot;&gt;https:&#x2F;&#x2F;cr.yp.to&#x2F;papers&#x2F;m3-20010811-retypeset-20220327.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Multiplicative_group_of_integers_modulo_n&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Multiplicative_group_of_integers_modulo_n&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;. Nussbaumer–Quandalle permutation algorithm. See [Bla10] p. 411.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;. Additive NTT https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1404.3458&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Goldilocks Reduction</title>
        <published>2023-01-17T00:00:00+00:00</published>
        <updated>2023-01-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/gold-reduce/"/>
        <id>https://2π.com/23/gold-reduce/</id>
        
        <content type="html" xml:base="https://2π.com/23/gold-reduce/">&lt;h1 id=&quot;goldilocks-reduction&quot;&gt;Goldilocks Reduction&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\F{\mathbb{F}}
\gdef\mod#1{\delim[{#1}]}
\gdef\floor#1{\delim\lfloor{#1}\rfloor}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The goal is to compute &lt;span class=&quot;math math-inline&quot;&gt;\mod{a⋅b}_p&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;p = 2^{64} - 2^{32} + 1&lt;&#x2F;span&gt; is the &lt;a href=&quot;&#x2F;22&#x2F;goldilocks&quot;&gt;Goldilocks prime&lt;&#x2F;a&gt; and &lt;span class=&quot;math math-inline&quot;&gt;a,b∈[0,p)&lt;&#x2F;span&gt; (or some suitable alternative for multiplication in &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt;). I&#x27;ve benchmarked existing methods and present a new method with variants &lt;code&gt;A&lt;&#x2F;code&gt; and &lt;code&gt;B&lt;&#x2F;code&gt;. Unfortunately these don&#x27;t work in all cases.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;23&#x2F;gold-reduce&#x2F;reduce.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{llllc}
                &amp;amp; \text{Algorithm}  &amp;amp; \text{Input} &amp;amp; \text{Output} &amp;amp; \text{Portable} \\[0.7em]
\texttt{Naïve}  &amp;amp; \text{Knuth}      &amp;amp; [0,2^{128})  &amp;amp; [0,p)         &amp;amp; ✓ \\[0.4em]
\texttt{PZT22}  &amp;amp; \text{Direct}     &amp;amp; [0,2^{128})  &amp;amp; [0,2^{64})    &amp;amp;   \\[0.4em]
\texttt{Redc}   &amp;amp; \text{Montgomery} &amp;amp; [0,2^{64}⋅p) &amp;amp; [0,p)⋅2^{-64}  &amp;amp; ✓ \\[0.4em]
\texttt{Por22}  &amp;amp; \text{Montgomery} &amp;amp; [0,2^{64}⋅p) &amp;amp; [0,p)⋅2^{-64}  &amp;amp; ✓ \\[0.4em]
\texttt{B}      &amp;amp; \text{Barrett}    &amp;amp; [0,2^{128})  &amp;amp; [0,2^{64})    &amp;amp;   \\[0.4em]
\texttt{A}      &amp;amp; \text{Barrett}    &amp;amp; [0,2^{64}⋅p) &amp;amp; [0,2^{64})    &amp;amp; ✓ \\[0.4em]
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The benchmark measures the number of multiply-reduce operations-per-second (Ops) on a single 3.2 GHz &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dougallj.github.io&#x2F;applecpu&#x2F;firestorm.html&quot;&gt;M1 Max Firestorm&lt;&#x2F;a&gt; core with &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt;-way &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Instruction-level_parallelism&quot;&gt;instruction-level parallelism&lt;&#x2F;a&gt; for &lt;span class=&quot;math math-inline&quot;&gt;N∈\set{1,2,4,8,16}&lt;&#x2F;span&gt;. The measured code is&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;iters&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;N&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_reduce&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where &lt;code&gt;N&lt;&#x2F;code&gt; is compile time constant and  &lt;code&gt;a&lt;&#x2F;code&gt;, &lt;code&gt;b&lt;&#x2F;code&gt; are &lt;code&gt;[u64; N]&lt;&#x2F;code&gt; are initialized with random elements from &lt;span class=&quot;math math-inline&quot;&gt;[0,p)&lt;&#x2F;span&gt;. I confirmed that the compiler inlines and unrolls the inner loop. The outer loop iterates a variable number of times and is used by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;criterion&#x2F;latest&#x2F;criterion&#x2F;struct.Bencher.html#method.iter_custom&quot;&gt;Criterion&lt;&#x2F;a&gt; to measure the code.&lt;&#x2F;p&gt;
&lt;p&gt;Benchmarking these functions is challenging because they take only a few nanoseconds. Some variants have branches so we need to feed them &#x27;fresh&#x27; numbers each time to make branch prediction realistic. we also need to create data dependencies to force at most &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt;-way parallelism. There is likely a non-trivial measurement overhead, but this should be the same for all methods.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;methods&quot;&gt;Methods&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;naive-approach&quot;&gt;Naïve approach&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s do the dumb thing first:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; MODULUS&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0xffff_ffff_0000_0001&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_naive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;MODULUS&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The naïve implementation looks simple, but the generated instructions are not. There is no suitable native instruction so the compiler (LLVM) generates a call to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;llvm&#x2F;llvm-project&#x2F;blob&#x2F;9bdfd7c8db2066e5b50b9599248660bdf8eda7f0&#x2F;compiler-rt&#x2F;lib&#x2F;builtins&#x2F;udivmodti4.c&quot;&gt;&lt;code&gt;__udivmodti4&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; compiler built-in function, which implements Knuth division. It is slow because it is generic and does no preprocessing on &lt;code&gt;MODULUS&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For 64-bit reductions there is the &lt;code&gt;UDIV&lt;&#x2F;code&gt; instruction, but this instruction is funny in that it takes either 7, 8 or 9 cycles. It is the only one with variable cycle count! So even the silicon is doing some sort of loop. Fortunately for 64-bit LLVM is smarter and it turns a 64-bit &lt;code&gt;a % MODULUS&lt;&#x2F;code&gt; into a conditional subtraction. But as noted by PZT22, it&#x27;s actually faster to use a branch here.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;direct-reduction&quot;&gt;Direct reduction&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mod{x}_p = \mod{x_2⋅2^{96} + x_1⋅2^{64} + x_0}_p =
\mod{x_2 ⋅ \p{-1} + x_1 ⋅ \p{2^{32} - 1} + x_0}_p
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This method expands the number in base &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt; and uses the particularly simple reductions of powers of this base in Goldilocks to reduce the number. This is the method in  &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cp4space.hatsya.com&#x2F;2021&#x2F;09&#x2F;01&#x2F;an-efficient-prime-for-number-theoretic-transforms&#x2F;&quot;&gt;Gou21&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&quot;&gt;Plonky2&lt;&#x2F;a&gt; uses a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&#x2F;blob&#x2F;3a6d693f3ffe5aa1636e0066a4ea4885a10b5cdf&#x2F;field&#x2F;src&#x2F;goldilocks_field.rs#L340-L356&quot;&gt;heavily optimized version&lt;&#x2F;a&gt; presented in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&#x2F;blob&#x2F;main&#x2F;plonky2&#x2F;plonky2.pdf&quot;&gt;PZT22&lt;&#x2F;a&gt; that reduces to &lt;span class=&quot;math math-inline&quot;&gt;[0, 2^{64})&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_pzt22&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    const&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; EPSILON&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x_lo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x_hi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x_hi_hi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x_hi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x_hi_lo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x_hi&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; EPSILON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; borrow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x_lo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;overflowing_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;x_hi_hi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; borrow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        branch_hint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        t0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; EPSILON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x_hi_lo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; EPSILON&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;res_wrapped&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; carry&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;overflowing_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;t1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    res_wrapped&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt; EPSILON&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;carry&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where &lt;code&gt;branch_hint()&lt;&#x2F;code&gt; is an empty volatile function forcing the compile to use a branch instead of conditional instructions. Plonky2 has another &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&#x2F;blob&#x2F;3a6d693f3ffe5aa1636e0066a4ea4885a10b5cdf&#x2F;field&#x2F;src&#x2F;goldilocks_field.rs#L300-L330&quot;&gt;clever trick&lt;&#x2F;a&gt; in x86_64. This does not translate directly to Aarch64 because the carry flag behaviour is different, but we can achieve the same using &lt;code&gt;csetm w9, cs&lt;&#x2F;code&gt;. To use it replace the last two lines with this assembly:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        adds x8, {t0}, {t1}    ; x8 = t0 + t1   (setting carry flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        csetm w9, cs           ; x9 = if carry { 0xffff_ffff } else { 0 }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        add {result}, x9, x8   ; result = x8 + x9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To quantify the impact of the &lt;code&gt;branch&lt;&#x2F;code&gt; and &lt;code&gt;cset&lt;&#x2F;code&gt; tricks I measured all combinations for all the batch sizes. The optimum appears to be both tricks, except for &lt;span class=&quot;math math-inline&quot;&gt;N=16&lt;&#x2F;span&gt; where not doing tricks is beneficial.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{lrrrrr}
                      &amp;amp; N\!=\!1 &amp;amp; N\!=\!2 &amp;amp; N\!=\!4 &amp;amp; N\!=\!8  &amp;amp; N\!=\!16 \\[0.4em]
\texttt{none}         &amp;amp; 297 &amp;amp; 538 &amp;amp; 854 &amp;amp; 1152 &amp;amp; 1354 \\[0.4em]
\texttt{branch}       &amp;amp; 336 &amp;amp; 596 &amp;amp; 965 &amp;amp; 1303 &amp;amp; 1209 \\[0.4em]
\texttt{csetm}        &amp;amp; 297 &amp;amp; 539 &amp;amp; 851 &amp;amp; 1141 &amp;amp; 1052 \\[0.4em]
\texttt{branch+csetm} &amp;amp; 338 &amp;amp; 608 &amp;amp; 1005 &amp;amp; 1394 &amp;amp; 1209 \\[0.4em]
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;montgomery-reduction&quot;&gt;Montgomery reduction&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mod{\frac{x}{2^{64}}}_p &amp;amp;=
\frac{x + m ⋅ p}{2^{64}} &amp;amp;\hspace{2em}
m &amp;amp;= \mod{- x ⋅ p^{-1}}_{2^{64}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In Montgomery reduction we add a multiple &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; of the modulus to create an exact multiple of &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt;.  This is efficient to implement because we pre-compute &lt;span class=&quot;math math-inline&quot;&gt;\mod{-p^{-1}}_{2^{64}}&lt;&#x2F;span&gt; and do math modulo &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt;. It&#x27;s main downside is that we are computing &lt;span class=&quot;math math-inline&quot;&gt;\mod{\frac{x}{2^{64}}}_p&lt;&#x2F;span&gt; instead of &lt;span class=&quot;math math-inline&quot;&gt;\mod{x}_p&lt;&#x2F;span&gt;. This is (usually) less of a problem that it might seem because we can pre-multiply our numbers by a factor of &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt; to compensate. For Goldilocks it unfortunately interferes with the nice bit-shift roots of unity. The method works for inputs in the range &lt;span class=&quot;math math-inline&quot;&gt;[0, 2^{64}⋅p)&lt;&#x2F;span&gt; and reduces to &lt;span class=&quot;math math-inline&quot;&gt;[0,p)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;facebook&#x2F;winterfell&quot;&gt;Winterfell&lt;&#x2F;a&gt; uses &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Montgomery_modular_multiplication&quot;&gt;Montgomery reduction&lt;&#x2F;a&gt; and has two implementations of the REDC algorithm, a relatively &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;facebook&#x2F;winterfell&#x2F;blob&#x2F;d0f4373da34569dc39fe8b978e785ebd83bdbeb5&#x2F;math&#x2F;src&#x2F;field&#x2F;f64&#x2F;mod.rs#L561-L574&quot;&gt;straightforward one&lt;&#x2F;a&gt; and a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;facebook&#x2F;winterfell&#x2F;blob&#x2F;d0f4373da34569dc39fe8b978e785ebd83bdbeb5&#x2F;math&#x2F;src&#x2F;field&#x2F;f64&#x2F;mod.rs#L576-L588&quot;&gt;very optimized one&lt;&#x2F;a&gt; due to Thomas Pornin (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;274.pdf&quot;&gt;Por22&lt;&#x2F;a&gt; section 5.1):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_por22&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;overflowing_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;overflowing_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This compiles down to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mul x8, x1, x0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    umulh x9, x1, x0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    adds x8, x8, x8, lsl #32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cset w10, hs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sub x8, x8, x8, lsr #32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sub x8, x8, x10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    subs x8, x9, x8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    mov x9, #-4294967295&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    csel x9, x9, xzr, lo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    add x0, x8, x9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;An interesting basis for Montgomery reduction is &lt;span class=&quot;math math-inline&quot;&gt;2^{192}&lt;&#x2F;span&gt; because &lt;span class=&quot;math math-inline&quot;&gt;\mod{2^{192}}_p = 1&lt;&#x2F;span&gt; so there would get a plain reduction method without a transform on the arguments. It&#x27;s also interesting to do a multi-precision Montgomery reduction in base &lt;span class=&quot;math math-inline&quot;&gt;b = 2^{32}&lt;&#x2F;span&gt; because &lt;span class=&quot;math math-inline&quot;&gt;\mod{-p^{-1}}_{b} = -1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p = [1, -1]&lt;&#x2F;span&gt;. We could even combine both ideas.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;barrett-reduction&quot;&gt;Barrett reduction&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mod{x}_p &amp;amp;= x - q ⋅ p  &amp;amp;\hspace{2em} q &amp;amp;= \floor{\frac{x}{p}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where we approximate &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\hat{q}&lt;&#x2F;span&gt; and do a small number of final additions&#x2F;subtractions of &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; to make it exact. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cacr.uwaterloo.ca&#x2F;hac&#x2F;&quot;&gt;Handbook of Applied Cryptography&lt;&#x2F;a&gt; algorithm 14.42 the approximation taken is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\hat{q} &amp;amp;= \floor{\frac{x ⋅ μ}{2^{128}}} &amp;amp;\hspace{2em} μ &amp;amp;= \floor{\frac{2^{128}}{p}} = 2^{64} + 2^{32} - 1
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This approximates &lt;span class=&quot;math math-inline&quot;&gt;\hat{q} ≤ q ≤ \hat{q} + 2&lt;&#x2F;span&gt; so at most two final subtractions are required to reduce the result to &lt;span class=&quot;math math-inline&quot;&gt;[0,p)&lt;&#x2F;span&gt;. This method is awkward in practice because it requires 128-bit multiplications.&lt;&#x2F;p&gt;
&lt;p&gt;We can do better! Starting with the exact formula and writing it in base &lt;span class=&quot;math math-inline&quot;&gt;b=2^{32}&lt;&#x2F;span&gt; we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
q = \floor{\frac{x_3 ⋅ b^3 + x_2 ⋅ b^2 + x_1 ⋅ b + x_0}{b^2 - b + 1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;we can use polynomial division in &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; to split off the integer part&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
q = x_3⋅b + x_2 + x_3 + \floor{\frac{\p{x_1 + x_2} ⋅ b + x_0 - x_2 - x_3}{b^2 - b + 1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This suggest the approximation &lt;span class=&quot;math math-inline&quot;&gt;\hat{q} = x_3⋅b + x_2 + x_3&lt;&#x2F;span&gt;. It can be shown that the remaining fraction is &lt;span class=&quot;math math-inline&quot;&gt;&amp;lt;3&lt;&#x2F;span&gt; so the approximation error is at most &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;. This is as tight as the above method but without the 128-bit multiplications.&lt;&#x2F;p&gt;
&lt;p&gt;But wait, there&#x27;s more! We can continue the polynomial division and get a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.wolframalpha.com&#x2F;input?i=%28x_3+*+b%5E3+%2B+x_2+*+b%5E2+%2B+x_1+*+b+%2B+x_0%29+%2F+%28b%5E2+-+b+%2B+1%29+Series+expansion+at+b%3D%E2%88%9E&quot;&gt;series expansion&lt;&#x2F;a&gt; in &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
q = x_3⋅b + x_2 + x_3 + \floor{\frac{x_1 + x_2}{b} + \frac{x_0 + x_1 - x_3}{b^2} + ⋯}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Looking at the sequence we can see that the first term is in the range &lt;span class=&quot;math math-inline&quot;&gt;[0,2)&lt;&#x2F;span&gt; and the remaining terms are all smaller than &lt;span class=&quot;math math-inline&quot;&gt;b^{-1}&lt;&#x2F;span&gt;. This suggests we take out the first term to improve our estimate of &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{q} = x_3⋅b + x_2 + x_3 + \floor{\frac{x_1 + x_2}{b}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is easy to verify that &lt;span class=&quot;math math-inline&quot;&gt;\hat{q} ≤ q + 1&lt;&#x2F;span&gt; so we have at most one reduction remaining. But this approximation satisfies the stronger bound &lt;span class=&quot;math math-inline&quot;&gt;x - \hat{q} ⋅ p &amp;lt; 2^{64}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Unfortunately it does not satisfy &lt;span class=&quot;math math-inline&quot;&gt;\hat{q} ≤ q&lt;&#x2F;span&gt;!&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;overflowing_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wrapping_sub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    cmn x8, x9, lsl #32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    lsr x10, x9, #32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    adc x9, x10, x9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sub x8, x8, x9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    add x0, x8, x9, lsl #32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{q}⋅b^2 = x_3⋅b^3 + x_2⋅b^2 + x_3⋅b^2 + x_1⋅ b + x_2⋅b + x_0 + x_1 - x_3
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{q}⋅b^2 = x_3⋅b^3 + x_2⋅b^2 + x_3⋅b^2 + x_1⋅ b + x_2⋅b + x_0 + x_1 - x_3
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This suggests two orthogonal modifications we can make. We can do an overflow check on &lt;code&gt;q&lt;&#x2F;code&gt; and handle all 128-bit inputs and&#x2F;or we can add a final reduction step to bring the result in &lt;span class=&quot;math math-inline&quot;&gt;[0,p)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-entity z-name z-type z-numeric z-rust&quot;&gt; as u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    unsafe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt; core&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt;arch&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-macro z-rust&quot;&gt;asm!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        cmn  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, lsl #32       ; carry flag from x0 + x1 &amp;lt;&amp;lt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        lsr  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, #32           ; q = x1 &amp;gt;&amp;gt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        adcs &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;          ; q += x1 + carry (and set carry flag)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        add  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, lsl #32  ; r = x0 + q &amp;lt;&amp;lt; 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        sub  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;           ; r -= q&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        b.cc 1f                        ; branch if q did not overflow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        mov  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q:w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;, #-1                ; q&amp;#39; = 0xffff_ffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        add  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;,  &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;           ; r += q&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;        1:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; _&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; lateout&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;reg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        options&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;pure&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; nomem&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; nostack&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    )}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;going-further&quot;&gt;Going further&lt;&#x2F;h2&gt;
&lt;p&gt;A theoretical limit to throughput is the ability to compute the 128-bit product. On an M1 Max this takes a &lt;code&gt;mul&lt;&#x2F;code&gt; and &lt;code&gt;umulh&lt;&#x2F;code&gt; instruction. A single &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dougallj.github.io&#x2F;applecpu&#x2F;firestorm-int.html&quot;&gt;Firestorm core&lt;&#x2F;a&gt; has two multiply units with a throughput of one cycle so a 128-bit product can be computed each cycle (the instructions are not fused). At 3.2 GHz this means a limit of 3.2 GE&#x2F;s per core. The presented methods reach 1.7 GE&#x2F;s per core.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Do vector instruction provide a better alternative to compute the 128-bit product? See for example the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&#x2F;blob&#x2F;3a6d693f3ffe5aa1636e0066a4ea4885a10b5cdf&#x2F;field&#x2F;src&#x2F;arch&#x2F;x86_64&#x2F;avx512_goldilocks_field.rs#L293-L331&quot;&gt;AVX512&lt;&#x2F;a&gt; implementation from Polygon Zero.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;appendix&quot;&gt;Appendix&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;proof-of&quot;&gt;Proof of &lt;span class=&quot;math math-inline&quot;&gt;x - \hat{q}⋅p &amp;lt; 2^{64}&lt;&#x2F;span&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;x ∈ [0, 2^{128})&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;p = 2^{64} - 2^{32} + 1&lt;&#x2F;span&gt;, write &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; in base &lt;span class=&quot;math math-inline&quot;&gt;b=2^{32}&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;x = x_3 ⋅ b^3 + x_2 ⋅ b^2 + x_1 ⋅ b + x_0&lt;&#x2F;span&gt; and define &lt;span class=&quot;math math-inline&quot;&gt;\hat{q} = x_3⋅b + x_2 + x_3 + \floor{\frac{x_1 + x_2}{b}}&lt;&#x2F;span&gt;. Now proof that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x - \hat{q}⋅p &amp;lt; 2^{64}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Start by expanding everything on the left hand side in base &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\begin{aligned} &amp;amp;x_3 ⋅ b^3 + x_2 ⋅ b^2 \\&amp;amp;+ x_1 ⋅ b + x_0 \end{aligned}}
-\p{x_3⋅b + x_2 + x_3 + \floor{\frac{x_1 + x_2}{b}}} ⋅ \p{b^2 - b + 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Expanding the terms…&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_3 ⋅ b^3 + x_2 ⋅ b^2 + x_1 ⋅ b + x_0 \\
-x_3 ⋅ b ⋅ \p{b^2 - b + 1} \\
-x_2 ⋅ \p{b^2 - b + 1} \\
-x_3 ⋅ \p{b^2 - b + 1} \\
-\floor{\frac{x_1 + x_2}{b}} ⋅ \p{b^2 - b + 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;…&lt;em&gt;all&lt;&#x2F;em&gt; the terms…&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_3 ⋅ b^3 + x_2 ⋅ b^2 + x_1 ⋅ b + x_0 \\
-x_3 ⋅ b^3 + x_3 ⋅ b^2 - x_3 ⋅ b \\
-x_2 ⋅ b^2 + x_2 ⋅ b - x_2 \\
-x_3 ⋅ b^2 + x_3 ⋅ b - x_3 \\
-\floor{\frac{x_1 + x_2}{b}} ⋅ \p{b^2 - b + 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;… leads to a lot of cancellations:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\cancel{x_3 ⋅ b^3} + \cancel{x_2 ⋅ b^2} + x_1 ⋅ b + x_0 \\
-\cancel{x_3 ⋅ b^3} + \cancel{x_3 ⋅ b^2} - \cancel{x_3 ⋅ b} \\
-\cancel{x_2 ⋅ b^2} + x_2 ⋅ b - x_2 \\
-\cancel{x_3 ⋅ b^2} + \cancel{x_3 ⋅ b} - x_3 \\
-\floor{\frac{x_1 + x_2}{b}} ⋅ \p{b^2 - b + 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which leaves us with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_1 ⋅ b + x_0 +x_2 ⋅ b - x_2 -x_3 \\-\floor{\frac{x_1 + x_2}{b}} ⋅ \p{b^2 - b + 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To deal with that integer division, recall the identity with modular reduction&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mod{x_1 + x_2}_b = \p{x_1 + x_2} - \floor{\frac{x_1 + x_2}{b}} ⋅ b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So that we can rewrite the integer division as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\floor{\frac{x_1 + x_2}{b}} ⋅ b = \p{x_1 + x_2} - \mod{x_1 + x_2}_b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which results in&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_1 ⋅ b + x_0 +x_2 ⋅ b - x_2 -x_3\\
-\p{\p{x_1 + x_2} - \mod{x_1 + x_2}_b}⋅\p{b - 1}-\floor{\frac{x_1 + x_2}{b}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Expanding the terms…&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_1 ⋅ b + x_0 +x_2 ⋅ b - x_2 -x_3\\
-\p{x_1 + x_2}⋅\p{b - 1} + \mod{x_1 + x_2}_b⋅\p{b - 1}-\floor{\frac{x_1 + x_2}{b}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;…expanding…&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_1 ⋅ b + x_0 +x_2 ⋅ b - x_2 -x_3\\
-x_1⋅b - x_2⋅b + x_1 + x_2 + \mod{x_1 + x_2}_b⋅\p{b - 1}-\floor{\frac{x_1 + x_2}{b}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;…and canceling&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\cancel{x_1 ⋅ b} + x_0 + \cancel{x_2 ⋅ b} - \cancel{x_2} -x_3\\
-\cancel{x_1⋅b} - \cancel{x_2⋅b} + x_1 + \cancel{x_2} + \mod{x_1 + x_2}_b⋅\p{b - 1}-\floor{\frac{x_1 + x_2}{b}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;leaves us with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_0 - x_3 + x_1 + \mod{x_1 + x_2}_b⋅\p{b - 1}-\floor{\frac{x_1 + x_2}{b}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This gives us the identity&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x - \hat{q}⋅p = x_0 - x_3 + x_1 + \mod{x_1 + x_2}_b⋅\p{b - 1}-\floor{\frac{x_1 + x_2}{b}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To maximize this we set &lt;span class=&quot;math math-inline&quot;&gt;x_2 = x_3 = 0&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;x_0 = x_1 = b - 1&lt;&#x2F;span&gt;. This is the global maximum because maximizes every positive term while setting every negative term to zero&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{b - 1} - 0 + \p{b - 1} + \mod{\p{b - 1} + 0}_b⋅\p{b - 1}-\floor{\frac{\p{b - 1} + 0}{b}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{b - 1} + \p{b - 1} + \p{b - 1}⋅\p{b - 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{b - 1}^2 + 2⋅\p{b - 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
b^2 - 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;proof-of-1&quot;&gt;Proof of &lt;span class=&quot;math math-inline&quot;&gt;\hat{q} ≤ q&lt;&#x2F;span&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Not true. Take &lt;span class=&quot;math math-inline&quot;&gt;x_3 &amp;gt; 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;x_0 = x_1 = x_2 = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Polynomial Commitment Benchmark</title>
        <published>2023-01-04T00:00:00+00:00</published>
        <updated>2023-01-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/23/pc-bench/"/>
        <id>https://2π.com/23/pc-bench/</id>
        
        <content type="html" xml:base="https://2π.com/23/pc-bench/">&lt;h1 id=&quot;polynomial-commitment-benchmark&quot;&gt;Polynomial Commitment Benchmark&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\Commit{\mathsf{Commit}}
\gdef\ceil#1{\left\lceil{#1}\right\rceil}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is hard to compare complete proof systems because they have wildly different designs and implementing a balanced suite of benchmarks that shows what each is capable of is an enormous amount of work.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
🍎 ≟ 🍏
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But all proof systems use some form of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;scroll.io&#x2F;blog&#x2F;kzg&quot;&gt;polynomial commitment&lt;&#x2F;a&gt;. These take a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec y ∈ \F^n&lt;&#x2F;span&gt; representing a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P(X) ∈ \F[X^{&amp;lt;n}]&lt;&#x2F;span&gt; evaluated on some domain (usually typically of unity) and turn it into a small commitment object, a process called &lt;span class=&quot;math math-inline&quot;&gt;\Commit&lt;&#x2F;span&gt;. I will ignore the &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Setup}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Open}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Verify}&lt;&#x2F;span&gt; processes as they are amortized over many or large proofs. (Though &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{Open}&lt;&#x2F;span&gt; is a significant factor, and so is witness generation, and lookup, and ...)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementations&quot;&gt;Implementations&lt;&#x2F;h2&gt;
&lt;p&gt;I picked the following libraries to benchmark, and for each library I picked what I assume are the highest performing parameters. Assembly code, multithreading and other speed improvements are enabled where optional. I&#x27;m ignoring zero-knowledge, proof size and verification cost as all of that can be taken care of with a layer of recursion.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;supranational&#x2F;blst&quot;&gt;&lt;strong&gt;&lt;code&gt;blst&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; Not a ZKP framework, but can be used to implement KZG.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ConsenSys&#x2F;gnark-crypto&quot;&gt;&lt;strong&gt;&lt;code&gt;gnark&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; A comprehensive Groth16 and Plonk framework from Consensys.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zcash&#x2F;halo2&quot;&gt;&lt;strong&gt;&lt;code&gt;halo2&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; ZCash&#x27;s Plonk framework using inner product arguments (IPA).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;privacy-scaling-explorations&#x2F;halo2&quot;&gt;&lt;strong&gt;&lt;code&gt;pse&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; Halo2 fork with KZG support from the Ethereum Foundation and Scroll.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&quot;&gt;&lt;strong&gt;&lt;code&gt;plonky2&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; Goldilocks-FRI Plonk with efficient recursion from Polygon Zero.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;arkworks-rs&#x2F;algebra&quot;&gt;&lt;strong&gt;&lt;code&gt;ark&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; The Arkworks comprehensive library for ZKP development.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;facebook&#x2F;winterfell&quot;&gt;&lt;strong&gt;&lt;code&gt;winter&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; Facebook Winterfell as used by Polygon Miden.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;risc0&#x2F;risc0&quot;&gt;&lt;strong&gt;&lt;code&gt;risc0&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; A tiny field FRI for a RiscZero&#x27;s RISC-V zkVM.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{lcccccc}
                 &amp;amp; \text{Algo} &amp;amp; \F            &amp;amp;  \ceil{\log_2{\vert \F \vert}} &amp;amp;\text{Hash} &amp;amp; R^{-1} &amp;amp; \text{Add}  \\[0.7em]
\texttt{blst}    &amp;amp; \text{KZG}  &amp;amp; \text{BLS12-384}\ \G_1  &amp;amp; 255 &amp;amp;  &amp;amp;  &amp;amp; ✓ \\[0.4em]
\texttt{gnark}   &amp;amp; \text{KZG}  &amp;amp; \text{BN254}\ \G_1      &amp;amp; 254 &amp;amp;  &amp;amp;  &amp;amp; ✓ \\[0.4em]
\texttt{halo2}   &amp;amp; \text{IPA}  &amp;amp; \text{Pallas}           &amp;amp; 255 &amp;amp;  &amp;amp;  &amp;amp; ✓ \\[0.4em]
\texttt{pse}     &amp;amp; \text{KZG}  &amp;amp; \text{BN254}\ \G_1      &amp;amp; 254 &amp;amp;  &amp;amp;  &amp;amp; ✓ \\[0.4em]
\texttt{ark}     &amp;amp; \text{KZG}  &amp;amp; \text{BN254}\ \G_1      &amp;amp; 254 &amp;amp;  &amp;amp;  &amp;amp; ✓ \\[0.4em]
\texttt{plonky2} &amp;amp; \text{FRI}  &amp;amp; \text{Goldilocks}       &amp;amp; 64 &amp;amp;  \text{Keccak} &amp;amp; 2 &amp;amp; \\[0.4em]
\texttt{winter}  &amp;amp; \text{FRI}  &amp;amp; \text{f62}              &amp;amp; 62 &amp;amp; \text{Blake3} &amp;amp; 2 &amp;amp; \\[0.4em]
\texttt{risc0}   &amp;amp; \text{FRI}  &amp;amp; \text{Fp}               &amp;amp; 32 &amp;amp; \text{Sha256} &amp;amp; 4 &amp;amp; \\[0.4em]
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the table if &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; is an elliptic curve, then its scalar field is implied. A check under &lt;span class=&quot;math math-inline&quot;&gt;\text{Add}&lt;&#x2F;span&gt; means the commitments support additive homomorphism, this means that given &lt;span class=&quot;math math-inline&quot;&gt;\Commit(P)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\Commit(Q)&lt;&#x2F;span&gt; we can compute &lt;span class=&quot;math math-inline&quot;&gt;\Commit(a⋅P + b⋅Q)&lt;&#x2F;span&gt;. For FRI implementations the rate &lt;span class=&quot;math math-inline&quot;&gt;R^{-1}&lt;&#x2F;span&gt; is set to the lowest supported, trading off proof size for better prover time.&lt;&#x2F;p&gt;
&lt;p&gt;For the KZG and IPA algorithms the &lt;span class=&quot;math math-inline&quot;&gt;\Commit&lt;&#x2F;span&gt; computes a multi-scalar multiplication (MSM, a.k.a. multi-exponentiation). For FRI it interpolates the polynomial using number-theoretic transforms (NTTs, a.k.a fast-fourier transforms) and then computes a Merkle tree.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Add &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AztecProtocol&#x2F;barretenberg&quot;&gt;barettenberg&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;iden3&#x2F;rapidsnark&quot;&gt;rapidsnark&lt;&#x2F;a&gt; (both KZG over BN254) and an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1010&quot;&gt;Orion&lt;&#x2F;a&gt; implementation like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;niconiconi&#x2F;OrionLinearPC&quot;&gt;this one&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;starkware-libs&#x2F;ethSTARK https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;582.pdf
https:&#x2F;&#x2F;twitter.com&#x2F;EliBenSasson&#x2F;status&#x2F;1610724082173235200&lt;&#x2F;p&gt;
&lt;!-- TODO: https:&#x2F;&#x2F;github.com&#x2F;TAMUCrypto&#x2F;virgo-plus --&gt;
&lt;h2 id=&quot;machines&quot;&gt;Machines&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;m1-max&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; M1 Max Macbook Pro with 64GB memory and 2+8 ores.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;hpc6a&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; AWS EC2 instance with 370GB memory and 96 cores.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;a15&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt; Apple iPhone 13 Pro with 6GB memory and 4+2 cores.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Given that the primary use case of ZKPs right now is R&amp;amp;D, the most common hardware is a Macbook Pro. For real world privacy use cases the phone is much more important, and for computational integrity the server hardware is relevant.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; An &lt;code&gt;x86_64&lt;&#x2F;code&gt; based desktop and &lt;code&gt;arm32&lt;&#x2F;code&gt; phone. And &lt;code&gt;gpu&lt;&#x2F;code&gt; and &lt;code&gt;wasm&lt;&#x2F;code&gt; targets.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;results&quot;&gt;Results&lt;&#x2F;h2&gt;
&lt;p&gt;Graphs show &lt;span class=&quot;math math-inline&quot;&gt;\Commit&lt;&#x2F;span&gt; throughput in field elements per second for increasing numbers of elements. Starting with the Macbook:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;23&#x2F;pc-bench&#x2F;bench-m1-max.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;All the MSM based commitments run within a factor two of each other once we hit an initial scale of &lt;span class=&quot;math math-inline&quot;&gt;~2^{16}&lt;&#x2F;span&gt;. The FRI based commitments do considerably better, with Winterfell processing elements 10x faster. All of them run out of memory around &lt;span class=&quot;math math-inline&quot;&gt;2^{28}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;2^{29}&lt;&#x2F;span&gt; elements, except Risc0 which hits its theoretical limit at &lt;span class=&quot;math math-inline&quot;&gt;2^{25}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;23&#x2F;pc-bench&#x2F;bench-hpc6a.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With &lt;span class=&quot;math math-inline&quot;&gt;10×&lt;&#x2F;span&gt; more cores parallelization becomes critical. Plonky2, Risc0 and Arkworks struggle with this and perform equal or worse than before. Most of the MSMs get the expected &lt;span class=&quot;math math-inline&quot;&gt;10×&lt;&#x2F;span&gt; boost, but the spread is a bit larger. The Halo2 forks have surprisingly &lt;em&gt;consistent&lt;&#x2F;em&gt; performance. Gnark seems particularly good at picking up the cores (or perhaps it is more optimized for &lt;code&gt;x86&lt;&#x2F;code&gt;). Winterfell still performs excellent but only &lt;span class=&quot;math math-inline&quot;&gt;2×&lt;&#x2F;span&gt; instead of &lt;span class=&quot;math math-inline&quot;&gt;10×&lt;&#x2F;span&gt; better. Like the other FRIs it also struggles with parallelization. The &lt;span class=&quot;math math-inline&quot;&gt;5×&lt;&#x2F;span&gt; extra memory translated well to &lt;span class=&quot;math math-inline&quot;&gt;4×&lt;&#x2F;span&gt; larger commitments.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;23&#x2F;pc-bench&#x2F;bench-a15.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On phones the memory was very constraint. Despite &lt;span class=&quot;math math-inline&quot;&gt;6&lt;&#x2F;span&gt;GB memory being available iOS terminates processes using more than &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;GB. This limits commitments to about &lt;span class=&quot;math math-inline&quot;&gt;2^{24}&lt;&#x2F;span&gt; elements. The phone also slows down slightly as its casing approaches &lt;span class=&quot;math math-inline&quot;&gt;40\degree\rm{C}&lt;&#x2F;span&gt;, which shows up as inconsistent performance for all the algorithms.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t know what is up with Gnark here, it drops out of scale and fails at &lt;span class=&quot;math math-inline&quot;&gt;2^{16}&lt;&#x2F;span&gt;. Either the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;gbotrel&#x2F;zprize-mobile-harness&#x2F;tree&#x2F;6ae651b7b1664b81e7dac19c4a038eb014e93237&quot;&gt;code&lt;&#x2F;a&gt; from winning the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.zprize.io&#x2F;blog&#x2F;announcing-zprize-results&quot;&gt;mobile ZPrize&lt;&#x2F;a&gt; has not been upstreamed yet or my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;golang&#x2F;mobile&quot;&gt;gomobile&lt;&#x2F;a&gt; setup is wrong. The Gnark performance there was &lt;span class=&quot;math math-inline&quot;&gt;2^{16}&lt;&#x2F;span&gt; elements in &lt;span class=&quot;math math-inline&quot;&gt;0.569&lt;&#x2F;span&gt; seconds or &lt;span class=&quot;math math-inline&quot;&gt;115\ \text{kElement&#x2F;s}&lt;&#x2F;span&gt; on a 6+2 core processor.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;limits&quot;&gt;Limits&lt;&#x2F;h2&gt;
&lt;p&gt;For all these implementations there is a theoretical limit to size determined by the availability of power-of-two roots of unity (at least for Stark and Plonk arithmetization). For BN254 and &lt;code&gt;risc0&lt;&#x2F;code&gt; this limit is lower and practically reachable. For the rest we run out of memory  before we get there.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{lcccc}
&amp;amp; \texttt{a14}   &amp;amp; \texttt{m1-max} &amp;amp; \texttt{gpc6a} &amp;amp; \text{limit} \\[0.7em]
\texttt{blst}    &amp;amp; 23 &amp;amp; 28 &amp;amp; 30 &amp;amp; 32 \\[0.4em]
\texttt{gnark}   &amp;amp; 16 &amp;amp; 30 &amp;amp; 30 &amp;amp; 28 \\[0.4em]
\texttt{halo2}   &amp;amp; 24 &amp;amp; 28 &amp;amp; 31 &amp;amp; 32 \\[0.4em]
\texttt{pse}     &amp;amp; 24 &amp;amp; 29 &amp;amp; 31 &amp;amp; 28 \\[0.4em]
\texttt{plonky2} &amp;amp; 23 &amp;amp; 28 &amp;amp; 30 &amp;amp; 31 \\[0.4em]
\texttt{ark}     &amp;amp; 24 &amp;amp; 29 &amp;amp; 31 &amp;amp; 28 \\[0.4em]
\texttt{winter}  &amp;amp; 24 &amp;amp; 29 &amp;amp; 30 &amp;amp; 31 \\[0.4em]
\texttt{risc0}   &amp;amp; 24 &amp;amp; 25 &amp;amp; 25 &amp;amp; 25 \\
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;The FRI based algorithms perform excellent on smaller machines, despite being &lt;span class=&quot;math math-inline&quot;&gt;O(n⋅\log n)&lt;&#x2F;span&gt; versus &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; for MSM. The asymptotical performance is moot because memory issues dominate well before the asymptotes come into play. Winterfell consistently performs best for larger commitments.&lt;&#x2F;p&gt;
&lt;p&gt;It is surprising that the FRI algorithms run out of memory around the same time as the elliptic curve ones, despite the input size being &lt;span class=&quot;math math-inline&quot;&gt;12×&lt;&#x2F;span&gt; smaller. This can be partially explained by extra allocations for the low degree extension and the Merkle tree.&lt;&#x2F;p&gt;
&lt;p&gt;Less surprising is that the FRI algorithms make ineffective use of multiple cores, with Winterfell only performing &lt;span class=&quot;math math-inline&quot;&gt;2×&lt;&#x2F;span&gt; better with &lt;span class=&quot;math math-inline&quot;&gt;10×&lt;&#x2F;span&gt; more cores. Number theoretic transforms are notoriously hard to parallelize.&lt;&#x2F;p&gt;
&lt;p&gt;Gnark looks exceptional among the elliptic curve solutions, it is unfortunate that did not perform well on mobile.&lt;&#x2F;p&gt;
&lt;p&gt;Source code for the benchmarks at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;pc-bench&quot;&gt;&lt;code&gt;recmo&#x2F;pc-bench&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Upper bound for transaction memory</title>
        <published>2022-12-30T00:00:00+00:00</published>
        <updated>2022-12-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/eth-max-mem/"/>
        <id>https://2π.com/22/eth-max-mem/</id>
        
        <content type="html" xml:base="https://2π.com/22/eth-max-mem/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{#1 #2 #3}
\gdef\p#1{({#1})}
\gdef\floor#1{\lfloor{#1}\rfloor}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;upper-bound-for-transaction-memory&quot;&gt;Upper bound for transaction memory&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;chfast&#x2F;status&#x2F;1607449650948194304&quot;&gt;Paweł Bylica&lt;&#x2F;a&gt; asks:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;What is good upper bound estimation of total EVM memory usage one can reach in a single transaction given the transaction gas limit?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The gas cost of memory from the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum.github.io&#x2F;yellowpaper&#x2F;paper.pdf&quot;&gt;yellow paper&lt;&#x2F;a&gt; is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathrm{C_{mem}}(a) ≝ \mathrm{G_{memory}} ⋅ a + \floor{ \frac{a^2}{512} }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{G_{memory}} = 3&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; is the highest accessed address in 256-bit words. Accessing arbitrarily high addresses can be done at constant negligible cost using a &lt;code&gt;MLOAD&lt;&#x2F;code&gt; opcode.&lt;&#x2F;p&gt;
&lt;p&gt;So given &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; gas, what is an upper bound for the accessible address?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
g &amp;amp;≤ 3 ⋅ a + \floor{ \frac{a^2}{512} } \\
g &amp;amp;≤ 3 ⋅ a + \frac{a^2}{512} + 1 \\
a &amp;amp;≤ 256 ⋅ \p{\sqrt{9 + (g - 1) ⋅ \frac{1}{128} } - 3} \\
a &amp;amp;≤ \sqrt{589312 + 512 ⋅ g} - 768
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; is in words, so the allocatable memory in a single &lt;code&gt;MLOAD&lt;&#x2F;code&gt; with gas &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;32⋅a&lt;&#x2F;span&gt; bounded by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M(g) ≤ 512 ⋅ \sqrt{2} ⋅ \sqrt{g + 1151} - 48⋅512
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Which looks like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;eth-max-mem&#x2F;max-mem-base.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;recursion-and-the-63-64-rule&quot;&gt;Recursion and the 63&#x2F;64 rule.&lt;&#x2F;h2&gt;
&lt;p&gt;A transaction can (recursively) call itself, which allows avoiding the quadratic cost of growing memory by splitting it up in multiple smaller allocations. On a call a transaction can pass some of the available gas. (See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-150&quot;&gt;EIP-150&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2929&quot;&gt;EIP-2929&lt;&#x2F;a&gt;). A call costs at least&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathrm{C_{call}} ≥ \mathrm{G_{warmaccess}} = 100
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;gas. There is some additional overhead in setting up the stack, but I conservatively round that to zero. There is no substantial difference between using &lt;code&gt;CALL&lt;&#x2F;code&gt;, &lt;code&gt;CALLCODE&lt;&#x2F;code&gt;, &lt;code&gt;DELEGATECALL&lt;&#x2F;code&gt; and &lt;code&gt;STATICCALL&lt;&#x2F;code&gt; here and the &lt;code&gt;CREATE&lt;&#x2F;code&gt; and &lt;code&gt;CREATE2&lt;&#x2F;code&gt; opcodes (which also allow recursion) are strictly more expensive. The call can pass along at most &lt;span class=&quot;math math-inline&quot;&gt;g&amp;#39;&lt;&#x2F;span&gt; of the &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; gas remaining after subtracting the call cost:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
g&amp;#39; = g - \floor{\frac{g}{64}} &amp;lt; \frac{63}{64} ⋅ g + 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So if &lt;span class=&quot;math math-inline&quot;&gt;g_i&lt;&#x2F;span&gt; gas is left at recursion &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;, the the maximum gas available at &lt;span class=&quot;math math-inline&quot;&gt;g_{i+1}&lt;&#x2F;span&gt; is bounded by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
g_{i+1} &amp;lt; \frac{63}{64} ⋅ \p{g_i - 100} + 1 = \frac{1}{64} ⋅ \p{63 ⋅ g_i - 6236}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can solve this linear recurrence to get the closed form bound&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
g_i &amp;lt; \p{g_0 + 6236}⋅\p{\frac{63}{64}}^i - 6236
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And we can solve this for zero to determine the maximum recursion depth&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
i_{\mathrm{max}} &amp;lt; \frac{\ln 6236 - \ln \p{g_0 + 6236}}{\ln 63 - \ln 64}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Which looks like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;eth-max-mem&#x2F;max-recursion.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;recursive-allocation&quot;&gt;Recursive allocation&lt;&#x2F;h2&gt;
&lt;p&gt;At each level of recursion we loose a &lt;span class=&quot;math math-inline&quot;&gt;64&lt;&#x2F;span&gt;-th fraction of the gas. This fraction can still be used &lt;em&gt;after&lt;&#x2F;em&gt; the call returns, but this is not useful for memory maximization purposes. We need to allocate memory before the recursive call so it must be held during the call. (For the same reason it does not help to use the return data write of the &lt;code&gt;CALL&lt;&#x2F;code&gt;, a robust EVM implementation can allocate that after the recursion is finished.)&lt;&#x2F;p&gt;
&lt;p&gt;To put a bound on the maximum memory allocatable with recursion, we can take the non-recursive limit &lt;span class=&quot;math math-inline&quot;&gt;M(g)&lt;&#x2F;span&gt; and define the recursive limit to be &lt;span class=&quot;math math-inline&quot;&gt;M_r(g)&lt;&#x2F;span&gt;. This limit will have to satisfy a function relation that basically says it is invariant to adding another level of recursion:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M_r(g) = \max_{g&amp;#39; ∈\delim[{0,g}]} M(g - g&amp;#39;) + M_r\p{\floor{\frac{63⋅\p{g&amp;#39; - \mathrm{C_{call}}}}{64}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This recursive function relation is a form of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bellman_equation#The_Bellman_equation&quot;&gt;Bellman equation&lt;&#x2F;a&gt;, which are hard to solve analytically. But numerically they can be solved by iterating until we find the fixed point. Bellman equations are basically the continuous analogue to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dynamic_programming&quot;&gt;dynamic programming&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;eth-max-mem&#x2F;many-recursion.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each line represent a level of recursion, starting with a single context (no recursion) as the bottom most line. We can also look at &lt;span class=&quot;math math-inline&quot;&gt;n = \frac{g}{g - g&amp;#39;}&lt;&#x2F;span&gt;, which is the &lt;span class=&quot;math math-inline&quot;&gt;\frac{1}{n}&lt;&#x2F;span&gt; fraction of the gas that is used locally to allocate while the rest is used for recursion.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;eth-max-mem&#x2F;many-recursion-frac.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is visible that for small &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;, if we are using &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; levels of recursion then in each level we want to use close to &lt;span class=&quot;math math-inline&quot;&gt;\frac{1}{n}&lt;&#x2F;span&gt; of the gas to allocate memory. As &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; gets large or the amount of gas available gets lower we want to forward less of the gas and allocate more locally. This matches our intuition that a good basic strategy is to divide the gas equally over a number of recursive calls to maximally avoid the quadratic factor.&lt;&#x2F;p&gt;
&lt;p&gt;In the limit of many recursions and lots of gas it converges to &lt;span class=&quot;math math-inline&quot;&gt;64&lt;&#x2F;span&gt;, so &lt;span class=&quot;math math-inline&quot;&gt;g&amp;#39; = \frac{63}{64} ⋅ g&lt;&#x2F;span&gt;. If we assume this limit and set &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{C_{call}} = 0&lt;&#x2F;span&gt; the above functional relation simplifies to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M_r(g) = M\p{\frac{g}{64}} + M_r\p{\p{\frac{63}{64}}^2 ⋅ g}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This defines an summation series&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M_r(g) = \sum_{i∈[0,∞)} M\p{\frac{1}{64} ⋅ \p{\frac{63}{64}}^{2⋅i}⋅g }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;substituting the above bound on &lt;span class=&quot;math math-inline&quot;&gt;M(g)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M_r(g) = \sum_{i∈[0,∞)} \p{
512 ⋅ \sqrt{2} ⋅ \sqrt{\frac{1}{64} ⋅ \p{\frac{63}{64}}^{2⋅i}⋅g + 1151} - 48⋅512 }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;taking the limit of large &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; we can ignore the additive constants&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M_r(g) = \sum_{i∈[0,∞)} \p{
512 ⋅ \sqrt{2} ⋅ \sqrt{\frac{1}{64} ⋅ \p{\frac{63}{64}}^{2⋅i}⋅g}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;this simplifies to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M_r(g) = 64 ⋅ \sqrt{2 ⋅ g} ⋅ \sum_{i∈[0,∞)} \p{\frac{63}{64}}^{i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which is a geometric series with solution&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M_r(g) = 4096 ⋅ \sqrt{2 ⋅ g}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can plot this with our numerical results&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;eth-max-mem&#x2F;many-recursion-bound.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The function indeed looks like an upper bound so our simplifying assumptions seem to hold. The bound could be tighter, but looks usable. So the upper bounds we found for &lt;span class=&quot;math math-inline&quot;&gt;30&lt;&#x2F;span&gt; MGas are &lt;span class=&quot;math math-inline&quot;&gt;32&lt;&#x2F;span&gt; MBytes using the analytic solution and &lt;span class=&quot;math math-inline&quot;&gt;27&lt;&#x2F;span&gt; MBytes numerically.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; What&#x27;s a good lower bound? I.e. write EVM bytecode that maximizes the memory required.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Goldilocks Prime</title>
        <published>2022-12-19T00:00:00+00:00</published>
        <updated>2022-12-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/goldilocks/"/>
        <id>https://2π.com/22/goldilocks/</id>
        
        <content type="html" xml:base="https://2π.com/22/goldilocks/">&lt;h1 id=&quot;the-goldilocks-prime&quot;&gt;The Goldilocks Prime&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\F{\mathbb{F}}
\gdef\mod#1{\delim[{#1}]}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2015&#x2F;625.pdf&quot;&gt;Ham15&lt;&#x2F;a&gt; Mike Hamburg introduced a class of primes of the form &lt;span class=&quot;math math-inline&quot;&gt;p = φ^2 - φ - 1&lt;&#x2F;span&gt; and named them Goldilocks primes. In those prime fields &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; satisfies the Golden ratio relation &lt;span class=&quot;math math-inline&quot;&gt;φ² = φ + 1&lt;&#x2F;span&gt;. When &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; is a power of two this allows for very efficient implementation. Unfortunately, the &lt;span class=&quot;math math-inline&quot;&gt;-1&lt;&#x2F;span&gt; at the end means it will have very few power-of-two roots of unity. We&#x27;d like to have many so we can do big number theoretic transforms.&lt;&#x2F;p&gt;
&lt;p&gt;We will instead consider primes of the form &lt;span class=&quot;math math-inline&quot;&gt;p = φ^2 - φ + 1&lt;&#x2F;span&gt;. Following the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&quot;&gt;plonky2&lt;&#x2F;a&gt; project we keep the name Goldilocks prime. Now &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; satisfies a modified Golden ration relation &lt;span class=&quot;math math-inline&quot;&gt;φ² = φ - 1&lt;&#x2F;span&gt;. More importantly, the &lt;span class=&quot;math math-inline&quot;&gt;+1&lt;&#x2F;span&gt; at the end guarantees we will have a &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt;-th root of unity.&lt;&#x2F;p&gt;
&lt;p&gt;The values of &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; is prime are the sequences &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oeis.org&#x2F;A055494&quot;&gt;A055494&lt;&#x2F;a&gt; and  &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;oeis.org&#x2F;A002383&quot;&gt;A002383&lt;&#x2F;a&gt; respectively:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
φ &amp;amp;= 2, 3, 4, 6, 7, 9, 13, 15, 16, 18, 21, 22, 25, 28, …, \\
p &amp;amp;= 3, 7, 13, 31, 43, 73, 157, 211, 241, 307, 421, …
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As mentioned, in the prime field &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;φ^2 = φ - 1&lt;&#x2F;span&gt;. From this further useful relations on the powers of &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; follow:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
φ^3 &amp;amp;= - 1 &amp;amp;\hspace{2em}
φ^4 &amp;amp;= - φ &amp;amp;\hspace{2em}
φ^5 &amp;amp;= 1 - φ &amp;amp;\hspace{2em}
φ^6 &amp;amp;= 1
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And the pattern repeats. This shows hat &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; is a primitive 6th root of unity. These relations leads to a particularly efficient modular reduction algorithm. First we write the number &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; in base &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
n = n_0 + n_1 ⋅ φ + n_2 ⋅ φ^2 + n_3 ⋅ φ^3 + n_4 ⋅ φ^4 + ⋯
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We get rid of all the terms &lt;span class=&quot;math math-inline&quot;&gt;n_{&amp;gt;3}&lt;&#x2F;span&gt; by folding them into &lt;span class=&quot;math math-inline&quot;&gt;n_0&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;n_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;n_2&lt;&#x2F;span&gt; using the relations on &lt;span class=&quot;math math-inline&quot;&gt;φ^3&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;φ^6&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
n_0&amp;#39; &amp;amp;= n_0 - n_3 + n_6 - n_{9\phantom{0}} + ⋯ \\
n_1&amp;#39; &amp;amp;= n_1 - n_4 + n_7 - n_{10} + ⋯ \\
n_2&amp;#39; &amp;amp;= n_2 - n_5 + n_8 - n_{11} + ⋯ \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To reduce this from three to two terms we use the relation on &lt;span class=&quot;math math-inline&quot;&gt;φ^2&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
n_0&amp;#39; = n_0 - n_2 \\
n_1&amp;#39; = n_1 + n_2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The reduced number is &lt;span class=&quot;math math-inline&quot;&gt;n_0 + n_1 ⋅ φ&lt;&#x2F;span&gt;. All that remains is carry propagation and some conditional subtractions of the modulus. Note that the reduction requires no multiplication operations.&lt;&#x2F;p&gt;
&lt;p&gt;To multiply two numbers &lt;span class=&quot;math math-inline&quot;&gt;a,b ∈ \F_p&lt;&#x2F;span&gt; we can write them in base &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; and make use of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Karatsuba_algorithm&quot;&gt;Karatsuba multiplication&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a⋅b &amp;amp;= (a_0 + a_1 ⋅ φ) ⋅ (b_0 + b_1 ⋅ φ) \\
&amp;amp;= a_0 ⋅ b_0 + (a_0⋅b_1 + a_1⋅b_0) ⋅ φ + a_1⋅b_1 ⋅ φ^2 \\
&amp;amp;= a_0 ⋅ b_0 - a_1⋅b_1 + (a_0⋅b_1 + a_1⋅b_0 + a_1⋅b_1) ⋅ φ \\
&amp;amp;= a_0 ⋅ b_0 - a_1⋅b_1 + ((a_0 + a_1) ⋅ (b_0 + b_1) - a_0⋅b_0) ⋅ φ \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This requires three full multiplications in base &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; and results in three terms. We reduce this to two terms using the final step of the modular reduction procedure.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; What do Barrett and Montgomery reduction look like?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-lucky-binary-base&quot;&gt;A lucky binary base&lt;&#x2F;h2&gt;
&lt;p&gt;To implement base &lt;span class=&quot;math math-inline&quot;&gt;φ&lt;&#x2F;span&gt; operations efficiently we&#x27;d like it to be a power of two, i.e. &lt;span class=&quot;math math-inline&quot;&gt;φ = 2^k&lt;&#x2F;span&gt;. There are not many such primes, the only solutions with &lt;span class=&quot;math math-inline&quot;&gt;k &amp;lt; 4000&lt;&#x2F;span&gt; are &lt;span class=&quot;math math-inline&quot;&gt;k = 1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;4&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;32&lt;&#x2F;span&gt;. The first to are too small to be practically useful which leaves us with &lt;span class=&quot;math math-inline&quot;&gt;32&lt;&#x2F;span&gt;. &lt;span class=&quot;math math-inline&quot;&gt;φ = 2^{32}&lt;&#x2F;span&gt; makes an especially useful prime &lt;span class=&quot;math math-inline&quot;&gt;p = 2^{64} - 2^{32} + 1&lt;&#x2F;span&gt; or written in full&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p = 18446744069414584321 = \mathtt{0x\,ffff\,ffff\,0000\,0001}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a great size. It is small enough to fit in a 64-bit number, but large enough to do a lot of useful math in. For example, if we have three 32-bit numbers &lt;span class=&quot;math math-inline&quot;&gt;a,b,c ∈ [0, 2^{32}-1]&lt;&#x2F;span&gt; we can compute &lt;span class=&quot;math math-inline&quot;&gt;a ⋅ b + c&lt;&#x2F;span&gt; without overflowing:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a⋅b + c \enspace ≤ \enspace (2^{32} - 1)^2 + (2^{32} - 1) \enspace=\enspace 2^{64} - 2^{32} \enspace&amp;lt;\enspace p
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When computing on 32&#x2F;64-bit computers we have some useful interactions with the binary rings:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mod{2^{n⋅32}}_p &amp;amp;= \mod{φ^n}_p &amp;amp;\quad
\mod{2^{64}}_p &amp;amp;= \mod{-1}_{2^{32}} &amp;amp;\quad
\mod{-p}_{2^{64}} &amp;amp;= \mod{-1}_{2^{32}} &amp;amp;\quad
\mod{φ}_{2^{32}} &amp;amp;= 0 &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first identity gives us a very efficient way to implement bit-shifts. This in turn leads to an efficient inversion algorithm from the half-extended binary GCD:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; inverse&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;MODULUS&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    twos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; trailing_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; twos&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    twos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 96&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # 2^96 = -1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        t0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; trailing_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        t1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        twos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; count&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            twos&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 96&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # 2^96 = -1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;191&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; twos&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 192&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # 2^-1 = 2^191, 2^192 = 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;multiplicative-group&quot;&gt;Multiplicative group&lt;&#x2F;h2&gt;
&lt;p&gt;The multiplicative group has order &lt;span class=&quot;math math-inline&quot;&gt;p - 1&lt;&#x2F;span&gt; and factors into a power of two and, interestingly, all five known &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mathworld.wolfram.com&#x2F;FermatPrime.html&quot;&gt;Fermat primes&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p - 1 = 2^{32} ⋅ 3 ⋅ 5 ⋅ 17 ⋅ 257 ⋅ 65537
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The factor &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt; means we can do efficient NTTs of power-of-two sizes using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cooley%E2%80%93Tukey_FFT_algorithm&quot;&gt;Cooley-Tukey algorithm&lt;&#x2F;a&gt;. The Fermat primes are not just curious, they allow us to use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rader%27s_FFT_algorithm&quot;&gt;Rader&#x27;s FFT algorithm&lt;&#x2F;a&gt; to turn the Fermat prime sized NTTs into power-of-two NTTs. With efficient NTTs for all prime factors we can use the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Prime-factor_FFT_algorithm&quot;&gt;Good-Thomans algorithm&lt;&#x2F;a&gt; to efficiently combine these without requirng twiddle factors. Overall this gives decent NTT performance for any divisor of &lt;span class=&quot;math math-inline&quot;&gt;p-1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;But what if we want a different size? The usual method is to pad the data until it is a power of two size. This is wasteful as can mean almost doubling the size. Instead we could go beyond powers of two and include the other small primes &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;5&lt;&#x2F;span&gt; things improve quite a bit&lt;&#x2F;p&gt;
&lt;img src=&quot;ntt-mixed-radix.png&quot; width=&quot;66%&quot;&#x2F;&gt;
&lt;p&gt;For example if we do a &lt;span class=&quot;math math-inline&quot;&gt;2^{32} ⋅ 3&lt;&#x2F;span&gt; mixed radix, then in half of the cases it is 25% smaller than if we only use &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt;. If we also add &lt;span class=&quot;math math-inline&quot;&gt;5&lt;&#x2F;span&gt; then in a quarter of the cases it is an extra 16% smaller. These two seem worthwhile. Adding &lt;span class=&quot;math math-inline&quot;&gt;17&lt;&#x2F;span&gt; still gives a visible improvement, but is probably not worth the implementation complexity. And &lt;span class=&quot;math math-inline&quot;&gt;257&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;65537&lt;&#x2F;span&gt; do not contribute anything noticeable.&lt;&#x2F;p&gt;
&lt;p&gt;NTTs require lot&#x27;s of multiplications by roots of unity. Goldilocks again helps us make this efficient. We already found that &lt;span class=&quot;math math-inline&quot;&gt;φ=2^{32}&lt;&#x2F;span&gt; is a &lt;span class=&quot;math math-inline&quot;&gt;6&lt;&#x2F;span&gt;th root of unity, and multiplying by it is simply a left shift of 32 bits. But if &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt; is a &lt;span class=&quot;math math-inline&quot;&gt;6&lt;&#x2F;span&gt;th root, then &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt; itself must be a &lt;span class=&quot;math math-inline&quot;&gt;6 ⋅ 32 = 192&lt;&#x2F;span&gt;th root. Great! This means multiplying by &lt;span class=&quot;math math-inline&quot;&gt;192&lt;&#x2F;span&gt;th roots is just cheap bit shift. And since &lt;span class=&quot;math math-inline&quot;&gt;192 = 2^6 ⋅ 3&lt;&#x2F;span&gt; has many divisors we can now create a whole set of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th roots &lt;span class=&quot;math math-inline&quot;&gt;ω_n&lt;&#x2F;span&gt; that can be implemented using bit shifts:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
ω_2 &amp;amp;= 2^{96} &amp;amp; ω_{6\phantom{0}} &amp;amp;= 2^{32} &amp;amp; ω_{16} &amp;amp;= 2^{12} &amp;amp; ω_{48} &amp;amp;= 2^{4} &amp;amp; ω_{192} &amp;amp;= 2\\
ω_3 &amp;amp;= 2^{64} &amp;amp; ω_{8\phantom{0}} &amp;amp;= 2^{24} &amp;amp; ω_{24} &amp;amp;= 2^{8}  &amp;amp; ω_{64} &amp;amp;= 2^{3} \\
ω_4 &amp;amp;= 2^{48} &amp;amp; ω_{12}           &amp;amp;= 2^{16} &amp;amp; ω_{32} &amp;amp;= 2^{6}  &amp;amp; ω_{96} &amp;amp;= 2^{2} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can go even further and construct a &lt;span class=&quot;math math-inline&quot;&gt;384&lt;&#x2F;span&gt;th root using two bit shifts, but for that we need a trick. Schönhage observed that given an &lt;span class=&quot;math math-inline&quot;&gt;8&lt;&#x2F;span&gt;th root &lt;span class=&quot;math math-inline&quot;&gt;ω_8&lt;&#x2F;span&gt;, the value &lt;span class=&quot;math math-inline&quot;&gt;ω_8 + ω_8^7&lt;&#x2F;span&gt; is a square root of &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;. Let&#x27;s quickly check this&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(ω_8 + ω_8^7)^2
= ω_8^2 + ω_8^{7⋅2} + 2 ⋅ ω_8^{1+7}
= ω_8^2 - ω_8^2 + 2
= 2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In Goldilocks &lt;span class=&quot;math math-inline&quot;&gt;2^{24}&lt;&#x2F;span&gt; is an &lt;span class=&quot;math math-inline&quot;&gt;8&lt;&#x2F;span&gt;th root and &lt;span class=&quot;math math-inline&quot;&gt;2^{96} = -1&lt;&#x2F;span&gt; so &lt;span class=&quot;math math-inline&quot;&gt;n = 2^{24} - 2^{72}&lt;&#x2F;span&gt; is a square root of two. Furthermore since &lt;span class=&quot;math math-inline&quot;&gt;n^2 = 2&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt; is a &lt;span class=&quot;math math-inline&quot;&gt;192&lt;&#x2F;span&gt;th root, it follows that &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is a &lt;span class=&quot;math math-inline&quot;&gt;384&lt;&#x2F;span&gt;th root &lt;span class=&quot;math math-inline&quot;&gt;ω_{384}&lt;&#x2F;span&gt;. If we don&#x27;t want that factor of &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt; we can compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ω_{128} = ω_{384}^3 = ω_{384}^2 ⋅ ω_{384} = 2⋅(2^{24} - 2^{72}) = 2^{25} - 2^{73}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This also shows that all even powers of &lt;span class=&quot;math math-inline&quot;&gt;ω_{384}&lt;&#x2F;span&gt; have one bit set and all odd powers two.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ω_{384}^i = \begin{cases}
2^{k} &amp;amp; i = 2⋅k \\
2^{k + 24} - 2^{k + 73} &amp;amp; i = 2⋅k + 1 \\
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{2}&lt;&#x2F;span&gt; trick is useful, let&#x27;s understand it better and see if we can take it further.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;schonhage-s-trick&quot;&gt;Schönhage&#x27;s trick&lt;&#x2F;h2&gt;
&lt;p&gt;To intuitively understand why this works, forget for the moment that we are working in a prime field and imagine the 8th roots of unity in the complex plane.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;goldilocks&#x2F;radical-trick.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can construct the sum &lt;span class=&quot;math math-inline&quot;&gt;ω_8 + ω_8^7&lt;&#x2F;span&gt; by adding vectors. Pythagoras theorem shows it is &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{2}&lt;&#x2F;span&gt;. This procedure generalizes this to &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-roots with &lt;span class=&quot;math math-inline&quot;&gt;ω_n + ω_n^{n-1}&lt;&#x2F;span&gt;, where the angles between roots are &lt;span class=&quot;math math-inline&quot;&gt;\frac{2⋅π}{n}&lt;&#x2F;span&gt;. A bit of trigonometry shows the solutions&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ω_n + ω_n^{n-1} = 2 ⋅ \cos \frac{2⋅π}{n}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For certain values of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; there are simple exact values for &lt;span class=&quot;math math-inline&quot;&gt;\cos&lt;&#x2F;span&gt;, see a table of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exact_trigonometric_values&quot;&gt;exact trigonometric values&lt;&#x2F;a&gt;. We indeed get &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{2}&lt;&#x2F;span&gt; and a few more. Most look quite uninteresting, but these two I like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
% ω_{8\phantom{0}} + ω_{8\phantom{0}}^7 &amp;amp;= \sqrt{2} \\
ω_{12} + ω_{12}^{11} &amp;amp;= \sqrt{3} &amp;amp;\hspace{2em}
ω_{10} + ω_{10}^9 &amp;amp;= \frac{1 + \sqrt{5}}{2}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The last one is also known as the Golden ratio. It turns out these work in the Goldilocks field as well. Since &lt;span class=&quot;math math-inline&quot;&gt;ω_{12} = 2^{16}&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{3} = 2^{16} - 2^{80}&lt;&#x2F;span&gt;. For &lt;span class=&quot;math math-inline&quot;&gt;ω_{10}&lt;&#x2F;span&gt; I don&#x27;t know a multiplication free construction.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; It is possible to geometrically construct &lt;span class=&quot;math math-inline&quot;&gt;\sqrt[4]{2}&lt;&#x2F;span&gt; using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Geometric_mean_theorem&quot;&gt;geometric mean theorem&lt;&#x2F;a&gt;. Is there a construction that leads to an efficient (multiplication free) implementation?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;apgox&#x2F;status&#x2F;1604894352417095680&quot;&gt;Adam P. Goucher&lt;&#x2F;a&gt; explains that it is not possible to construct &lt;span class=&quot;math math-inline&quot;&gt;\sqrt[4]{2}&lt;&#x2F;span&gt; as a rational function of roots of unity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;generators&quot;&gt;Generators&lt;&#x2F;h2&gt;
&lt;p&gt;So far we&#x27;ve cleverly constructed roots up to &lt;span class=&quot;math math-inline&quot;&gt;ω_{384}&lt;&#x2F;span&gt;, but for our NTTs we need all the roots up to the &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt;th. The standard way to do this is to find a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Generating_set_of_a_group&quot;&gt;generator&lt;&#x2F;a&gt; of the multiplicative group. A generator is a field element &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; such that all non-zero numbers can be written as powers &lt;span class=&quot;math math-inline&quot;&gt;g^i&lt;&#x2F;span&gt; for some &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;. There are many such numbers and the smallest generator in Goldilocks in &lt;span class=&quot;math math-inline&quot;&gt;7&lt;&#x2F;span&gt;. By Fermat&#x27;s little theorem we have &lt;span class=&quot;math math-inline&quot;&gt;g^{p - 1} = 1&lt;&#x2F;span&gt; and thus &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is a primitive &lt;span class=&quot;math math-inline&quot;&gt;(p-1)&lt;&#x2F;span&gt;-th root of unity. Since this is the highest possible root of unity, we can derive all others from it using&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ω_n = g^{\frac{p - 1}{n}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Nothing-up-my-sleeve_number&quot;&gt;convention&lt;&#x2F;a&gt; to use the smallest generator, but if we compute &lt;span class=&quot;math math-inline&quot;&gt;ω_{192}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;g=7&lt;&#x2F;span&gt; we get &lt;span class=&quot;math math-inline&quot;&gt;35184372080640&lt;&#x2F;span&gt; instead of &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;. This happens because &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-th primitive roots are not unique and there are many choices that work. While this is still a power of two, &lt;span class=&quot;math math-inline&quot;&gt;ω_{192} = 2^{77}&lt;&#x2F;span&gt;, it makes things more complicated than they need to be and we get a more complicated formula for &lt;span class=&quot;math math-inline&quot;&gt;ω_{384}^i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A priory there is no reason to pick one choice of roots over the other. But we do need our choices to be consistent, meaning we want&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
ω_n = ω_{k⋅n}^k
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;to hold where applicable. Using a generator full fills that requirement. We&#x27;d also like a choice where we have an easy formula for multiplication by &lt;span class=&quot;math math-inline&quot;&gt;ω_{384}^i&lt;&#x2F;span&gt; in terms of bit shifts. The smallest generator that satisfies this is &lt;span class=&quot;math math-inline&quot;&gt;554&lt;&#x2F;span&gt;. But this one has &lt;span class=&quot;math math-inline&quot;&gt;ω_{384} = -(ω_8 + ω_8^7)&lt;&#x2F;span&gt;, it takes the negative square root of two. The smallest generator that picks the positive root is &lt;span class=&quot;math math-inline&quot;&gt;2717&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Are there larger values of &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; for which &lt;span class=&quot;math math-inline&quot;&gt;2^{2⋅k} - 2^k + 1&lt;&#x2F;span&gt; is prime or is &lt;span class=&quot;math math-inline&quot;&gt;32&lt;&#x2F;span&gt; the largest?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-references&quot;&gt;Further references&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cp4space.hatsya.com&#x2F;2021&#x2F;09&#x2F;01&#x2F;an-efficient-prime-for-number-theoretic-transforms&#x2F;&quot;&gt;Gou21&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;apgox&quot;&gt;Adam P. Goucher&lt;&#x2F;a&gt; (2021). &quot;An efficient prime for number-theoretic transforms&quot;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;274.pdf&quot;&gt;Po22&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;. Thomas Pornin (2022).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&#x2F;issues&#x2F;1#issuecomment-809323437&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;mir-protocol&#x2F;plonky2&#x2F;issues&#x2F;1#issuecomment-809323437&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Brief history of anonymity in crypto</title>
        <published>2022-10-18T00:00:00+00:00</published>
        <updated>2022-10-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/history-anon/"/>
        <id>https://2π.com/22/history-anon/</id>
        
        <content type="html" xml:base="https://2π.com/22/history-anon/">&lt;h1 id=&quot;brief-history-of-anonymity-in-crypto&quot;&gt;Brief history of anonymity in crypto&lt;&#x2F;h1&gt;
&lt;p&gt;Cryptographic protocols providing anonymity contain zero-knowledge proofs of (some of) the following claims:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Membership.&lt;&#x2F;strong&gt; I am a member of the given set.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;One-shot.&lt;&#x2F;strong&gt; I have not made a claim before in this context.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Message.&lt;&#x2F;strong&gt; And I want to state this.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;pre-history-signatures&quot;&gt;Pre-history: signatures&lt;&#x2F;h2&gt;
&lt;p&gt;Anonymous transactions started with David Chaum&#x27;s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.hit.bme.hu&#x2F;~buttyan&#x2F;courses&#x2F;BMEVIHIM219&#x2F;2009&#x2F;Chaum.BlindSigForPayment.1982.PDF&quot;&gt;eCash&lt;&#x2F;a&gt; (1982) which introduces blind signatures and uses central services to achieve this goal. It uses numbers in a central database to track spend coins, the ancestor of &lt;em&gt;nullifiers&lt;&#x2F;em&gt;. In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cs.tau.ac.il&#x2F;~amnon&#x2F;Papers&#x2F;ST.crypto99.pdf&quot;&gt;ST99&lt;&#x2F;a&gt; this was improved to add a public Merkle tree commitment to spend coins, now called &#x27;serial numbers&#x27;. The blind signatures developed into &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1007&#x2F;3-540-45682-1_32&quot;&gt;ring signatures&lt;&#x2F;a&gt; (2001) which provide the &lt;em&gt;membership&lt;&#x2F;em&gt; claim but not the &lt;em&gt;one-shot&lt;&#x2F;em&gt; claim. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20140529235502&#x2F;https:&#x2F;&#x2F;cryptonote.org&#x2F;whitepaper.pdf&quot;&gt;CryptoNote&lt;&#x2F;a&gt; (2014) introduces what became known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20140116100059&#x2F;https:&#x2F;&#x2F;sourceforge.net&#x2F;mailarchive&#x2F;message.php?msg_id=31813471&quot;&gt;&#x27;stealth addresses&#x27;&lt;&#x2F;a&gt; which anonymise public keys. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getmonero.org&#x2F;&quot;&gt;Monero&lt;&#x2F;a&gt; (2014) combined these techniques to create a decentralized anonymous currency. Ring signatures scale linearly so in practice the anonymity sets are much smaller than the full set of users. Further work like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;196&quot;&gt;BDHKS19&lt;&#x2F;a&gt; improved on ring signatures. See my notes on &lt;a href=&quot;&#x2F;22&#x2F;signatures&quot;&gt;signature schemes&lt;&#x2F;a&gt; for details.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zero-knowledge-proofs&quot;&gt;Zero-knowledge proofs&lt;&#x2F;h2&gt;
&lt;p&gt;Ian Miers et al&#x27;s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;spar.isi.jhu.edu&#x2F;~mgreen&#x2F;ZerocoinOakland.pdf&quot;&gt;Zerocoin&lt;&#x2F;a&gt; (2013) introduces the construction with a zero-knowledge proof of &lt;em&gt;membership&lt;&#x2F;em&gt; and &lt;em&gt;one-shot&lt;&#x2F;em&gt; claims. It&#x27;s basically the construction in it&#x27;s modern form, but using RSA accumulators for the set of spend &#x27;serial numbers&#x27;. The follow up work on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;349&quot;&gt;Zerocash&lt;&#x2F;a&gt; (2014) uses zk-SNARKs and changes the set commitment to a Merkle proof. Zerocash also develops the protocol in many ways. but that has little to do with anonymity and deals mostly with keeping transaction amounts private. The Zerocash protocol is the basis for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;z.cash&#x2F;&quot;&gt;ZCash&lt;&#x2F;a&gt; (2016) which introduces the term &#x27;nullifier&#x27;. Further developments such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;962.pdf&quot;&gt;Zexe&lt;&#x2F;a&gt; (2018) extend the transaction semantics further, but retain the same design of the anonymity construction.&lt;&#x2F;p&gt;
&lt;p&gt;Anonymity on Ethereum started with the inclusion of affordable zero-knowledge proof support in Byzantium (2017) (i.e. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-196&quot;&gt;EIP-196&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-197&quot;&gt;EIP-197&lt;&#x2F;a&gt;). This was motivated in part by ZCash&#x27;s success and a desire to support similar constructions. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;AztecProtocol&#x2F;AZTEC&#x2F;blob&#x2F;7a020f4ced9680f6e4a452fe570671aac0802471&#x2F;AZTEC.pdf&quot;&gt;Aztec protocol&lt;&#x2F;a&gt; (2018) implemented the first Ethereum private transactions. It has an unprecendent protocol for transaction privacy but uses stealth addresses for anonyimity. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tornado.cash&#x2F;&quot;&gt;Tornado Cash&lt;&#x2F;a&gt; (2019) only implements the anonymity part of the ZCash protocol and skips the transaction privacy, greatly simplifying the protocol. Tornado Cash has only two kinds of transactions, deposit and withdrawal, both with the same fixed size.&lt;&#x2F;p&gt;
&lt;p&gt;Note that Monero, ZCash, Aztec and TornadoCash have all since made major changes to their designs. What is described here is the initial version to the extend I could find out.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;semaphore.appliedzkp.org&#x2F;&quot;&gt;Semaphore&lt;&#x2F;a&gt; (2019) takes the anonymity part from Tornado Cash and offers it as a standalone protocol. It introduces the &lt;em&gt;context&lt;&#x2F;em&gt; part of the &lt;em&gt;one-shot&lt;&#x2F;em&gt; claim to make it a reusable system and it introduces the &lt;em&gt;message&lt;&#x2F;em&gt; that allows for applications such as voting.&lt;&#x2F;p&gt;
&lt;p&gt;In retrospect, the hard part was never anonymity but most effort went into transaction privacy. It would seem obvious to unbundle the easy part from the hard part and make anonymity a standalone primitive. So why did it take so long? My guess is the UTXO design of early blockchains made it hard to think of the two as separate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;small&gt;Thanks Ian Miers for answering some questions.&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nullifiers</title>
        <published>2022-10-18T00:00:00+00:00</published>
        <updated>2022-10-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/nullifiers/"/>
        <id>https://2π.com/22/nullifiers/</id>
        
        <content type="html" xml:base="https://2π.com/22/nullifiers/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\p#1{({#1})}
\gdef\mod#1{[{#1}]}
\gdef\set#1{\mathcal{#1}}
\gdef\g{\mathrm{g}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;nullifiers&quot;&gt;Nullifiers&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\g{\mathrm{G}}
\gdef\H{\mathsf{H}}
\gdef\S{\mathcal{S}}
\gdef\HF{\H_{\F}}
\gdef\HG{\H_{\G}}
\gdef\ZKP{\mathsf{ZKP}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In privacy-preserving protocols we sometimes want to prevent users from doing an action twice while keeping them anonymous. This is somewhat paradoxical: the property of “having done the action” is potentially observable: Users could be asked to “try the action again”. This will either succeed or fail, revealing if they did the action before. This splits the users in two groups, thus reducing the anonymity set size. Fortunately, this requires users to actively participate.&lt;&#x2F;p&gt;
&lt;p&gt;We also need to specify the set of users in some way, otherwise people can just create new user-accounts and do the action many times this way. To do the action, users will need to proof that they are members of this set. To preserve anonymity, they need to do this in a zero-knowledge way.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, in some applications we want to attach data to the action. For example in a basic election we want to attach the user&#x27;s preferred choice to the &quot;vote&quot; action. Together, this means we need a zero-knowledge proof that the user:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;is a member of the set of users (&lt;em&gt;membership&lt;&#x2F;em&gt;),&lt;&#x2F;li&gt;
&lt;li&gt;has not done this action before (&lt;em&gt;one-shot&lt;&#x2F;em&gt;), and&lt;&#x2F;li&gt;
&lt;li&gt;wants to attach this data (&lt;em&gt;message&lt;&#x2F;em&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The first and last have simple solutions, but the one-shot does not have an obvious solution. A common solution is to use &lt;em&gt;nullifiers&lt;&#x2F;em&gt;. The general scheme is as follows:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basic-nullifiers&quot;&gt;Basic Nullifiers&lt;&#x2F;h2&gt;
&lt;p&gt;To set up the users create public-private key-pairs &lt;span class=&quot;math math-inline&quot;&gt;(P_i, p_i)&lt;&#x2F;span&gt;, the operator creates a set commitment of the public keys &lt;span class=&quot;math math-inline&quot;&gt;\S = \set{P_i}&lt;&#x2F;span&gt;, and the operator creates a mutable set of nullifiers &lt;span class=&quot;math math-inline&quot;&gt;\mathcal N&lt;&#x2F;span&gt;, initially empty.&lt;&#x2F;p&gt;
&lt;p&gt;To do the action users &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; create a zero-knowledge proof with public inputs &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{action}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{message}&lt;&#x2F;span&gt; and a new value called &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{nullifier}&lt;&#x2F;span&gt; that proofs that&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;it knows the private key &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt; to a public key &lt;span class=&quot;math math-inline&quot;&gt;P_i&lt;&#x2F;span&gt; in the set &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathsf{nullifier} = \H\p{p_i, \mathsf{action}}&lt;&#x2F;span&gt;,&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;To verify a proof the operator&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;verifies the zero-knowledge proof and set commitment &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;rejects if &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{nullifier} ∈ \mathcal N&lt;&#x2F;span&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;inserts &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{nullifier} ∈ \mathcal N&lt;&#x2F;span&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;executes the &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{action}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{message}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;general-structure&quot;&gt;General structure&lt;&#x2F;h2&gt;
&lt;p&gt;For a zero-knowledge proof and its verification I introduce the following notation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
π &amp;amp;= \ZKP\p{
\begin{array}{c}
\text{public inputs} \\
\hdashline
\text{private inputs}
\end{array}
\mid
\text{claim}
}&amp;amp;
\mathsf{Verify}\p{π,\text{public inputs}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;zerocoin-nullifiers&quot;&gt;Zerocoin Nullifiers&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;spar.isi.jhu.edu&#x2F;%7Emgreen&#x2F;ZerocoinOakland.pdf&quot;&gt;MGGR13&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;RSA Accumulators working on primes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c = \mod{g^S ⋅ h^r}_p
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
π = \ZKP\p{
\begin{array}{c}
\S, \mathsf{nullifier} \\
\hdashline
p
\end{array}
\mid
\begin{aligned}
\mathsf{secret} &amp;amp;= \HF\p{p_{\mathsf{trapdoor}}, p_{\mathsf{nullifier}}} \\
\mathsf{id} &amp;amp;= \HF\p{\mathsf{secret}} \\
\mathsf{id} &amp;amp;∈ \S \\
\mathsf{nullifier} &amp;amp;= \HF\p{p_{\mathsf{nullifier}}, \mathsf{context}}
\end{aligned}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With public inputs &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and private inputs &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; compute a proof &lt;span class=&quot;math math-inline&quot;&gt;π&lt;&#x2F;span&gt; of&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P &amp;amp;= \HF\p{s} \\
P &amp;amp;∈ \S \\
N &amp;amp;= \HF\p{m, s}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the paper the set commitment and membership proof is done using RSA accumulators.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;semaphore-nullifiers&quot;&gt;Semaphore Nullifiers&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;semaphore.appliedzkp.org&#x2F;&quot;&gt;Semaphore&lt;&#x2F;a&gt; introduced anonymity as a stand-alone protocol and added the &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{context}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{message}&lt;&#x2F;span&gt; parts to the claim. It uses a &lt;span class=&quot;math math-inline&quot;&gt;\ZKP&lt;&#x2F;span&gt; scheme with field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, a snark-friendly hash function &lt;span class=&quot;math math-inline&quot;&gt;\HF&lt;&#x2F;span&gt; and a set membership proof. In the current &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;semaphore-protocol&quot;&gt;implementation&lt;&#x2F;a&gt; these are Circom-Groth16, Posseidon and Posseidon-Merkle trees.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Setup.&lt;&#x2F;strong&gt; Each users create two random private keys &lt;span class=&quot;math math-inline&quot;&gt;p_{\mathsf{trapdoor}}, p_{\mathsf{nullifier}} ∈ \F&lt;&#x2F;span&gt; and computes identity commitment&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathsf{id} = \HF\p{\HF\p{p_{\mathsf{trapdoor}}, p_{\mathsf{nullifier}}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The verifier constructs a set commitment &lt;span class=&quot;math math-inline&quot;&gt;\S = \set{\mathsf{id}, …}&lt;&#x2F;span&gt; of identity commitments and picks a &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{context} ∈ \F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Claim.&lt;&#x2F;strong&gt; Given a &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{context}&lt;&#x2F;span&gt; the user can decide on a &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{message} ∈ \F&lt;&#x2F;span&gt; and compute the zero-knowledge proof&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
π = \ZKP\p{
\begin{array}{c}
\S,\mathsf{context}, \\
\mathsf{nullifier}, \mathsf{message} \\
\hdashline
p_{\mathsf{trapdoor}}, p_{\mathsf{nullifier}}
\end{array}
\mid
\begin{aligned}
\mathsf{secret} &amp;amp;= \HF\p{p_{\mathsf{trapdoor}}, p_{\mathsf{nullifier}}} \\
\mathsf{id} &amp;amp;= \HF\p{\mathsf{secret}} \\
\mathsf{id} &amp;amp;∈ \S \\
\mathsf{nullifier} &amp;amp;= \HF\p{p_{\mathsf{nullifier}}, \mathsf{context}}
\end{aligned}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; This scheme is re-usable in that the verifier can create new sets &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{context}&lt;&#x2F;span&gt;s while the users can keep using the same private keys and &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{id}&lt;&#x2F;span&gt;s.&lt;&#x2F;p&gt;
&lt;p&gt;The extra &lt;span class=&quot;math math-inline&quot;&gt;p_{\mathsf{trapdoor}}&lt;&#x2F;span&gt; provides some protection against attacks on the snark-friendly hash function &lt;span class=&quot;math math-inline&quot;&gt;\HF&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;semaphore-variants&quot;&gt;Semaphore Variants&lt;&#x2F;h3&gt;
&lt;p&gt;If we use a &#x27;standard&#x27; hash functions for &lt;span class=&quot;math math-inline&quot;&gt;\H&lt;&#x2F;span&gt; like SHA256, then we only need one private key &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; and we can simplify the proof to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
π = \ZKP\p{
\begin{array}{c}
\S,\mathsf{context}, \\
\mathsf{nullifier}, \mathsf{message} \\
\hdashline
p
\end{array}
\mid
\begin{aligned}
\mathsf{id} &amp;amp;= \H\p{p} \\
\mathsf{id} &amp;amp;∈ \S \\
\mathsf{nullifier} &amp;amp;= \H\p{p, \mathsf{context}}
\end{aligned}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This has the additional advantage that the protocol becomes proof-system agnostic. If in the future a different proof system is desirable, the users can keep the same private key &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; and identities &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{id}&lt;&#x2F;span&gt;. If the sets &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; are public they can be recomputed using a proof system friendly set membership protocol.&lt;&#x2F;p&gt;
&lt;p&gt;Another useful variant is to replace &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{id} = \H\p{p}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{id} = p⋅\g&lt;&#x2F;span&gt; for some generator &lt;span class=&quot;math math-inline&quot;&gt;\g&lt;&#x2F;span&gt; of an elliptic curve. This makes the keys and identities to be compatible with existing elliptic curve signature schemes, allowing the creation of anonymity sets &lt;span class=&quot;math math-inline&quot;&gt;\S&lt;&#x2F;span&gt; out of existing sets.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gupta-nullifiers&quot;&gt;Gupta Nullifiers&lt;&#x2F;h2&gt;
&lt;p&gt;Aayush Gupta (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;yush_g&quot;&gt;@yush_g&lt;&#x2F;a&gt;) developed a nullifier scheme that&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;uses existing public keys as identities and,&lt;&#x2F;li&gt;
&lt;li&gt;does not require the ZK-prover to know the private key.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The advantage is that large anonymity sets can be constructed out of existing sets of public keys and that the protocol can be implemented in resource constrained (hardware) wallets. See the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aayushg.com&#x2F;thesis.pdf&quot;&gt;thesis&lt;&#x2F;a&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zk-nullifier-sig&#x2F;zk-nullifier-sig&quot;&gt;repo&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=dZKFG2i1gec&quot;&gt;talk&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Take an elliptic curve &lt;span class=&quot;math math-inline&quot;&gt;\G&lt;&#x2F;span&gt; with scalar field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; and a generator &lt;span class=&quot;math math-inline&quot;&gt;\g&lt;&#x2F;span&gt;, a hash-to-field &lt;span class=&quot;math math-inline&quot;&gt;\HF&lt;&#x2F;span&gt;, a hash-to-curve &lt;span class=&quot;math math-inline&quot;&gt;\HG&lt;&#x2F;span&gt; and a &lt;span class=&quot;math math-inline&quot;&gt;\ZKP&lt;&#x2F;span&gt; with field &lt;span class=&quot;math math-inline&quot;&gt;\F&amp;#39;&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Setup.&lt;&#x2F;strong&gt; Each users wallet creates a private key &lt;span class=&quot;math math-inline&quot;&gt;p ∈ \F&lt;&#x2F;span&gt; and public key &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{id} = p ⋅ \g&lt;&#x2F;span&gt;. The verifier constructs a set commitment &lt;span class=&quot;math math-inline&quot;&gt;\S = \set{\mathsf{id}, …}&lt;&#x2F;span&gt; and decides on a &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{context}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Claim.&lt;&#x2F;strong&gt; Given a &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{context}&lt;&#x2F;span&gt; the user can decide on a &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{message} ∈ \F&amp;#39;&lt;&#x2F;span&gt; and interact with the wallet holding the private key as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{|c|c|}
\text{Wallet} &amp;amp; \text{User} \\
\hline
&amp;amp; H = \HG\p{\mathsf{id}, \mathsf{context}} \\
\mathsf{nullifier} = p ⋅ H &amp;amp; &amp;amp; \\
r ∈ \F &amp;amp; &amp;amp; \\
r⋅\g &amp;amp; &amp;amp; \\
r⋅H &amp;amp; &amp;amp; \\
&amp;amp; c = \HF\p{\begin{array}{c}
    \g , \mathsf{id}, H, \mathsf{nullifier}, \\
     r⋅\g , r⋅H
    \end{array}
}\\
s = r + c ⋅ p &amp;amp; &amp;amp; \\
&amp;amp;
π = \ZKP\p{
\begin{array}{c}
\S,\mathsf{context}, \\
\mathsf{nullifier}, \mathsf{message} \\
\hdashline
\mathsf{id},c,s
\end{array}
}
\\
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the &lt;span class=&quot;math math-inline&quot;&gt;\ZKP&lt;&#x2F;span&gt; proofs the claim&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
π = \ZKP\p{
\begin{array}{c}
\S,\mathsf{context}, \\
\mathsf{nullifier}, \mathsf{message} \\
\hdashline
\mathsf{id},c,s
\end{array}
\mid
\begin{aligned}
\mathsf{id} &amp;amp;∈ \S \\
c &amp;amp;= \HF\p{\begin{array}{c}
    \g, \mathsf{id}, H, \mathsf{nullifier}, \\
    s⋅\g - c⋅\mathsf{id},  \\
    s⋅H - c⋅\mathsf{nullifier}
\end{array}}  \\
\end{aligned}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Completeness follows because the last two arguments to &lt;span class=&quot;math math-inline&quot;&gt;\HG&lt;&#x2F;span&gt; in the &lt;span class=&quot;math math-inline&quot;&gt;\ZKP&lt;&#x2F;span&gt; expand to equal those from the construction of &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{ll}
s⋅\g - c⋅\mathsf{id} &amp;amp;= \p{r + c⋅p} ⋅ \g - c⋅\p{p⋅\g} = r⋅\g \\
s⋅H - c⋅\mathsf{nullifier} \mskip{-12mu} &amp;amp;= \p{r + c⋅p} ⋅H - c ⋅ \p{p ⋅ H} = r⋅H
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;for soundness, anonymity, security of private key and other properties see the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aayushg.com&#x2F;thesis.pdf&quot;&gt;thesis&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;https:&#x2F;&#x2F;worldcoin.slack.com&#x2F;archives&#x2F;C01HKLX1MPZ&#x2F;p1671775978914459&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;zcash&#x2F;zips&#x2F;issues&#x2F;26#issuecomment-198932249&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mathemagic: exp and ln</title>
        <published>2022-10-03T00:00:00+00:00</published>
        <updated>2022-10-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/exp-ln/"/>
        <id>https://2π.com/22/exp-ln/</id>
        
        <content type="html" xml:base="https://2π.com/22/exp-ln/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{({#1})}
\gdef\floor#1{\lfloor{#1}\rfloor}
\gdef\dummyarg{\operatorname{-}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;mathemagic-exp-and-ln&quot;&gt;Mathemagic: exp and ln&lt;&#x2F;h1&gt;
&lt;p&gt;After basic arithmetic, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exponential_function&quot;&gt;exponential function&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\exp\p{\dummyarg}&lt;&#x2F;span&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Natural_logarithm&quot;&gt;natural logarithm&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\ln\p{\dummyarg}&lt;&#x2F;span&gt; are the most useful functions to implement because they allow for a range of other operations:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a ⋅ b &amp;amp;= \exp\p{\ln\p a + \ln\p b} \\
a &#x2F; b &amp;amp;= \exp\p{\ln\p a - \ln\p b} \\
a^b &amp;amp;= \exp\p{b ⋅ \ln\p{a}} \\
\log_b a &amp;amp;= \ln\p{a} &#x2F; \ln\p{b} \\
\sqrt{a} &amp;amp;= \exp\p{½ ⋅ \ln\p{a}} \\
\sqrt[3]{a} &amp;amp;= \exp\p{⅓ ⋅ \ln\p{a}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since you can implement multiplication and division, you just need &lt;span class=&quot;math math-inline&quot;&gt;+, -, \exp&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\ln&lt;&#x2F;span&gt; to construct a full set of operations. But usually there are more efficient methods for multiplication and division available. You can also construct more efficient dedicated operations for square roots and other functions, see my &lt;a href=&quot;&#x2F;22&#x2F;approximation&quot;&gt;introduction to approximation theory&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The choice of natural basis &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{e} = 2.71828…&lt;&#x2F;span&gt; is conventional, but actually doesn&#x27;t matter much. The above relations are equally valid in any base and the implementations just as efficient. The natural basis does have advantages in analysis due to nicer differential identities.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fixed-point-arithmetic&quot;&gt;Fixed-point arithmetic&lt;&#x2F;h2&gt;
&lt;p&gt;So far we used real numbers &lt;span class=&quot;math math-inline&quot;&gt;ℝ&lt;&#x2F;span&gt;, but in our target platform we will use 256-bit integers &lt;span class=&quot;math math-inline&quot;&gt;[-2^{255}, 2^{255})&lt;&#x2F;span&gt;. Using integers directly is not very useful because they can not represent fractional values. To solve this, we will use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fixed-point_arithmetic&quot;&gt;fixed-point arithmetic&lt;&#x2F;a&gt;, that is, we treat each number as if it is in units of a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Long_and_short_scales&quot;&gt;quintillionth&lt;&#x2F;a&gt; (&lt;span class=&quot;math math-inline&quot;&gt;10^{-18}&lt;&#x2F;span&gt;). This is the same as putting a fixed decimal point before the 18-th digit, hence the name  “fixed point”. To convert between integers and the real numbers they represent we define these to functions:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathtt{to\_fix}\p{x} : ℝ → ℤ &amp;amp;= \floor{½ + 10^{18} ⋅ x} \\
\mathtt{from\_fix}\p{x}: ℤ → ℝ &amp;amp;= \frac{x}{10^{18}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{to\_fix}&lt;&#x2F;span&gt; function looses information by rounding. Fixed-point is an approximation method and it&#x27;s important to do the straightforward-but-tedious error analysis to make sure this error is tolerable. In the above definitions I used round-to-nearest. Often it helps to bias the error in a safe direction, for example in finance you may want to &lt;em&gt;round down&lt;&#x2F;em&gt; for amounts you send out and &lt;em&gt;round up&lt;&#x2F;em&gt; for amounts you receive.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fixed-point-exponential-function&quot;&gt;Fixed-point exponential function&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s implement a fixed-point exponential function &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{expWad}&lt;&#x2F;span&gt;. Conversion to fixed point gives us:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathtt{expWad}\p{x} = \mathtt{to\_fix}\p{ \exp\p{\mathtt{from\_fix}\p{x} }  }= \floor{½ + 10^{18} ⋅ \exp\p{\frac{x}{10^{18}}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The implementation works as follows&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Handle underflow and overflow cases.&lt;&#x2F;li&gt;
&lt;li&gt;Convert from &lt;span class=&quot;math math-inline&quot;&gt;10^{-18}&lt;&#x2F;span&gt; fix point to &lt;span class=&quot;math math-inline&quot;&gt;2^{-96}&lt;&#x2F;span&gt; fix point for increased intermediate precision and more efficient multiplications.&lt;&#x2F;li&gt;
&lt;li&gt;Further reduce the input range to &lt;span class=&quot;math math-inline&quot;&gt;(-½ \ln 2, ½ \ln 2)&lt;&#x2F;span&gt; by factoring out powers of two
from the result. We will add those back using a shift in the end.&lt;&#x2F;li&gt;
&lt;li&gt;Approximate &lt;span class=&quot;math math-inline&quot;&gt;\exp&lt;&#x2F;span&gt; using a &lt;span class=&quot;math math-inline&quot;&gt;(6,7)&lt;&#x2F;span&gt;-term rational function evaluated in &lt;span class=&quot;math math-inline&quot;&gt;2^{-96}&lt;&#x2F;span&gt; fixed point.&lt;&#x2F;li&gt;
&lt;li&gt;Convert back to &lt;span class=&quot;math math-inline&quot;&gt;10^{-18}&lt;&#x2F;span&gt; fixed point and add powers of two.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;A lot of the scaling factors can be merged. I was worried that the &lt;span class=&quot;math math-inline&quot;&gt;10^{-18}&lt;&#x2F;span&gt; base would be less efficient, but it turns out the conversion cost is negligible as it can mostly be absorbed in other operations. Both the denominator and numerator of the rational function are made &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Monic_polynomial&quot;&gt;monic&lt;&#x2F;a&gt; to save a two multiplications. The denominator is evaluated using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Horner%27s_method&quot;&gt;Horner&#x27;s method&lt;&#x2F;a&gt;, but the numerator uses a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_evaluation#Evaluation_with_preprocessing&quot;&gt;preprocessed method&lt;&#x2F;a&gt; to save another multiplication. Preprocessing did not seem effective for the denominator, potentially due to some suboptimality in stack handling. There might be some slight room for improvement there.&lt;&#x2F;p&gt;
&lt;p&gt;Except for the range reduction in step 3, this strategy is very generic and can be applied to any smooth single-variable function.&lt;&#x2F;p&gt;
&lt;p&gt;Care is taken to make sure that &lt;span class=&quot;math math-inline&quot;&gt;\exp\p{0}&lt;&#x2F;span&gt; is exactly &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; as one would expect. As far as I know the function is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Monotonic_function&quot;&gt;monotonic&lt;&#x2F;a&gt;, but I have not proven this and there may be exceptions. The maximum absolute error on the reduced range is designed to be &lt;span class=&quot;math math-inline&quot;&gt;10^{-20}&lt;&#x2F;span&gt;. Over the whole domain this a relative error of at most &lt;span class=&quot;math math-inline&quot;&gt;10^{-20}&lt;&#x2F;span&gt;. So for small values the result is near perfect. It takes &lt;span class=&quot;math math-inline&quot;&gt;411&lt;&#x2F;span&gt; gas.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Math {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; Computes the exponential function in 1e18 fixed point using 411 gas.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function expWad(int256 x) internal pure returns (int256 r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        unchecked {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; When the result is &amp;lt; 0.5 we return zero. This happens when&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; x &amp;lt;= floor(log(0.5e18) * 1e18) ~ -42e18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            if (x &amp;lt;= -42139678854452767551) return 0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; When the result is &amp;gt; (2**255 - 1) &#x2F; 1e18 we can not represent it as an&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; int. This happens when x &amp;gt;= floor(log((2**255 - 1) &#x2F; 1e18) * 1e18) ~ 135.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            if (x &amp;gt;= 135305999368893231589) revert(&amp;quot;EXP_OVERFLOW&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; for more intermediate precision and a binary basis. This base conversion&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; is a multiplication by 1e18 &#x2F; 2**96 = 5**18 &#x2F; 2**78.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x = (x &amp;lt;&amp;lt; 78) &#x2F; 5**18;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; of two such that exp(x) = exp(x&amp;#39;) * 2**k, where k is an integer.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; Solving this gives k = round(x &#x2F; log(2)) and x&amp;#39; = x - k * log(2).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            int256 k = ((x &amp;lt;&amp;lt; 96) &#x2F; 54916777467707473351141471128 + 2**95) &amp;gt;&amp;gt; 96;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x = x - k * 54916777467707473351141471128;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; k is in the range [-61, 195].&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; Evaluate using a (6, 7)-term rational approximation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; p is made monic, we&amp;#39;ll multiply by a scale factor later.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            int256 y = x + 1346386616545796478920950773328;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            y = ((y * x) &amp;gt;&amp;gt; 96) + 57155421227552351082224309758442;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            int256 p = y + x - 94201549194550492254356042504812;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p = ((p * y) &amp;gt;&amp;gt; 96) + 28719021644029726153956944680412240;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p = p * x + (4385272521454847904659076985693276 &amp;lt;&amp;lt; 96);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; We leave p in 2**192 basis so we don&amp;#39;t need to scale it back up for the division.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            int256 q = x - 2855989394907223263936484059900;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 50020603652535783019961831881945;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) - 533845033583426703283633433725380;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 3604857256930695427073651918091429;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) - 14423608567350463180887372962807573;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 26449188498355588339934803723976023;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &#x2F;&#x2F; Div in assembly because solidity adds a zero check despite the unchecked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &#x2F;&#x2F; The q polynomial won&amp;#39;t have zeros in the domain as all its roots are complex.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &#x2F;&#x2F; No scaling is necessary because p is already 2**96 too large.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                r := sdiv(p, q)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; r should be in the range (0.09, 0.25) * 2**96.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; We now need to multiply r by:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; * the scale factor s = ~6.031367120.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; * the 2**k factor from the range reduction.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; * the 1e18 &#x2F; 2**96 factor for base conversion.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; We do this all at once, with an intermediate result in 2**213&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; basis, so the final right shift is always by a positive amount.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) &amp;gt;&amp;gt; uint256(195 - k));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;fixed-point-natural-logarithm&quot;&gt;Fixed-point natural logarithm&lt;&#x2F;h2&gt;
&lt;p&gt;The implementation of &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{lnWad}&lt;&#x2F;span&gt;  is nearly identical to &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{expWad}&lt;&#x2F;span&gt; except for a different range reduction strategy and a different &lt;span class=&quot;math math-inline&quot;&gt;(8,8)&lt;&#x2F;span&gt;-term rational approximation. The reduction strategy is to factor out powers of two from the input&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ln\p{x} = \ln\p{2^k ⋅ x&amp;#39;} = k ⋅ \ln\p{2} + \ln{x&amp;#39;}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;k = \mathtt{log2}\p{x} = \floor{\log_2 x}&lt;&#x2F;span&gt;. See below for the implementation of &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{log2}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Care is taken to make sure &lt;span class=&quot;math math-inline&quot;&gt;\ln\p{1}&lt;&#x2F;span&gt; is exactly &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; as one would expect. As before, as far as I know the the function is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Monotonic_function&quot;&gt;monotonic&lt;&#x2F;a&gt;, but I have not proven this and there may be exceptions. The maximum absolute error over the whole range is about &lt;span class=&quot;math math-inline&quot;&gt;10^{-18}&lt;&#x2F;span&gt;, which is near perfect. It takes &lt;span class=&quot;math math-inline&quot;&gt;614&lt;&#x2F;span&gt; gas which can be reduced to &lt;span class=&quot;math math-inline&quot;&gt;585&lt;&#x2F;span&gt; by inlining &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{log2}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Math {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; Computes the natural logarithm in 1e18 fixed point using 675 gas.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; Reverts if x is negative or zero.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function lnWad(int256 x) internal pure returns (int256 r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        unchecked {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            require(x &amp;gt; 0, &amp;quot;UNDEFINED&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; We want to convert x from 10**18 fixed point to 2**96 fixed point.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; We do this by multiplying by 2**96 &#x2F; 10**18. But since&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; ln(x * C) = ln(x) + ln(C), we can simply do nothing here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; and add ln(2**96 &#x2F; 10**18) at the end.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; Reduce range of x to (1, 2) * 2**96&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; ln(2^k * x) = k * ln(2) + ln(x)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            int256 k = int256(log2(uint256(x))) - 96;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x &amp;lt;&amp;lt;= uint256(159 - k);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x = int256(uint256(x) &amp;gt;&amp;gt; 159);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; Evaluate using a (8, 8)-term rational approximation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; p is made monic, we will multiply by a scale factor later.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            int256 p = x + 3273285459638523848632254066296;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p = ((p * x) &amp;gt;&amp;gt; 96) + 24828157081833163892658089445524;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p = ((p * x) &amp;gt;&amp;gt; 96) + 43456485725739037958740375743393;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p = ((p * x) &amp;gt;&amp;gt; 96) - 11111509109440967052023855526967;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p = ((p * x) &amp;gt;&amp;gt; 96) - 45023709667254063763336534515857;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p = ((p * x) &amp;gt;&amp;gt; 96) - 14706773417378608786704636184526;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            p = p * x - (795164235651350426258249787498 &amp;lt;&amp;lt; 96);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; We leave p in 2**192 basis so we don&amp;#39;t need to scale it back up for the division.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; q is monic by convention.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            int256 q = x + 5573035233440673466300451813936;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 71694874799317883764090561454958;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 283447036172924575727196451306956;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 401686690394027663651624208769553;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 204048457590392012362485061816622;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 31853899698501571402653359427138;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            q = ((q * x) &amp;gt;&amp;gt; 96) + 909429971244387300277376558375;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &#x2F;&#x2F; Div in assembly because solidity adds a zero check despite the unchecked.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &#x2F;&#x2F; The q polynomial is known not to have zeros in the domain.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &#x2F;&#x2F; No scaling required because p is already 2**96 too large.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                r := sdiv(p, q)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; r is in the range (0, 0.125) * 2**96&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; Finalization, we need to:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; * multiply by the scale factor s = 5.549…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; * add ln(2**96 &#x2F; 10**18)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; * add k * ln(2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; * multiply by 10**18 &#x2F; 2**96 = 5**18 &amp;gt;&amp;gt; 78&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; mul s * 5e18 * 2**96, base is now 5**18 * 2**192&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r *= 1677202110996718588342820967067443963516166;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; add ln(2) * k * 5e18 * 2**192&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; add ln(2**96 &#x2F; 10**18) * 5e18 * 2**192&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r += 600920179829731861736702779321621459595472258049074101567377883020018308;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; base conversion: mul 2**18 &#x2F; 2**192&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r &amp;gt;&amp;gt;= 174;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;discrete-binary-logarithm&quot;&gt;Discrete binary logarithm&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{lnWad}&lt;&#x2F;span&gt; requires the discrete &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Binary_logarithm&quot;&gt;binary logarithm&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{log2}&lt;&#x2F;span&gt;, also known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Find_first_set&quot;&gt;find last set&lt;&#x2F;a&gt; because it returns the index of the most significant non-zero bit.&lt;&#x2F;p&gt;
&lt;p&gt;I &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;experiment-solexp&#x2F;blob&#x2F;bbc164fb5ec078cfccf3c71b521605106bfae00b&#x2F;src&#x2F;FixedPointMathLib.sol#L11&quot;&gt;experimented&lt;&#x2F;a&gt; with a de Bruijn based version but a simpler SWAR approach was more efficient. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;optimizoor&quot;&gt;Vectorized&lt;&#x2F;a&gt; did get the de Bruijn approach to perform better by 13 gas, so I will present &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Vectorized&#x2F;solady&#x2F;blob&#x2F;25e885141f5632a3a4ae2cc6d5e799883baaa3f8&#x2F;src&#x2F;utils&#x2F;LibBit.sol#L8&quot;&gt;his version&lt;&#x2F;a&gt; here, which takes &lt;span class=&quot;math math-inline&quot;&gt;191&lt;&#x2F;span&gt; gas:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Math {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; Compute the discrete binary logarithm of x using 191 gas.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &#x2F;&#x2F; Requires x to be non-zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function log2(uint256 x) internal pure returns (uint256 r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r := or(r, shl(5, lt(0xffffffff, shr(r, x))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &#x2F;&#x2F; For the remaining 32 bits, use a De Bruijn lookup.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x := shr(r, x)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x := or(x, shr(1, x))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x := or(x, shr(2, x))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x := or(x, shr(4, x))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x := or(x, shr(8, x))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            x := or(x, shr(16, x))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r := or(r, byte(shr(251, mul(x, shl(224, 0x07c4acdd))),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h2&gt;
&lt;p&gt;The code in this post can be used under an MIT License. An early version with the rational derivation code is in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;experiment-solexp&quot;&gt;an experiment repo&lt;&#x2F;a&gt;. A polished and tested version lives in the Solmate &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;transmissions11&#x2F;solmate&#x2F;blob&#x2F;ed67feda67b24fdeff8ad1032360f0ee6047ba0a&#x2F;src&#x2F;utils&#x2F;FixedPointMathLib.sol#L34&quot;&gt;repo&lt;&#x2F;a&gt; to be included in v7. It has already seen use in Paradigm&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.paradigm.xyz&#x2F;2022&#x2F;08&#x2F;vrgda#implementation&quot;&gt;VRGDA&lt;&#x2F;a&gt; library and their projects &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;artgobblers.com&quot;&gt;ArtGobblers&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.0xmonaco.com&quot;&gt;0xMonaco&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you like this you may also enjoy my &lt;a href=&quot;&#x2F;21&#x2F;muldiv&quot;&gt;muldiv&lt;&#x2F;a&gt; and &lt;a href=&quot;&#x2F;17&#x2F;full-mul&quot;&gt;full-mul&lt;&#x2F;a&gt; implementations and my &lt;a href=&quot;&#x2F;22&#x2F;approximation&quot;&gt;introduction to approximation theory&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Number Theoretic Transform Argument</title>
        <published>2022-09-01T00:00:00+00:00</published>
        <updated>2022-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/ntt-argument/"/>
        <id>https://2π.com/22/ntt-argument/</id>
        
        <content type="html" xml:base="https://2π.com/22/ntt-argument/">&lt;h1 id=&quot;number-theoretic-transform-argument&quot;&gt;Number Theoretic Transform Argument&lt;&#x2F;h1&gt;
&lt;p&gt;Given two polynomials &lt;span class=&quot;math math-inline&quot;&gt;P, Q ∈ \mathbb{F}[X]&#x2F;X^n&lt;&#x2F;span&gt;, we can write them as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X) &amp;amp;= \sum_i p_i ⋅ L_i(X) &amp;amp;
Q(X) &amp;amp;= \sum_i q_i ⋅ L_i(X)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;p_i, q_i ∈ \mathbb{F}^n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;L_i(X)&lt;&#x2F;span&gt; are the Lagrange polynomials on &lt;span class=&quot;math math-inline&quot;&gt;\{ \omega_n^i \}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;ω_n&lt;&#x2F;span&gt; is an &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;th-root of unity. We want to proof that &lt;span class=&quot;math math-inline&quot;&gt;q_i&lt;&#x2F;span&gt; is the number theoretic transform of &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt;, that is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
q_i = \sum_j p_j ⋅ ω_n^{i⋅j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is equivalent to proving that &lt;span class=&quot;math math-inline&quot;&gt;Q(X) = \sum_i p_i ⋅ X^i&lt;&#x2F;span&gt;. To see this note that the Vandermonde matrix for the basis is also the Fourier matrix:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
ω_n^0 &amp;amp; ω_n^0 &amp;amp; ω_n^0 &amp;amp; ⋯ &amp;amp; ω_n^0 \\
ω_n^0 &amp;amp; ω_n^1 &amp;amp; ω_n^2 &amp;amp; ⋯ &amp;amp; ω_n^{n-1} \\
ω_n^0 &amp;amp; ω_n^2 &amp;amp; ω_n^4 &amp;amp; ⋯ &amp;amp; ω_n^{2(n-1)} \\
⋮ &amp;amp; ⋮ &amp;amp; ⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\
ω_n^0 &amp;amp; ω_n^{n-1} &amp;amp; ω_n^{2(n-1)} &amp;amp; ⋯ &amp;amp; ω_n^{(n-1)^2} \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;argument&quot;&gt;Argument&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;Commit to &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Sample random &lt;span class=&quot;math math-inline&quot;&gt;τ&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Commit &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-term polynomial &lt;span class=&quot;math math-inline&quot;&gt;H(X)&lt;&#x2F;span&gt; containing progressive Horner evaluations:&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{array}{l l}
P(ω_n^i) &amp;amp; H(ω_n^i) \\
\hline
p_0 &amp;amp; p_0 + τ ⋅ (p_1 + τ ⋅ (p_2+⋯ \\
p_1 &amp;amp; p_1 + τ ⋅ (p_2 + τ ⋅ (p_3+⋯ \\
⋮ &amp;amp; ⋮ \\
p_{n - 3} &amp;amp; p_{n - 3} + τ ⋅ (p_{n - 2} + τ ⋅ p_{n - 1}) \\
p_{n - 2} &amp;amp; p_{n - 2} + τ ⋅ p_{n - 1} \\
p_{n - 1} &amp;amp; p_{n - 1} \\
\end{array}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Now proof the constraints&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
&amp;amp;H(X) = P(X) + τ ⋅ H(ω_n ⋅ X) &amp;amp;&amp;amp; \forall X ∈ \{ω_n^0, …, ω_n^{n-2}\} \\
&amp;amp;H(ω_n^{n-1}) = P(ω_n^{n-1}) \\
&amp;amp;Q(τ) = H(ω_n^0)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Elliptic curve pairings</title>
        <published>2022-07-14T00:00:00+00:00</published>
        <updated>2022-07-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/pairings/"/>
        <id>https://2π.com/22/pairings/</id>
        
        <content type="html" xml:base="https://2π.com/22/pairings/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\p#1{({#1})}
\gdef\dummyarg{\operatorname{-}}
\gdef\e{\mathrm{e}}
\gdef\g{\mathrm{g}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;elliptic-curve-pairings&quot;&gt;Elliptic curve pairings&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\g{\mathrm{G}}
\gdef\e{\mathrm{e}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_3&lt;&#x2F;span&gt; be elliptic curve groups with the same scalar field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, generators &lt;span class=&quot;math math-inline&quot;&gt;\g_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\g_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\g_3&lt;&#x2F;span&gt; and a &lt;em&gt;pairing&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\e: \G_1 × \G_2 → \G_3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A pairing is a function that satisfies &lt;span class=&quot;math math-inline&quot;&gt;\e(a ⋅ A, b ⋅ B) = a ⋅ b ⋅ \e(A, B)&lt;&#x2F;span&gt; and is not the trivial solution &lt;span class=&quot;math math-inline&quot;&gt;\e(\dummyarg,\dummyarg) = 0&lt;&#x2F;span&gt;. From this it follows that &lt;span class=&quot;math math-inline&quot;&gt;\e(A_1 + A_2, B) = \e(A_1, B) + \e(A_2, B)&lt;&#x2F;span&gt; and other useful linear properties.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The pairing is symmetrical in &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; so protocols also work with groups and pairing arguments swapped. This is useful if one group has better performance than the other.&lt;&#x2F;p&gt;
&lt;p&gt;Finding a pairing that satisfy the requirements is challenging, especially when there are additional constraints such as having large binary roots of unity in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;. Different families of solutions have been found:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MNT, Miyaji-Nakabayashi-Takano (2001; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dspace.jaist.ac.jp&#x2F;dspace&#x2F;bitstream&#x2F;10119&#x2F;4432&#x2F;1&#x2F;73-48.pdf&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;BLS, Barreto-Lynn-Scott (2002; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2002&#x2F;088&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;BN, Barreto-Naehrig (2005; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2005&#x2F;133.pdf&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;KSS, Kachisa-Schaefer-Scott (2008; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;chapter&#x2F;10.1007&#x2F;978-3-540-85538-5_9&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Two important specific solutions are&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;scipr-lab&#x2F;libff&#x2F;blob&#x2F;674e437446216ade040194105b4fc9ff3d8db6f1&#x2F;libff&#x2F;algebra&#x2F;curves&#x2F;alt_bn128&#x2F;alt_bn128.sage&quot;&gt;&lt;code&gt;ALT_BN128&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; (2015). Developed by &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.scipr-lab.org&#x2F;&quot;&gt;SCIPR-lab&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;electriccoin.co&#x2F;blog&#x2F;new-snark-curve&#x2F;&quot;&gt;&lt;code&gt;BLS12-381&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; (2017). Developed by Sean Bowe for ZCash.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The 128 in &lt;code&gt;alt_bn128&lt;&#x2F;code&gt; revers to the target security level, but it was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;moderncrypto.org&#x2F;mail-archive&#x2F;curves&#x2F;2016&#x2F;000740.html&quot;&gt;since found&lt;&#x2F;a&gt; that it is &quot;closer to 96 or so&quot;. &lt;code&gt;BLS12-381&lt;&#x2F;code&gt; development was in part motivated to address this and targets 128 bit security.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alt-bn128&quot;&gt;Alt-BN128&lt;&#x2F;h2&gt;
&lt;p&gt;Also known as BN254.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
r = 21888242871839275222246405745257275088548364400416034343698204186575808495617
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
q = 21888242871839275222246405745257275088696311157297823662689037894645226208583
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Generator &lt;span class=&quot;math math-inline&quot;&gt;5&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To quickly check a a large number of pairings of the form &lt;span class=&quot;math math-inline&quot;&gt;\e(A_i, B) = \e(C_i, \g_2)&lt;&#x2F;span&gt; we can take a random linear combination: Generate random &lt;span class=&quot;math math-inline&quot;&gt;r_i ∈ \F^n&lt;&#x2F;span&gt;, compute &lt;span class=&quot;math math-inline&quot;&gt;A = \sum_i r_i ⋅ A_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;C = \sum_i r_i ⋅ C_i&lt;&#x2F;span&gt; and check &lt;span class=&quot;math math-inline&quot;&gt;\e\p{A, B} = \e\p{C, \G_2}&lt;&#x2F;span&gt;. We can repeat this trick to aggregate multiple values of &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Groth16</title>
        <published>2022-07-12T00:00:00+00:00</published>
        <updated>2022-07-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/groth16/"/>
        <id>https://2π.com/22/groth16/</id>
        
        <content type="html" xml:base="https://2π.com/22/groth16/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\Z{\mathbb{Z}}
\gdef\F{\mathbb{F}}
\gdef\p#1{({#1})}
\gdef\e{\mathrm{e}}
\gdef\g{\mathrm{g}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;groth16&quot;&gt;Groth16&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\g{\mathrm{G}}
\gdef\e{\mathrm{e}}
\gdef\Z{\mathrm{Z}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Notes on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2016&#x2F;260&quot;&gt;Groth16&lt;&#x2F;a&gt; proof system. An evergreen from the era of R1CS with extensive and widely used tooling such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zkcrypto&#x2F;bellman&quot;&gt;bellman&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zokrates.github.io&quot;&gt;zokrates&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;iden3.io&#x2F;circom&quot;&gt;circom&lt;&#x2F;a&gt;. It is the proof system currently used by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;z.cash&#x2F;&quot;&gt;ZCash&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hermez.io&quot;&gt;Hermez&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;zkga.me&#x2F;&quot;&gt;DarkForest&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tornado.cash&#x2F;&quot;&gt;TornadoCash&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;semaphore.appliedzkp.org&#x2F;&quot;&gt;Semaphore&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;loopring.io&#x2F;&quot;&gt;Loopring&lt;&#x2F;a&gt;, and others.&lt;&#x2F;p&gt;
&lt;p&gt;Pick an &lt;a href=&quot;&#x2F;22&#x2F;pairings&quot;&gt;elliptic curve pairing&lt;&#x2F;a&gt;.
Let &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_3&lt;&#x2F;span&gt; be groups with the same scalar field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, generators &lt;span class=&quot;math math-inline&quot;&gt;\g_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\g_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\g_3&lt;&#x2F;span&gt; and a &lt;em&gt;pairing&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\e: \G_1 × \G_2 → \G_3&lt;&#x2F;span&gt;. For a multiset of &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt; of elements from &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt; define the zero polynomial &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\mathcal S} ∈ \F[X]&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Z_{\mathcal S}(X) = \prod_{s ∈ \mathcal S} \p{X - s}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;circuit&quot;&gt;Circuit&lt;&#x2F;h2&gt;
&lt;p&gt;To proof your program in Groth16 you first need to convert it to an &lt;em&gt;R1CS&lt;&#x2F;em&gt; constraint system. A classic introduction to this transformation is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@VitalikButerin&#x2F;quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649&quot;&gt;Vitalik&#x27;s writup&lt;&#x2F;a&gt;. An early formal definition is in &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;groth16&#x2F;%5Dhttps:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;507.pdf&quot;&gt;BCGTV13&lt;&#x2F;a&gt; appendix E.1. There are many proof systems besides Groth16 that use it and for a while it looked to become a standard format, until Starks and Plonks took over. To create R1CSs we now have high level programming languages and compilers like Circom.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;r1cs&quot;&gt;R1CS&lt;&#x2F;h3&gt;
&lt;p&gt;A rank-1 constraint system (R1CS) with &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; variables and &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; constraints and &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; public inputs has a witness vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w ∈ \F^n&lt;&#x2F;span&gt;. By convention, the first &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; elements of &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; are the public input and the first public input &lt;span class=&quot;math math-inline&quot;&gt;w_0&lt;&#x2F;span&gt; is fixed to &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;. The &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; constraints in R1CS are a product equation between three inner products:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(\vec w ⋅ \vec a_i) ⋅ (\vec w ⋅ \vec b_i) = \vec w ⋅ \vec c_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where vectors &lt;span class=&quot;math math-inline&quot;&gt;(\vec a_i, \vec b_i, \vec c_i) ∈ \F^{3⋅n}&lt;&#x2F;span&gt; specify the constraint. The constraint vectors are usually very sparse, typically only nonzero for a single or few values. These constraint vectors can be aggregated in &lt;span class=&quot;math math-inline&quot;&gt;n × m&lt;&#x2F;span&gt; matrices so that the whole constraint system can be concisely written using an element-wise product&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\vec w ⋅ A} ∘ \p{\vec w ⋅ B} = \vec w ⋅ C
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;polynomials-qap&quot;&gt;Polynomials (QAP)&lt;&#x2F;h3&gt;
&lt;p&gt;We fix a basis &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \F^m&lt;&#x2F;span&gt; and for each constraint define polynomials such that &lt;span class=&quot;math math-inline&quot;&gt;A_i(x_j) = A_{ij}&lt;&#x2F;span&gt;, similarly for &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt;. Then define &lt;span class=&quot;math math-inline&quot;&gt;A(X) = \sum_{i ∈ [0,n)} w_i ⋅ A_i(X)&lt;&#x2F;span&gt;, similarly for &lt;span class=&quot;math math-inline&quot;&gt;B, C&lt;&#x2F;span&gt;. Now the constraints are equivalent to &lt;span class=&quot;math math-inline&quot;&gt;A(x_i) ⋅ B(x_i) = C(x_i)&lt;&#x2F;span&gt;. This form is called a quadratic arithmetic program (QAP) and can be verified by the existence of a low-degree &lt;span class=&quot;math math-inline&quot;&gt;H(X)&lt;&#x2F;span&gt; that satisfies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A(X) ⋅ B(X) - C(X) = H(X) ⋅ \Z_{\vec x}(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To construct &lt;span class=&quot;math math-inline&quot;&gt;H(X)&lt;&#x2F;span&gt; divide the left-hand-side by &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\vec x}(X)&lt;&#x2F;span&gt;, which will only be &#x27;exact&#x27; (precisely, a low-degree polynomial) if the constraints hold. The polynomial equation itself is efficiently verified by evaluating at a random value &lt;span class=&quot;math math-inline&quot;&gt;τ&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;811&quot;&gt;BKSV20&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;geometryresearch.xyz&#x2F;notebook&#x2F;groth16-malleability&quot;&gt;GR22&lt;&#x2F;a&gt; it is shown that for Groth16 there exists potential malleability on the public input unless certain linear independence requirements are met. An easy way to meet these requirements is to add additional constraints &lt;span class=&quot;math math-inline&quot;&gt;w_i ⋅ 0 = 0&lt;&#x2F;span&gt; for all public inputs. This is done implicitly by the Arkworks and SnarkJS implementations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trusted-setup&quot;&gt;Trusted setup&lt;&#x2F;h2&gt;
&lt;p&gt;Groth16 requires some setup to create a shared set of values known as the &lt;em&gt;common reference string&lt;&#x2F;em&gt;. This setup can be split in two parts, one generic and one specific to the circuit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;powers-of-tau&quot;&gt;Powers of Tau&lt;&#x2F;h3&gt;
&lt;p&gt;Pick an upper bound &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; for the number of constraints. Generate random values &lt;span class=&quot;math math-inline&quot;&gt;τ, α, β&lt;&#x2F;span&gt; and compute:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{τ^0, τ^1, τ^2, …, τ^{2 ⋅ m - 2}} ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{τ^0, τ^1, τ^2, …, τ^{m - 1} } ⋅ \g_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
α ⋅ \p{ τ^0, τ^1, τ^2, …, τ^{m - 1} } ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
β ⋅ \p{τ^0, τ^1, τ^2, …, τ^{m - 1}} ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
β ⋅ \g_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;phase-2&quot;&gt;Phase 2&lt;&#x2F;h3&gt;
&lt;p&gt;Given circuit polynomials &lt;span class=&quot;math math-inline&quot;&gt;A_i, B_i, C_i&lt;&#x2F;span&gt;, generate random values &lt;span class=&quot;math math-inline&quot;&gt;γ, δ&lt;&#x2F;span&gt; and define the polynomials &lt;span class=&quot;math math-inline&quot;&gt;L_i&lt;&#x2F;span&gt; by:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i(X) = β ⋅ A_i(X) + α ⋅ B_i(X) + C_i(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can not compute the &lt;span class=&quot;math math-inline&quot;&gt;L_i(X)&lt;&#x2F;span&gt; directly since we don&#x27;t know &lt;span class=&quot;math math-inline&quot;&gt;α&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;β&lt;&#x2F;span&gt;, but we can still construct &lt;span class=&quot;math math-inline&quot;&gt;L_i(τ) ⋅ \g_1&lt;&#x2F;span&gt; using linear combinations of the values from the previous step. This way, we compute the proving key:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(α, β, δ) ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(τ^0, τ^1, τ^2, τ^3, …, τ^{m-1}) ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
δ^{-1} ⋅ (L_p(τ), L_{p+1}(τ), …, L_{m-1}(τ)) ⋅ \g_1,
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
δ^{-1} ⋅ (τ^0, τ^1, τ^2, τ^3, …, τ^{m-2}) ⋅ \Z_{\vec x}(τ) ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(β, δ) ⋅ \g_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(τ^0, τ^1, τ^2, τ^3, …, τ^{m-1}) ⋅ \g_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;!-- TODO: Instead of $τ⋅\g_1$ we can create $A_i(τ)⋅\g_1$, same for B. --&gt;
&lt;p&gt;and the verification key:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
α ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
γ^{-1} ⋅ (L_0(τ), L_1(τ), L_2(τ), …, L_{p-1}(τ)) ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(β, γ, δ) ⋅ \g_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Instead of providing &lt;span class=&quot;math math-inline&quot;&gt;α ⋅ \g_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;β ⋅ \g_2&lt;&#x2F;span&gt; we could also provide &lt;span class=&quot;math math-inline&quot;&gt;α ⋅ β ⋅ \g_3&lt;&#x2F;span&gt; in the verifying key, but &lt;span class=&quot;math math-inline&quot;&gt;\G_3&lt;&#x2F;span&gt; elements tend to be big and weird so we avoid them.&lt;&#x2F;p&gt;
&lt;p&gt;The Phase 2 ceremony is critical for soundness. If &lt;span class=&quot;math math-inline&quot;&gt;δ&lt;&#x2F;span&gt; is known the prover can construct any &lt;span class=&quot;math math-inline&quot;&gt;δ^{-1} ⋅ P(τ) ⋅ \g_1&lt;&#x2F;span&gt; of degree &lt;span class=&quot;math math-inline&quot;&gt;2 ⋅ n - 1&lt;&#x2F;span&gt; where otherwise it is constraint to the form &lt;span class=&quot;math math-inline&quot;&gt;δ^{-1} ⋅ H(τ) ⋅ \Z_{\vec x}(τ) ⋅ \g_1&lt;&#x2F;span&gt;. The forced factorization into &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\Z_{\vec x}&lt;&#x2F;span&gt; is critical for soundness.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;multi-party-computation&quot;&gt;Multi-party computation&lt;&#x2F;h3&gt;
&lt;p&gt;It is critical for the security of the system that the values &lt;span class=&quot;math math-inline&quot;&gt;τ, α, β, δ, γ&lt;&#x2F;span&gt; are not known to anyone. They must be disposed of securely, hence they are known as &lt;em&gt;toxic waste&lt;&#x2F;em&gt;. The ZCash team has developed multi-party computation protocols to share the burden of the setup over many participants, such that each produces only a fragment of the waste and you need all fragments to break the system. That is, the system is secure as long as at least one participant is secure. The protocol is described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1050&quot;&gt;BGM17&lt;&#x2F;a&gt; with historical context in a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;z.cash&#x2F;technology&#x2F;paramgen&quot;&gt;blog post&lt;&#x2F;a&gt;. A good introduction to how trusted setups work is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vitalik.ca&#x2F;general&#x2F;2022&#x2F;03&#x2F;14&#x2F;trustedsetup.html&quot;&gt;Vitalik&#x27;s writeup&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll give a sketch of how such protocols work. Imagine we need values &lt;span class=&quot;math math-inline&quot;&gt;S_i = α ⋅ β^i ⋅ A&lt;&#x2F;span&gt; with secret &lt;span class=&quot;math math-inline&quot;&gt;α&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;β&lt;&#x2F;span&gt;. Start with some value initial values &lt;span class=&quot;math math-inline&quot;&gt;α = β = 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;S_i = A&lt;&#x2F;span&gt; and send these to the first participant. The participant generates random &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
S_i&amp;#39; = a ⋅ b^i ⋅ S_i = α&amp;#39; ⋅ β&amp;#39;^i⋅ A
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with updated secrets &lt;span class=&quot;math math-inline&quot;&gt;α&amp;#39; = a ⋅ α&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;β&amp;#39; = b ⋅ β&lt;&#x2F;span&gt;. It passes &lt;span class=&quot;math math-inline&quot;&gt;S_i&amp;#39;&lt;&#x2F;span&gt; on to the next participant and the process repeats. To make sure participants do this correctly they also publish &lt;span class=&quot;math math-inline&quot;&gt;a ⋅ \g_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;b ⋅ \g_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b^i ⋅ \g_2&lt;&#x2F;span&gt; and we verify&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e(S_0, a ⋅ \g_2) &amp;amp;= \e(S_0&amp;#39;, \g_2) \\
\e(S_{i-1}&amp;#39;, b^i ⋅ \g_2) &amp;amp;= \e(S_i&amp;#39;, \g_2) \\
\e(b ⋅ \g_1, b^{i-1} ⋅ \g_2) &amp;amp;= \e(\g_1, b^i ⋅ \g_2) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The actual protocol described in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;1050&quot;&gt;BGM17&lt;&#x2F;a&gt; includes additional safeguards such as proof-of-knowledge of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and a random beacon to guarantee the result is uniformly distributed.&lt;&#x2F;p&gt;
&lt;p&gt;The setup for Groth16 has two phases where the second phase is specific for the circuit you want to proof. This is unfortunate because it means we need to recruit participants and do a setup ceremony for each circuit. Later proof systems have simpler setups that only require a secret value &lt;span class=&quot;math math-inline&quot;&gt;τ&lt;&#x2F;span&gt; and values &lt;span class=&quot;math math-inline&quot;&gt;(τ^0, τ^1, τ^2, τ^3, …, τ^{n-1}) ⋅ (\g_1, \g_2)&lt;&#x2F;span&gt;. These can then be used for many proof systems and circuits. Large, well-constructed sets of values are available.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;proving&quot;&gt;Proving&lt;&#x2F;h2&gt;
&lt;p&gt;Given a witness &lt;span class=&quot;math math-inline&quot;&gt;\vec w = (1, w_1, w_2, …, w_m)&lt;&#x2F;span&gt; that satisfies the constraints, we first compute the degree &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; polynomials &lt;span class=&quot;math math-inline&quot;&gt;A, B, C, H&lt;&#x2F;span&gt; as above. Then compute the private witness polynomials:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
L(X) &amp;amp;= \sum_{i ∊ [p,m)} w_i ⋅ L_i(X)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Generate two random values &lt;span class=&quot;math math-inline&quot;&gt;r, s&lt;&#x2F;span&gt; and compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
A &amp;amp;= (α + r ⋅ δ + A(τ)) ⋅ \g_1 \\
B &amp;amp;= (β + s ⋅ δ + B(τ)) ⋅ \g_2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
C = \p{\begin{aligned}
    &amp;amp; δ^{-1} ⋅ \p{L(τ) + H(τ) ⋅ \Z_{\vec x}(τ)} \\
    + &amp;amp; s ⋅ \p{α + r ⋅ δ + A(τ)} \\
    + &amp;amp; r ⋅ \p{β + s ⋅ δ + B(τ)} \\
    - &amp;amp; r ⋅ s ⋅ δ
    \end{aligned}
} ⋅ \g_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The proof is the triplet &lt;span class=&quot;math math-inline&quot;&gt;(A, B, C)&lt;&#x2F;span&gt;. To compute &lt;span class=&quot;math math-inline&quot;&gt;A(τ)⋅\g_1&lt;&#x2F;span&gt; and, &lt;span class=&quot;math math-inline&quot;&gt;B(τ)⋅\g_1&lt;&#x2F;span&gt; efficiently we can precompute a basis &lt;span class=&quot;math math-inline&quot;&gt;A_i(X), B_i(X)&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; from the proving key and use a multi-scalar-multiplication (MSM)⋅ To compute &lt;span class=&quot;math math-inline&quot;&gt;δ^{-1}⋅H(τ)⋅\Z_{\vec x}(τ)⋅\g_1&lt;&#x2F;span&gt; we use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;geometry.xyz&#x2F;notebook&#x2F;the-hidden-little-secret-in-snarkjs&quot;&gt;Jordi&#x27;s trick&lt;&#x2F;a&gt;: Observe that &lt;span class=&quot;math math-inline&quot;&gt;H(X)⋅\Z_{\vec x}(X)&lt;&#x2F;span&gt; is a degree &lt;span class=&quot;math math-inline&quot;&gt;2⋅n&lt;&#x2F;span&gt; polynomial that equals zero on the domain &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt;. We pick a disjunct domain &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; and prepare a &lt;span class=&quot;math math-inline&quot;&gt;2⋅n&lt;&#x2F;span&gt; size basis over &lt;span class=&quot;math math-inline&quot;&gt;\vec x \cup \vec y&lt;&#x2F;span&gt;. Since evaluations on &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; are zero we only need to MSM over the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; values. To get evaluations on &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; we can interpolate &lt;span class=&quot;math math-inline&quot;&gt;A(X), B(X), C(X)&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; and element-wise compute &lt;span class=&quot;math math-inline&quot;&gt;A(X)⋅B(X)-C(X)&lt;&#x2F;span&gt;. If &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; is chosen to be the odd&#x2F;even &lt;span class=&quot;math math-inline&quot;&gt;2⋅n&lt;&#x2F;span&gt; roots of unity, the interpolation can be done using &lt;span class=&quot;math math-inline&quot;&gt;6⋅\mathsf{NTT}_n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Can we get rid of the &lt;span class=&quot;math math-inline&quot;&gt;\mathsf{NTT}&lt;&#x2F;span&gt;&#x27;s on &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; by MSMing it directly and subtracting &lt;span class=&quot;math math-inline&quot;&gt;C(τ)⋅Z_{\vec x}(τ)&lt;&#x2F;span&gt;?. This won&#x27;t work for &lt;span class=&quot;math math-inline&quot;&gt;A⋅B&lt;&#x2F;span&gt; since we can&#x27;t multiply at &lt;span class=&quot;math math-inline&quot;&gt;τ&lt;&#x2F;span&gt;. We also no longer have &lt;span class=&quot;math math-inline&quot;&gt;A⋅B&lt;&#x2F;span&gt; evaluating to zero on &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt;, so we end up with &lt;span class=&quot;math math-inline&quot;&gt;4⋅\mathsf{NTT}_{n} + \mathsf{NTT}_{2⋅n}&lt;&#x2F;span&gt; which cost about the same.&lt;&#x2F;p&gt;
&lt;p&gt;Note that the proof is malleable. Given a proof &lt;span class=&quot;math math-inline&quot;&gt;(A, B, C)&lt;&#x2F;span&gt; and arbitrary values &lt;span class=&quot;math math-inline&quot;&gt;t, u&lt;&#x2F;span&gt; the triplet &lt;span class=&quot;math math-inline&quot;&gt;(t^{-1} ⋅ A, t ⋅ B + t ⋅ u ⋅ δ ⋅ \g_2, C + u ⋅ A)&lt;&#x2F;span&gt; is also a valid proof and indistinguishable from a regularly produced one, see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;540&quot;&gt;GM17&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;811&quot;&gt;BKSV20&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;verifying&quot;&gt;Verifying&lt;&#x2F;h2&gt;
&lt;p&gt;Given proof &lt;span class=&quot;math math-inline&quot;&gt;(A, B, C)&lt;&#x2F;span&gt; and public inputs &lt;span class=&quot;math math-inline&quot;&gt;w  = (1, w_1, …, w_l)&lt;&#x2F;span&gt;. Aggregate the public inputs&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
{\overline L} &amp;amp;= \sum_{i ∊ [0, p)} w_i ⋅ \p{γ^{-1} ⋅ L_i(τ) ⋅ \g_1} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;then check&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(A, B) = \e(α ⋅ \g_1, β ⋅ \g_2) + \e( {\overline L}, γ ⋅ \g_2) + \e(C, δ ⋅ \g_2)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Intuitively, this verifies &lt;span class=&quot;math math-inline&quot;&gt;A(τ) ⋅ B(τ) = C(τ) + H(τ) ⋅ \Z_{\vec x}(τ)&lt;&#x2F;span&gt; with some extra terms mixed in. Some of these extra terms guarantee that the same value &lt;span class=&quot;math math-inline&quot;&gt;\vec w&lt;&#x2F;span&gt; is used consistently, others are just there to cancel out spurious terms. Groth16 is remarkable in how everything happens simultaneously in a single complex expression. It is hard to separate in clear parts. Later systems based on polynomial commitments have a much more modular structure, but also have larger proofs and more steps in the verification.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Completeness&lt;&#x2F;em&gt; follows from an expansion of the pairing check. &lt;em&gt;Soundness&lt;&#x2F;em&gt; follows from the observation that the values &lt;span class=&quot;math math-inline&quot;&gt;τ, α, β, γ, δ&lt;&#x2F;span&gt; are unknown, therefore prover provided values must be linear combinations of the setup values. We can consider the pairing check a multivariate polynomial equation in these secret values, invoke Schwartz-Zippel and equate the coefficients. Straightforward but tedious solving for each coefficient shows the existence of a satisfying witness &lt;span class=&quot;math math-inline&quot;&gt;w&lt;&#x2F;span&gt;. &lt;em&gt;Zero knowledge&lt;&#x2F;em&gt; follows from &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; being uniformly random through &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; being fully determined through the claim.&lt;&#x2F;p&gt;
&lt;!-- TODO: Where does the &#x27;Rank-1&#x27; come from? --&gt;
&lt;!-- NOTE: Arkworks and SnarkJS differ in how the witness is computed:
https:&#x2F;&#x2F;github.com&#x2F;philsippl&#x2F;ark-circom&#x2F;blob&#x2F;b1bd48648a106aebdd093b581b413e87cf47d16f&#x2F;src&#x2F;circom&#x2F;qap.rs#L7
--&gt;
&lt;!-- TODO: Snarkpack https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;529 --&gt;
&lt;!--
https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;691.pdf

https:&#x2F;&#x2F;github.com&#x2F;Consensys&#x2F;gnark&#x2F;blob&#x2F;7f38c2116e04914798d44a5289c07e5410b8bded&#x2F;backend&#x2F;groth16&#x2F;bn254&#x2F;prove.go#L44C62-L44C95 :
https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2022&#x2F;1072.pdf

--&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>muldiv 512x512</title>
        <published>2022-07-12T00:00:00+00:00</published>
        <updated>2022-07-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/muldiv-512x512/"/>
        <id>https://2π.com/22/muldiv-512x512/</id>
        
        <content type="html" xml:base="https://2π.com/22/muldiv-512x512/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\floor#1{\lfloor{#1}\rfloor}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;muldiv-512x512&quot;&gt;muldiv 512x512&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\a{\mathtt{a}}
\gdef\b{\mathtt{b}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; Compute
&lt;span class=&quot;math math-display&quot;&gt;
\mathtt{div512}(\a_0, \a_1, \b_0, \b_1) = \floor{\frac{\a_0 + \a_1 ⋅ 2^{256}}{\b_0 + \b_1 ⋅ 2^{256}}}
&lt;&#x2F;span&gt;
where all arguments are integers in the range &lt;span class=&quot;math math-inline&quot;&gt;[0, 2^{256})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Div512 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function div512(uint256 a0, uint256 a1, uint256 b0, uint256 b1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    internal pure returns (uint256 result)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if(b1 == 0) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            return div512x256(a0, a1, b0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here we can use Knuth&#x27;s algorithm D, see for example the implementation in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;OpenZKP&#x2F;blob&#x2F;c28a5c66b6ee9b97bf177373ba148981df60b7fb&#x2F;algebra&#x2F;u256&#x2F;src&#x2F;arch&#x2F;generic&#x2F;knuth_division.rs#L89&quot;&gt;OpenZKP&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{b}_1 = 0&lt;&#x2F;span&gt; we can use the &lt;a href=&quot;&#x2F;21&#x2F;muldiv&quot;&gt;previous method&lt;&#x2F;a&gt;, so assume &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{b}_1 ≥ 1&lt;&#x2F;span&gt;. In this case the high limbs bound the answer:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\floor{\frac
    {\mathtt{a}_1}
    {\mathtt{b}_1 + 1}
}
≤
\floor{\frac
    {\mathtt{a}_0 + \mathtt{a}_1 ⋅ 2^{256}}
    {\mathtt{b}_0 + \mathtt{b}_1 ⋅ 2^{256}}
}
≤
\floor{\frac
    {\mathtt{a}_1 + 1}
    {\mathtt{b}_1}
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So we can start by subtracting&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a&amp;#39; = a - \floor{\frac
    {\mathtt{a}_1}
    {\mathtt{b}_1 + 1}
} ⋅ b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;a&amp;#39; &amp;lt; b&lt;&#x2F;span&gt; we are done.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Polynomial evaluation</title>
        <published>2022-07-12T00:00:00+00:00</published>
        <updated>2022-07-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/poly-eval/"/>
        <id>https://2π.com/22/poly-eval/</id>
        
        <content type="html" xml:base="https://2π.com/22/poly-eval/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;polynomial-evaluation&quot;&gt;Polynomial evaluation&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{p_0 + p_1 ⋅ x + p_2 ⋅ x^2 + p_3 ⋅ x^3 + p_4 ⋅ x^4 + p_5 ⋅ x^5}
{q_0 + q_1 ⋅ x + q_2 ⋅ x^2 + q_3 ⋅ x^3 + q_4 ⋅ x^4 + q_5 ⋅ x^5 + x^6}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basic-algorithms&quot;&gt;Basic algorithms&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;horners-rule&quot;&gt;Horners rule&lt;&#x2F;h3&gt;
&lt;p&gt;For Monomial basis&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;clenshaw-algorithm&quot;&gt;Clenshaw algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;Generalization, specifically for Chebyshev basis.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Clenshaw_algorithm&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Clenshaw_algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;de-castlejau-s-algorithm&quot;&gt;De Castlejau&#x27;s algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;For Bernstein basis&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;De_Casteljau%27s_algorithm&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;De_Casteljau%27s_algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;De_Boor%27s_algorithm&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;De_Boor%27s_algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;easy-polynomials&quot;&gt;Easy polynomials&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Arithmetic_circuit_complexity&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Arithmetic_circuit_complexity&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exponentiation_by_squaring&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exponentiation_by_squaring&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Addition-chain_exponentiation&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Addition-chain_exponentiation&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vectorial_addition_chain&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vectorial_addition_chain&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;WNAF, Pippenger&#x27;s algorithm, etc.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;preprocessing&quot;&gt;Preprocessing&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
y = p_0 + p_1 ⋅ x + p_2 ⋅ x^2 + p_3 ⋅ x^3 + x^4
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;would take three multiplications to evaluate&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;but can also be evaluated using only two by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a &amp;amp;= (x + β_0) ⋅ x + β_1 &amp;amp; y &amp;amp;= (a + β_2) ⋅ a + β_3
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
β_0 &amp;amp;= \frac12\p{a_3 - 1} &amp;amp; z &amp;amp;= a_2 - β_0 ⋅ \p{β_0 + 1} &amp;amp; β_1 &amp;amp;= a_1 - β_0 ⋅ z \\
β_2 &amp;amp;= z - 2 ⋅ β_1 &amp;amp; β_3 &amp;amp;= a_0 - β_1 ⋅ \p{β_1 + β_2}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; β0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a ⋅ x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; β1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; β2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y ⋅ a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; β3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;pan-s-scheme-for-one-polynomial&quot;&gt;Pan&#x27;s scheme for one polynomial&lt;&#x2F;h2&gt;
&lt;p&gt;See §3.3 of the Pan&#x27;s 1966 paper.&lt;&#x2F;p&gt;
&lt;p&gt;Assuming p monic&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;h2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;g4_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g4_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;g4_2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g4_2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;# Output formulas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p6&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p10&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p12&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(6,7)-term rat scheme: 4 + 5 muls.&lt;&#x2F;p&gt;
&lt;p&gt;p5 &amp;amp; p6&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;h2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;g4_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g4_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;g4_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g4_1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;p6&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;above: 1 + 2 + 3 = 6 muls.&lt;&#x2F;p&gt;
&lt;p&gt;knuth explicits: 3 + 3 = 6 muls&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x) = p_0 + p_1 ⋅ x + p_2 ⋅ x^2 + p_3 ⋅ x^3 + p_4 ⋅ x^4 + x^5
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
q(x) = q_0 + q_1 ⋅ x + q_2 ⋅ x^2 + q_3 ⋅ x^3 + q_4 ⋅ x^4 + q_5 ⋅ x^5 + x^6
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;paterson-stockmeyer&quot;&gt;Paterson-Stockmeyer&lt;&#x2F;h2&gt;
&lt;p&gt;Consider the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-term monic polynomial where &lt;span class=&quot;math math-inline&quot;&gt;n = 2 ⋅ k&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x) = p_0 + p_1 ⋅ x + p_2 ⋅ x^2 + \cdots + p_{n-2} ⋅ x^{n-2} + x^{n-1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can rewrite it using two &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-term monic polynomial &lt;span class=&quot;math math-inline&quot;&gt;p_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p_2&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x) = p_1(x) + (x^k + a) ⋅ p_2(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;a = p_{k-1} -1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p_2&lt;&#x2F;span&gt; the top half of &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p_1&lt;&#x2F;span&gt; is the lower half of &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;a ⋅ p_2&lt;&#x2F;span&gt; subtracted.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;x^2 = x ⋅ x&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;x^4 = x^2 ⋅ x^2&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;p(x) = p_0(x) + (x^4 + a_0) ⋅ p_1(x)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;p_0 = c_0 + c_1 ⋅ x + c_2 ⋅ x^2 + c_3 ⋅ x^3&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;p_0(x) = p_2(x) + (x^2 + a_0) ⋅ p_3(x)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;random&quot;&gt;Random&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;schwartz-zippel-lemma&quot;&gt;Schwartz–Zippel lemma&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Schwartz%E2%80%93Zippel_lemma&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Schwartz%E2%80%93Zippel_lemma&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vieta-s-formula&quot;&gt;Vieta&#x27;s formula&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vieta%27s_formulas&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vieta%27s_formulas&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;frobenius-endomorphism&quot;&gt;Frobenius Endomorphism&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Frobenius_endomorphism&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Frobenius_endomorphism&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;abert-method&quot;&gt;Abert method&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Durand%E2%80%93Kerner_method&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Durand%E2%80%93Kerner_method&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Aberth_method&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Aberth_method&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Arithmetic_circuit_complexity&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Arithmetic_circuit_complexity&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;V.Ya. Pan (1966).
&quot;Methods of Computing Values of Polynomials&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1070&#x2F;rm1966v021n01abeh004147&quot;&gt;doi&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;S. Winograd (1970).
&quot;On the number of multiplications necessary to compute certain functions&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1002&#x2F;cpa.3160230204&quot;&gt;doi&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;M.O. Rabin &amp;amp; S. Winograd (1972).
&quot;Fast Evaluation of Polynomials by Rational Preparation&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1002&#x2F;cpa.3160250405&quot;&gt;doi&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;D. Knuth (2011).
&quot;The Art of Computer Programming – Volume 2: Seminumerical Algorithms&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Special:BookSources?isbn=978-0-201-89684-8&quot;&gt;isbn&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eprints.maths.manchester.ac.uk&#x2F;2700&#x2F;3&#x2F;fasi19.pdf&quot;&gt;http:&#x2F;&#x2F;eprints.maths.manchester.ac.uk&#x2F;2700&#x2F;3&#x2F;fasi19.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;epubs.siam.org&#x2F;doi&#x2F;10.1137&#x2F;0202007&quot;&gt;https:&#x2F;&#x2F;epubs.siam.org&#x2F;doi&#x2F;10.1137&#x2F;0202007&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;onlinelibrary.wiley.com&#x2F;doi&#x2F;10.1002&#x2F;cpa.3160250405&quot;&gt;https:&#x2F;&#x2F;onlinelibrary.wiley.com&#x2F;doi&#x2F;10.1002&#x2F;cpa.3160250405&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;simple-guide-to-fast-linear-combinations-aka-multiexponentiations&#x2F;7238&quot;&gt;https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;simple-guide-to-fast-linear-combinations-aka-multiexponentiations&#x2F;7238&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jbootle.github.io&#x2F;Misc&#x2F;pippenger.pdf&quot;&gt;https:&#x2F;&#x2F;jbootle.github.io&#x2F;Misc&#x2F;pippenger.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Zero Knowledge Machine Learning</title>
        <published>2022-07-12T00:00:00+00:00</published>
        <updated>2022-07-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/zk-ml/"/>
        <id>https://2π.com/22/zk-ml/</id>
        
        <content type="html" xml:base="https://2π.com/22/zk-ml/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\norm#1{\lVert{#1}\rVert}
\gdef\floor#1{\lfloor{#1}\rfloor}
\gdef\argmax{\mathop{\operatorname{arg\,max}}\limits}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;zero-knowledge-machine-learning&quot;&gt;Zero Knowledge Machine Learning&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;worldcoin-use-case&quot;&gt;Worldcoin Use-Case&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;IrisCode self-custody and upgrade ability.&lt;&#x2F;li&gt;
&lt;li&gt;Making the Orb trustless, provide proof that fraud filters are applied.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;deep-learning-networks&quot;&gt;Deep learning networks&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;               layer |    output shape |     #parameters |            #ops &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-------------------- | --------------- | --------------- | --------------- &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       conv 32x5x5x3 |   (116, 76, 32) |            2400 |        21158400 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            max-pool |    (58, 38, 32) |               0 |          282112 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                relu |    (58, 38, 32) |               0 |           70528 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      conv 32x5x5x32 |    (54, 34, 32) |           25600 |        47001600 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            max-pool |    (27, 17, 32) |               0 |           58752 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                relu |    (27, 17, 32) |               0 |           14688 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             flatten |        (14688,) |               0 |               0 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     full 1000x14688 |         (1000,) |        14689000 |        14688000 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                relu |         (1000,) |               0 |            1000 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         full 5x1000 |            (5,) |            5005 |            5000 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           normalize |            (5,) |               0 |               6 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Linear operations
&lt;ul&gt;
&lt;li&gt;Matrix multiplications: &lt;span class=&quot;math math-inline&quot;&gt;A ⋅ \vec x&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Convolutions&lt;&#x2F;li&gt;
&lt;li&gt;Biases: &lt;span class=&quot;math math-inline&quot;&gt;\vec x + \vec b&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Pooling
&lt;ul&gt;
&lt;li&gt;Max pooling: &lt;span class=&quot;math math-inline&quot;&gt;\max_i x_i&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Sum&#x2F;Avg pooling: &lt;span class=&quot;math math-inline&quot;&gt;\sum_i x_i&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Activation functions:
&lt;ul&gt;
&lt;li&gt;ReLU: &lt;span class=&quot;math math-inline&quot;&gt;\max(0,x)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;PReLU: &lt;span class=&quot;math math-inline&quot;&gt;\max(α⋅x,x)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;0 ≤ α &amp;lt; 1&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Logistic: &lt;span class=&quot;math math-inline&quot;&gt;\p{1 + \mathrm{e}^{-x}}^{-1}&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Polynomial: &lt;span class=&quot;math math-inline&quot;&gt;x^2 + x&lt;&#x2F;span&gt;,&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Argmax: &lt;span class=&quot;math math-inline&quot;&gt;\argmax_i x_i&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Softmax: &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{e}^{x_i}&lt;&#x2F;span&gt; and rescaling &lt;span class=&quot;math math-inline&quot;&gt;\norm{\vec x}_1 = 1&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Normalize: Rescale such that 2-norm &lt;span class=&quot;math math-inline&quot;&gt;\norm{\vec x}_2 = 1&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;relevant-ml-evaluation-work&quot;&gt;Relevant ML evaluation work&lt;&#x2F;h2&gt;
&lt;p&gt;Generally: lot&#x27;s of similarities with embedded implementations: use fixed-point to avoid floating point math, model is held constant, can do precompute.&lt;&#x2F;p&gt;
&lt;p&gt;Differences: Fixed-point numbers in ZK can be large (very very large in some proof systems). Simple comparisons are expensive. Can do inverses trivially. (i.e. zk development we are all familiar with).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prior-zk-ml-work&quot;&gt;Prior ZK-ML work&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Justin Thaler (2013).
&quot;Time-Optimal Interactive Proofs for Circuit Evaluation&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;351&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;351&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Pengtao Xie, Misha Bilenko, Tom Finley, Ran Gilad-Bachrach, Kristin Lauter, Michael Naehrig (2014).
&quot;Crypto-Nets: Neural Networks over Encrypted Data&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1412.6181&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1412.6181&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Nathan Dowlin, Ran Gilad-Bachrach, Kim Laine, Kristin Lauter, Michael Naehrig, John Wernsing (2016).
&quot;CryptoNets: Applying Neural Networks to Encrypted Data with High Throughput and Accuracy&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;publication&#x2F;cryptonets-applying-neural-networks-to-encrypted-data-with-high-throughput-and-accuracy&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;publication&#x2F;cryptonets-applying-neural-networks-to-encrypted-data-with-high-throughput-and-accuracy&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Zahra Ghodsi, Tianyu Gu, Siddharth Garg (2017).
&quot;SafetyNets: Verifiable Execution of Deep Neural Networks on an Untrusted Cloud&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1706.10268&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1706.10268&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Payman Mohassel and Yupeng Zhang (2017).
&quot;SecureML: A System for Scalable Privacy-Preserving Machine Learning&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;396&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;396&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Jian Liu, Mika Juuti, Yao Lu, and N. Asokan (2017).
&quot;Oblivious Neural Network Predictions via MiniONN transformations&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;452&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2017&#x2F;452&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Seunghwa Lee, Hankyung Ko, Jihye Kim, and Hyunok Oh (2020).
&quot;vCNN: Verifiable Convolutional Neural Network based on zk-SNARKs&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;584&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;584&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Ramy E. Ali, Jinhyun So, A. Salman Avestimehr (2020).
&quot;On Polynomial Approximations for Privacy-Preserving and Verifiable ReLU Networks&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2011.05530&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2011.05530&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Boyuan Feng, Lianke Qin, Zhenfei Zhang, Yufei Ding, and Shumo Chu (2021).
&quot;ZEN: An Optimizing Compiler for Verifiable, Zero-Knowledge Neural Network Inferences&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;087&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;087&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Tianyi Liu, Xiang Xie, and Yupeng Zhang (2021).
&quot;zkCNN: Zero Knowledge Proofs for Convolutional Neural Network Predictions and Accuracy&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;673&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;673&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Chenkai Weng, Kang Yang, Xiang Xie, Jonathan Katz, and Xiao Wang (2021).
&quot;Mystique: Efficient Conversions for Zero-Knowledge Proofs with Applications to Machine Learning&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;730&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;730&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.usenix.org&#x2F;system&#x2F;files&#x2F;sec21-weng.pdf&quot;&gt;slides&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Zahra Ghodsi, Tianyu Gu, Siddharth Garg (2017).
&quot;SafetyNets: Verifiable Execution of Deep Neural Networks on an Untrusted Cloud&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1706.10268&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1706.10268&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;@liaopeiyuan (2021).
&quot;zk-ml&#x2F;demo&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;zk-ml&#x2F;demo&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;zk-ml&#x2F;demo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;@socathie (2022).
&quot;CircomLib-ML&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;socathie&#x2F;circomlib-ml&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;socathie&#x2F;circomlib-ml&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gitcoin.co&#x2F;grants&#x2F;6847&#x2F;zkmachinelearning-an-end-to-end-platform-to-bridge&quot;&gt;GitCoin Grant Proposal&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;@horacepan @sunfishstanford @henripal (2022).
&quot;ZK-MNIST&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xZKML&#x2F;zk-mnist&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;0xZKML&#x2F;zk-mnist&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;0xparc.org&#x2F;blog&#x2F;zk-mnist&quot;&gt;https:&#x2F;&#x2F;0xparc.org&#x2F;blog&#x2F;zk-mnist&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;@recmo (2022).
&quot;proto-neural-zkp&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;worldcoin&#x2F;proto-neural-zkp&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;worldcoin&#x2F;proto-neural-zkp&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;fix-point&quot;&gt;Fix point&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathtt{a} = \floor{\frac{a}{2^{32}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathtt{a} ⋅ \mathtt{b} = \floor{\frac{a}{2^{32}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;strategy-ideas&quot;&gt;Strategy ideas&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Results in low level optimized implementation of matrix multiplications and
convolutions.&lt;&#x2F;li&gt;
&lt;li&gt;Recursion around layers. Vectors passed between layers are smallish, so can be committed to.&lt;&#x2F;li&gt;
&lt;li&gt;Target 16-bit fixpoint so we can use PLookup for Relu.&lt;&#x2F;li&gt;
&lt;li&gt;dot product without renormalization.&lt;&#x2F;li&gt;
&lt;li&gt;Flip max-pool and relu 😁&lt;&#x2F;li&gt;
&lt;li&gt;Clever algorithms to compute convolutions (from simple tricks to FFT based)&lt;&#x2F;li&gt;
&lt;li&gt;Efficient non-zk convolution algorithms: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1903.01521&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1903.01521&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;people.ece.umn.edu&#x2F;users&#x2F;parhi&#x2F;SLIDES&#x2F;chap8.pdf&quot;&gt;http:&#x2F;&#x2F;people.ece.umn.edu&#x2F;users&#x2F;parhi&#x2F;SLIDES&#x2F;chap8.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>BLS Signatures</title>
        <published>2022-05-01T00:00:00+00:00</published>
        <updated>2022-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/bls-signatures/"/>
        <id>https://2π.com/22/bls-signatures/</id>
        
        <content type="html" xml:base="https://2π.com/22/bls-signatures/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\p#1{({#1})}
\gdef\abs#1{\lvert{#1}\rvert}
\gdef\set#1{\mathcal{#1}}
\gdef\setb#1#2{\{{#1} \mid {#2}\}}
\gdef\dummyarg{\operatorname{-}}
\gdef\e{\mathrm{e}}
\gdef\g{\mathrm{g}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;bls-signatures&quot;&gt;BLS Signatures&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\G{\mathbb{G}}
\gdef\g{\mathrm{G}}
\gdef\h{\mathtt{H}}
\gdef\e{\mathrm{e}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Previously I wrote about several elliptic curve &lt;a href=&quot;&#x2F;22&#x2F;signatures&quot;&gt;signature schemes&lt;&#x2F;a&gt;. I did not cover pairing based ones. These allow for some great aggregation schemes. so let&#x27;s cover those now.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;background&quot;&gt;Background&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;hash-to-curve&quot;&gt;Hash to curve&lt;&#x2F;h3&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;\h_{\mathcal S} : \mathcal I → \mathcal S&lt;&#x2F;span&gt; be a hash function mapping some input set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal I&lt;&#x2F;span&gt; to the output set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal S&lt;&#x2F;span&gt;. A superscript like &lt;span class=&quot;math math-inline&quot;&gt;\h&amp;#39;&lt;&#x2F;span&gt; is used to indicate two domain separated hash functions.&lt;&#x2F;p&gt;
&lt;p&gt;Securely generating elliptic curve points from binary noise is challenging. The naive solution of multiplying by a generator is not secure, since the discrete logarithm is known. The BLS paper introduced the first solution: repeatedly trying &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; coordinates until a valid curve point is found. This method is generic but not constant time. Constant time methods exists but are curve specific.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pairing-curves&quot;&gt;Pairing curves&lt;&#x2F;h3&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\G_3&lt;&#x2F;span&gt; be elliptic curve groups with the same scalar field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, generators &lt;span class=&quot;math math-inline&quot;&gt;\g_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\g_2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\g_3&lt;&#x2F;span&gt; and a &lt;em&gt;pairing&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\e: \G_1 × \G_2 → \G_3&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A pairing is a function that satisfies &lt;span class=&quot;math math-inline&quot;&gt;\e(a ⋅ A, b ⋅ B) = a ⋅ b ⋅ \e(A, B)&lt;&#x2F;span&gt; and is not the trivial solution &lt;span class=&quot;math math-inline&quot;&gt;\e(\dummyarg,\dummyarg) = 0&lt;&#x2F;span&gt;. From this it follows that &lt;span class=&quot;math math-inline&quot;&gt;\e(A_1 + A_2, B) = \e(A_1, B) + \e(A_2, B)&lt;&#x2F;span&gt; and other useful linear properties.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The pairing is symmetrical in &lt;span class=&quot;math math-inline&quot;&gt;\G_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\G_2&lt;&#x2F;span&gt; so protocols also work with groups and pairing arguments swapped. This is useful if one group has better performance than the other.&lt;&#x2F;p&gt;
&lt;p&gt;Finding a pairing that satisfy the requirements is challenging, especially when there are additional constraints such as having large binary roots of unity in &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;. Different families of solutions have been found:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MNT, Miyaji-Nakabayashi-Takano (2001; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dspace.jaist.ac.jp&#x2F;dspace&#x2F;bitstream&#x2F;10119&#x2F;4432&#x2F;1&#x2F;73-48.pdf&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;BLS, Barreto-Lynn-Scott (2002; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2002&#x2F;088&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;BN, Barreto-Naehrig (2005; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2005&#x2F;133.pdf&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;KSS, Kachisa-Schaefer-Scott (2008; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;chapter&#x2F;10.1007&#x2F;978-3-540-85538-5_9&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Two important specific solutions are&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;scipr-lab&#x2F;libff&#x2F;blob&#x2F;674e437446216ade040194105b4fc9ff3d8db6f1&#x2F;libff&#x2F;algebra&#x2F;curves&#x2F;alt_bn128&#x2F;alt_bn128.sage&quot;&gt;&lt;code&gt;ALT_BN128&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; (2015). Developed by &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.scipr-lab.org&#x2F;&quot;&gt;SCIPR-lab&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;electriccoin.co&#x2F;blog&#x2F;new-snark-curve&#x2F;&quot;&gt;&lt;code&gt;BLS12-381&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; (2017). Developed by Sean Bowe for ZCash.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The 128 in &lt;code&gt;alt_bn128&lt;&#x2F;code&gt; revers to the target security level, but it was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;moderncrypto.org&#x2F;mail-archive&#x2F;curves&#x2F;2016&#x2F;000740.html&quot;&gt;since found&lt;&#x2F;a&gt; that it is &quot;closer to 96 or so&quot;. &lt;code&gt;BLS12-381&lt;&#x2F;code&gt; development was in part motivated to address this and targets 128 bit security.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;signature-aggregation&quot;&gt;Signature aggregation&lt;&#x2F;h2&gt;
&lt;p&gt;Like with elliptic curve protocols, the private key is a random scalar field element &lt;span class=&quot;math math-inline&quot;&gt;x ∈ \F&lt;&#x2F;span&gt; and the public key is the private key times a generator &lt;span class=&quot;math math-inline&quot;&gt;X = x ⋅ \g_2&lt;&#x2F;span&gt;. However, this alone is not secure in pairing cryptography due to the &lt;em&gt;rogue key attack&lt;&#x2F;em&gt; that I will &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;bls-signatures&#x2F;#rogue-key-attack&quot;&gt;explain later&lt;&#x2F;a&gt;. We need to prove that we actually know the private key, a &lt;em&gt;proof of possession&lt;&#x2F;em&gt;. To do this compute and publish&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
S_X = x ⋅ \h_{\G_1}&amp;#39;(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now anyone with &lt;span class=&quot;math math-inline&quot;&gt;(X, S_X)&lt;&#x2F;span&gt; can verify the public key using&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S_X, \g_2) = \e(\h_{\G_1}&amp;#39;(X), X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Details&lt;&#x2F;summary&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e(S_X, \g_2) &amp;amp;= \e(\h_{\G_2}&amp;#39;(X), X) \\
\e(x ⋅ \h_{\G_2}&amp;#39;(X), \g_2) &amp;amp;= \e(\h_{\G_2}&amp;#39;(X), x ⋅ \g_2) \\
x ⋅ \e(\h_{\G_2}&amp;#39;(X), \g_2) &amp;amp;= x ⋅ \e(\h_{\G_2}&amp;#39;(X), \g_2) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;p&gt;In the following I will assume all public keys have had their proofs of possession checked.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;one-signer-one-message&quot;&gt;One signer, one message&lt;&#x2F;h3&gt;
&lt;p&gt;To sign a message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;, hash the message &lt;span class=&quot;math math-inline&quot;&gt;H = \h_{\G_1}(m)&lt;&#x2F;span&gt; and the signature is &lt;span class=&quot;math math-inline&quot;&gt;S = x ⋅ H&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To verify, hash the message &lt;span class=&quot;math math-inline&quot;&gt;H = \h_{\G_1}(m)&lt;&#x2F;span&gt; and check&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \e(H, X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Details&lt;&#x2F;summary&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e(S, \g_2) &amp;amp;= \e(H, X) \\
\e(x ⋅ H, \g_2) &amp;amp;= \e(H, X) \\
x ⋅ \e(H, \g_2) &amp;amp;= \e(H, x ⋅ \g_2) \\
x ⋅ \e(H, \g_2) &amp;amp;= x ⋅ \e(H, \g_2) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;h3 id=&quot;many-signers-many-messages&quot;&gt;Many signers, many messages&lt;&#x2F;h3&gt;
&lt;p&gt;To aggregate many signatures, we simply sum them&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
S = S_1 + S_2 + S_3 + ⋯
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then to verify, we compute all the hashes for the messages &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt; and check&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \e(H_1, X_1) + \e(H_2, X_2) + \e(H_3, X_3) + ⋯
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;many-signers-one-message&quot;&gt;Many signers, one message&lt;&#x2F;h3&gt;
&lt;p&gt;In the case where all messages are the same, the verification simplifies to only two pairing operations:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \e(H, X_1 + X_2 + X_3 + ⋯)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;threshold-signatures&quot;&gt;Threshold signatures&lt;&#x2F;h2&gt;
&lt;p&gt;BLS signatures also allows for a threshold signature scheme. For a scheme where &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; out of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; signatories can sign we first do a setup: Assign every signer &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; a unique &lt;span class=&quot;math math-inline&quot;&gt;a_i ∈ \F&lt;&#x2F;span&gt; and pick another unique &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \F&lt;&#x2F;span&gt; that we will need soon. These values &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; are public. Use a distributed key generation protocol to create a random &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;-term polynomial &lt;span class=&quot;math math-inline&quot;&gt;P ∈ \F[X]&lt;&#x2F;span&gt; and provide all the signers with private keys &lt;span class=&quot;math math-inline&quot;&gt;x_i = P(a_i)&lt;&#x2F;span&gt; and public keys &lt;span class=&quot;math math-inline&quot;&gt;X_i = x_i ⋅ G_2&lt;&#x2F;span&gt;. Also compute the verification public key &lt;span class=&quot;math math-inline&quot;&gt;X = P(a) ⋅ \g_2&lt;&#x2F;span&gt;. This is basically &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Shamir%27s_Secret_Sharing&quot;&gt;Shamir&#x27;s Secret Sharing&lt;&#x2F;a&gt; scheme where each private key is a share of the private to the verification key.&lt;&#x2F;p&gt;
&lt;p&gt;Signing is as with plain BLS signatures. Given message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; compute &lt;span class=&quot;math math-inline&quot;&gt;H = \h_{\G_1}(m)&lt;&#x2F;span&gt;. Each signer computes their signature &lt;span class=&quot;math math-inline&quot;&gt;S_i = x_i ⋅ H&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To aggregate the treshold, first verify the individual signatures using plain BLS verification. Take &lt;span class=&quot;math math-inline&quot;&gt;\mathcal I&lt;&#x2F;span&gt; to be the set of indices &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; of valid signatures. Compute the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lagrange_polynomial&quot;&gt;Lagrange interpolation&lt;&#x2F;a&gt; weights &lt;span class=&quot;math math-inline&quot;&gt;w_i ∈ \F&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w_i = \prod_{j ∈ \mathcal I \setminus \set{i}} \frac{a - a_j}{a_i - a_j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt;&#x27;s range over all valid signatory indices except &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;. Compute the aggregate signature&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
S = \sum_{i ∈ \mathcal I} w_i ⋅ S_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The aggregate signature &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; is now a valid BLS signatured for &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; for the verification public key &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \e(H, X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Details&lt;&#x2F;summary&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e(S, \g_2) &amp;amp;= \e(H, X) \\
\e\p{\sum_{i ∈ \mathcal I} w_i ⋅ S_i, \g_2} &amp;amp;= \e(H, P(a) ⋅ \g_2) \\
\e\p{\sum_{i ∈ \mathcal I} w_i ⋅ x_i ⋅ H, \g_2} &amp;amp;= P(a) ⋅ \e(H, \g_2) \\
\p{\sum_{i ∈ \mathcal I} w_i ⋅ x_i} ⋅ \e\p{H, \g_2} &amp;amp;= P(a) ⋅ \e(H, \g_2) \\
\sum_{i ∈ \mathcal I} w_i ⋅ x_i &amp;amp;= P(a) \\
\sum_{i ∈ \mathcal I} P(a_i) ⋅ \prod_{j ∈ \mathcal I \setminus \set{i}} \frac{a - a_j}{a_i - a_j} &amp;amp;= P(a) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This final relation is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lagrange_polynomial&quot;&gt;Langrange interpolation&lt;&#x2F;a&gt; formula evaluated at &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, it holds if &lt;span class=&quot;math math-inline&quot;&gt;\abs{\mathcal I} ≥ m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;h2 id=&quot;rogue-key-attack&quot;&gt;Rogue key attack&lt;&#x2F;h2&gt;
&lt;p&gt;The proof-of-possession is sometimes omitted. This makes the system vulnerable to the &lt;em&gt;rogue key attack&lt;&#x2F;em&gt; where an attacker can co-sign with forged signatures making it look like both attacker and one or more victims signed a message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;. I&#x27;ll cover the one victim case:&lt;&#x2F;p&gt;
&lt;p&gt;Given victim public key &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt;, the attacker generates a random private key &lt;span class=&quot;math math-inline&quot;&gt;a ∈ \F&lt;&#x2F;span&gt; and computes a rogue public key &lt;span class=&quot;math math-inline&quot;&gt;A = a ⋅ \g_2 - X&lt;&#x2F;span&gt;. The attacker signs a message &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt; as usual &lt;span class=&quot;math math-inline&quot;&gt;S = a ⋅ H&lt;&#x2F;span&gt;. Now &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; looks like the aggregate signature of &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; on a common message &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \e(H, A) + \e(H, X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Details&lt;&#x2F;summary&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e(S, \g_2) &amp;amp;= \e(H, A) + \e(H, X) \\
\e(a ⋅ H, \g_2) &amp;amp;= \e(H, a ⋅ \g_2 - X) + \e(H, X) \\
a ⋅ \e(H, \g_2) &amp;amp;= a ⋅ \e(H, \g_2) - \e(H, X) + \e(H, X) \\
a ⋅ \e(H, \g_2) &amp;amp;= a ⋅ \e(H, \g_2)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;p&gt;Besides proof-of-possession that was used above, there are two other notable mitigation strategies (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.stanford.edu&#x2F;~dabo&#x2F;pubs&#x2F;papers&#x2F;BLSmultisig.html&quot;&gt;Boneh, Drijvers &amp;amp; Neven (2018)&lt;&#x2F;a&gt;). For the first, note that the attack requires the messages to be the same. Making sure that every signer signs a different message avoids the attack. One way of achieving this is including the public key in each message:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
H = \h_{\G_1}\p{X, m}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since this makes all messages distinct, we can no longer use the &quot;many signers, one message&quot; optimization. A second mitigation strategy is to modify the aggregation method. To aggregate a set of signatures &lt;span class=&quot;math math-inline&quot;&gt;\mathcal I&lt;&#x2F;span&gt; we first compute pseudorandom constants &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt; for each signer&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c_i = \h_{\F}\p{X_i, \setb{X_j}{j ∈ \mathcal I}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt; These &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt; are a function of the whole set of signatories. Simplifying it to &lt;span class=&quot;math math-inline&quot;&gt;c_i = \h_{\F}(X_i)&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;pragmatic-signature-aggregation-with-bls&#x2F;2105&#x2F;11&quot;&gt;not enough&lt;&#x2F;a&gt;. This means each &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt; will have to be recomputed everytime the set of signatories changes.&lt;&#x2F;p&gt;
&lt;p&gt;Using these &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt;, we aggregate signatures as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
S = \sum_{i∈\mathcal I} c_i ⋅ S_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Signature aggregation is no longer associative. In fact, it can only be done once all signers are known. To verify the aggregate signature we use a correspondingly modified check&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \sum_{i∈\mathcal I}  \e(H_i, c_i ⋅ X_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Details&lt;&#x2F;summary&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e(S, \g_2) &amp;amp;= \sum_{i∈\mathcal I}  \e(H_i, c_i ⋅ X_i) \\
\e\p{\sum_{i∈\mathcal I} c_i ⋅ S_i, \g_2} &amp;amp;= \sum_{i∈\mathcal I} \e(H_i, c_i ⋅ x_i ⋅ \g_2) \\
\sum_{i∈\mathcal I} c_i ⋅ \e\p{x_i ⋅ H_i, \g_2} &amp;amp;= \sum_{i∈\mathcal I} c_i ⋅ x_i ⋅ \e(H_i, \g_2) \\
\sum_{i∈\mathcal I} c_i ⋅ x_i ⋅ \e\p{H_i, \g_2} &amp;amp;= \sum_{i∈\mathcal I} c_i ⋅ x_i ⋅ \e(H_i, \g_2) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;p&gt;This method also optimizes to two pairings in the repeated message case&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \e\p{H, \sum_{i∈\mathcal I} c_i ⋅ X_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-gotchas&quot;&gt;Other gotchas&lt;&#x2F;h2&gt;
&lt;p&gt;The BLS signature scheme is very linear. This enables all the useful aggregation schemes above, but also allows for a number of unexpected things. Linearity in the public key allows the rogue key attack. This is why we need proof-of-possession.&lt;&#x2F;p&gt;
&lt;p&gt;Linearity in the private key has interesting behaviour around zero. For example a zero private key produces signatures valid for all messages: &lt;span class=&quot;math math-inline&quot;&gt;S = 0 ⋅ \h_{\G_1}(m) = 0&lt;&#x2F;span&gt;. This is mitigated by rejecting the public key &lt;span class=&quot;math math-inline&quot;&gt;0 ⋅ \g_2&lt;&#x2F;span&gt;. But this is not enough.&lt;&#x2F;p&gt;
&lt;p&gt;Two colluding signers pick private keys &lt;span class=&quot;math math-inline&quot;&gt;a_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;a_2 = -a_1&lt;&#x2F;span&gt; and register their public keys &lt;span class=&quot;math math-inline&quot;&gt;A_1 = a_1 ⋅ \g_2&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;A_2 = a_2 ⋅ \g_2&lt;&#x2F;span&gt;. Now anyone can claim &lt;span class=&quot;math math-inline&quot;&gt;A_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;A_2&lt;&#x2F;span&gt; are part of any aggregate signature with any message. Given a batch signature &lt;span class=&quot;math math-inline&quot;&gt;S = \sum_i x_i ⋅ H_i&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \sum_i \e(H_i, X_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; also verifies with &lt;span class=&quot;math math-inline&quot;&gt;A_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;A_2&lt;&#x2F;span&gt; signing an arbitrary message &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\e(S, \g_2) = \e(H, A_1) + \e(H, A_2) +  \sum_i \e(H_i, X_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;details&gt;&lt;summary&gt;Details&lt;&#x2F;summary&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\e(S, \g_2) &amp;amp;= \e(H, A_1) + \e(H, A_2) +  \sum_i \e(H_i, X_i) \\
\e(S, \g_2) &amp;amp;= \e(H, a_1 ⋅ \g_2) + \e(H, a_2 ⋅ \g_2) +  \sum_i \e(H_i, X_i) \\
\e(S, \g_2) &amp;amp;= a_1 ⋅ \e(H, \g_2) + a_2 ⋅ \e(H, \g_2) +  \sum_i \e(H_i, X_i) \\
\e(S, \g_2) &amp;amp;= (a_1 + a_2) ⋅ \e(H, \g_2) +  \sum_i \e(H_i, X_i) \\
\e(S, \g_2) &amp;amp;= 0 ⋅ \e(H, \g_2) +  \sum_i \e(H_i, X_i) \\
\e(S, \g_2) &amp;amp;= \sum_i \e(H_i, X_i) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;details&gt;
&lt;p&gt;This generalizes to more complex linear relations among the public keys.&lt;&#x2F;p&gt;
&lt;p&gt;Linearity in the signatures can be exploited to create two signatures that are individually invalid, but their aggregate is valid. Start with two valid signatures &lt;span class=&quot;math math-inline&quot;&gt;S_1, S_2&lt;&#x2F;span&gt; and an arbitrary non-zero point &lt;span class=&quot;math math-inline&quot;&gt;P ∈ \G_1&lt;&#x2F;span&gt;, then compute the two new signatures&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
S_1&amp;#39; &amp;amp;= S_1 + P &amp;amp; S_2&amp;#39; &amp;amp;= S_2 - P
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dan Boneh, Ben Lynn &amp;amp; Hovav Shacham (2001).
&quot;Short Signatures from the Weil Pairing&quot;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;link.springer.com&#x2F;content&#x2F;pdf&#x2F;10.1007&#x2F;3-540-45682-1_30.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A. Faz-Hernandez et al. (2021).
&quot;Hashing to Elliptic Curves&quot;. IETF Draft.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;datatracker.ietf.org&#x2F;doc&#x2F;html&#x2F;draft-irtf-cfrg-hash-to-curve-11&quot;&gt;link&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Dan Boneh et al. (2020).
&quot;BLS Signatures&quot;. IETF Draft.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;datatracker.ietf.org&#x2F;doc&#x2F;html&#x2F;draft-irtf-cfrg-bls-signature-04&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Sean Bowe (2017).
&quot;BLS12-381: New zk-SNARK Elliptic Curve Construction&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;electriccoin.co&#x2F;blog&#x2F;new-snark-curve&#x2F;&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Thomas Ristenpart &amp;amp; Scott Yilek (2007).
&quot;The Power of Proofs-of-Possession&quot;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rist.tech.cornell.edu&#x2F;papers&#x2F;pkreg.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Nguyen Thoi Minh Quan (2021).
&quot;Attacks and weaknesses of BLS aggregate signatures&quot;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2021&#x2F;377.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Dan Boneh, Manu Drijvers &amp;amp; Gregory Neven (2018).
&quot;Compact Multi-Signatures for Smaller Blockchains&quot;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2018&#x2F;483.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Dan Boneh, Manu Drijvers &amp;amp; Gregory Neven (2018).
&quot;BLS Multi-Signatures With Public-Key Aggregation&quot;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.stanford.edu&#x2F;~dabo&#x2F;pubs&#x2F;papers&#x2F;BLSmultisig.html&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Approximation theory</title>
        <published>2022-03-04T00:00:00+00:00</published>
        <updated>2022-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/approximation/"/>
        <id>https://2π.com/22/approximation/</id>
        
        <content type="html" xml:base="https://2π.com/22/approximation/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\R{\mathbb{R}}
\gdef\delim#1#2#3{#1 #2 #3}
\gdef\p#1{({#1})}
\gdef\abs#1{\lvert{#1}\rvert}
\gdef\argmin{\mathop{\operatorname{arg\,min}}\limits}
\gdef\e{\mathrm{e}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;approximation-theory&quot;&gt;Approximation theory&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\e{\mathrm{e}}
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{\delim({#1})}
\gdef\abs#1{\delim\vert{#1}\vert}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Consider &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gaussian_function&quot;&gt;this simple function&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(x) = \e^{-x^2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;func.png&quot; alt=&quot;a line resembling a speed bumb&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;you may recognize it from such hits as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Normal_distribution&quot;&gt;normal distribution&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gaussian_blur&quot;&gt;gaussian blur&lt;&#x2F;a&gt;. It has loads of applications, so we want to use it!&lt;&#x2F;p&gt;
&lt;p&gt;But what if we are in strange new lands where we only have basic math operations? Or a direct implementation doesn&#x27;t have quite the performance we are looking for?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;taylor-series&quot;&gt;Taylor series&lt;&#x2F;h3&gt;
&lt;p&gt;The first thing a calculus 101 graduate does is compute the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Taylor_series&quot;&gt;Taylor series&lt;&#x2F;a&gt;. After a moment with pen and paper the first ten terms turn out to be:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x) = 1 - 2 ⋅ x^2 + 12 ⋅ x^4 - 120 ⋅ x^6 + 1680 ⋅ x^8
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Every other term turned out zero! That feels a bit wasteful. It must have something to do with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Even_and_odd_functions&quot;&gt;odd and even functions&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now we have a nice polynomial that we can compute using basic operations. We can even trade off accuracy for performance by using fewer terms. Let&#x27;s see what it looks like with the 3, 5, 7 and 9th Taylor polynomial (dashed line is the target function):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;taylor.png&quot; alt=&quot;crapy approximations&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s... terrible. We&#x27;ll never get our function implemented this way. Time to think.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;minimize-the-maximum-error&quot;&gt;Minimize the maximum error&lt;&#x2F;h2&gt;
&lt;p&gt;So what is the goal? We want to find a simple-to-implement function &lt;span class=&quot;math math-inline&quot;&gt;p(x)&lt;&#x2F;span&gt; that best approximates our target function &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; on the domain of interest &lt;span class=&quot;math math-inline&quot;&gt;[-3, 3]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;What makes an approximation better or worse? We want to give some hard guarantee like &quot;this approximation is accurate to 12 decimals&quot;. For that, we need to consider the worst case behaviour, where the error is largest. This is maximum of &lt;span class=&quot;math math-inline&quot;&gt;\abs{f(x) - p(x)}&lt;&#x2F;span&gt; in the domain. We want the &lt;span class=&quot;math math-inline&quot;&gt;p(x)&lt;&#x2F;span&gt; that minimizes this value. In math-speak, we want:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\argmin_{p} \max_{x ∈ [a, b]} \abs{f(x) - p(x)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Minimax_approximation_algorithm&quot;&gt;minimax&lt;&#x2F;a&gt; approximation. It is different from the more common &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Least_squares&quot;&gt;least squares&lt;&#x2F;a&gt; approximation. Minimax is much harder to solve which is why least squares is more popular, but for use cases like approximation you really need the robust guarantees that you can only get from minimax. In this post I&#x27;ll show you how to solve these minimax problems by building up to it.&lt;&#x2F;p&gt;
&lt;p&gt;Before we go any further, often the first thing you do when approximating a function is exploit its symmetries to reduce the range. For example, our target function is symmetrical around the vertical axis: &lt;span class=&quot;math math-inline&quot;&gt;f(-x) = f(x)&lt;&#x2F;span&gt;. We can use this to reduce the domain to &lt;span class=&quot;math math-inline&quot;&gt;[0, 3]&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; and&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; abs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # ... rest of the function, now with x in [0, 3]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we just need to implement &lt;span class=&quot;math math-inline&quot;&gt;p(x)&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;[0,3]&lt;&#x2F;span&gt; using only basic operations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;polynomial-interpolation&quot;&gt;Polynomial interpolation&lt;&#x2F;h2&gt;
&lt;p&gt;With the basic operations addition and multiplication we can only construct &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial&quot;&gt;polynomials&lt;&#x2F;a&gt;. (If we also have division we can do rational functions, more on that later.) For now we want polynomials that we can implement using few operations. A pretty good way to implement polynomials is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Horner%27s_method&quot;&gt;Horner&#x27;s method&lt;&#x2F;a&gt; (it is a common misconception that Horner&#x27;s method is optimal, but this is a subject for another blog post.) Using Horner&#x27;s method, the number of operations is proportional to the number of terms in the polynomial. Let&#x27;s start with a five term polynomial:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x) = p_0 + p_1 ⋅ x + p_2 ⋅ x^2 + p_3 ⋅ x^3 + p_4 ⋅ x^4
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It has five parameters &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt; that we need to pick. One way to do this is by picking five points &lt;span class=&quot;math math-inline&quot;&gt;(x_i, y_i)&lt;&#x2F;span&gt; on the target function and insisting that the polynomial goes through those points. Let&#x27;s pick &lt;span class=&quot;math math-inline&quot;&gt;n=5&lt;&#x2F;span&gt; points evenly spaced over the domain &lt;span class=&quot;math math-inline&quot;&gt;[a, b]=[0,3]&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_i &amp;amp;= a + \frac{i}{n - 1}\p{b-a} &amp;amp;&amp;amp;&amp;amp; y_i &amp;amp;= f(x_i)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;equispaced.png&quot; alt=&quot;equispaced points on the curve&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This results in five equations &lt;span class=&quot;math math-inline&quot;&gt;p(x_i) = y_i&lt;&#x2F;span&gt;. Fully expanded, each one looks like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_0 + p_1 ⋅ x_i + p_2 ⋅ x_i^2 + p_3 ⋅ x_i^3 + p_4 ⋅ x_i^4 = y_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We know the &lt;span class=&quot;math math-inline&quot;&gt;(x_i, y_i)&lt;&#x2F;span&gt;&#x27;s and want to solve for the &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt;&#x27;s. We can compute all the powers of &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; and we end up with &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt;&#x27;s multiplied by constants; a system of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;System_of_linear_equations&quot;&gt;linear equations&lt;&#x2F;a&gt;. We can write this as a matrix:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\def\arraystretch{1.3}
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; x_0^3 &amp;amp; x_0^4 \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; x_1^3 &amp;amp; x_1^4 \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; x_2^3 &amp;amp; x_2^4 \\
1 &amp;amp; x_3 &amp;amp; x_3^2 &amp;amp; x_3^3 &amp;amp; x_3^4 \\
1 &amp;amp; x_4 &amp;amp; x_4^2 &amp;amp; x_4^3 &amp;amp; x_4^4
\end{bmatrix} \cdot
\begin{bmatrix}
p_0 \\ p_1 \\ p_2 \\ p_3 \\ p_4
\end{bmatrix} =
\begin{bmatrix}
y_0 \\ y_1 \\ y_2 \\ y_3 \\ y_4
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This kind of matrix is called a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vandermonde_matrix&quot;&gt;Vandermonde matrix&lt;&#x2F;a&gt;. We can solve it using basic linear algebra to get our &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt;&#x27;s. In this case&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_i = \small\begin{bmatrix}
 1.0000 &amp;amp; -0.1493 &amp;amp; -0.9330 &amp;amp; 0.5560 &amp;amp; -0.0885
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The solution polynomial we found looks like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;equispaced-5.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That is &lt;em&gt;much&lt;&#x2F;em&gt; better than any of our Taylor polynomials, and we used only five terms instead of ten! In fact, it&#x27;s already hard to see the error, so let&#x27;s zoom in on the error &lt;span class=&quot;math math-inline&quot;&gt;p(x) - f(x)&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;equispaced-5-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s nicely meandering back and forth around zero, crossing zero exactly where we picked the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; values. It has a maximum error less than &lt;span class=&quot;math math-inline&quot;&gt;0.037&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;What if we use ten terms? We can re-do all the above with &lt;span class=&quot;math math-inline&quot;&gt;n=10&lt;&#x2F;span&gt; points and we get:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;equispaced-10.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The approximation now looks perfect! We need to look at the error to see what is going on:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;equispaced-10-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The maximum error is now nearly &lt;span class=&quot;math math-inline&quot;&gt;0.001&lt;&#x2F;span&gt;, almost 3 decimals of precision! Notice how the largest error is again at the ends. This gets worse as we add more terms and is an example of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Runge%27s_phenomenon&quot;&gt;Runge&#x27;s phenomenon&lt;&#x2F;a&gt;. Let&#x27;s fix that!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;chebyshev-nodes&quot;&gt;Chebyshev nodes&lt;&#x2F;h3&gt;
&lt;p&gt;Runge&#x27;s phenomenon happens on equaly spaced interpolations. To counter it we need to move the points more towards the edges. Intuitively this forces the polynomial to learn more about the edges and be more accurate there. A special set of points called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chebyshev_nodes&quot;&gt;Chebyshev nodes&lt;&#x2F;a&gt; does this. On the domain &lt;span class=&quot;math math-inline&quot;&gt;[a, b]&lt;&#x2F;span&gt; they are defined as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_i &amp;amp;= \frac{a+b}{2} + \frac{b-a}{2} \cos\p{\frac{2 ⋅i + 1}{2 ⋅ n} ⋅ π} &amp;amp;&amp;amp;&amp;amp; y_i &amp;amp;= f(x_i)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using these points, the five term interpolation looks like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;chebyshev-5.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;chebyshev-5-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The maximum error reduced slightly and no longer happens at the ends. With Chebyshev nodes the ten term interpolation looks like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;chebyshev-10.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;chebyshev-10-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The error is about &lt;span class=&quot;math math-inline&quot;&gt;1.5\cdot10^{-4}&lt;&#x2F;span&gt; that is nearly four accurate digits, a 10x improvement over the previous equispaced version! There is also no sign of Runge&#x27;s phenomenon anymore.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-equioscilation-theorem&quot;&gt;The equioscilation theorem&lt;&#x2F;h2&gt;
&lt;p&gt;If you look at the last error plot you&#x27;ll notice how the error wobbles smoothly and uniformly from negative to positive, instead of having large peaks like before. This apparently results in a lower overall error. It makes intuitive sense: by spreading the error evenly over all places, it doesn&#x27;t pile up in a big peak and we reduce the maximum error.&lt;&#x2F;p&gt;
&lt;p&gt;This is actually a profound fact called the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Equioscillation_theorem&quot;&gt;equioscillation theorem&lt;&#x2F;a&gt;. In plain words a &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-term polynomial is the best possible approximation if and only if its error goes back and forth at least &lt;span class=&quot;math math-inline&quot;&gt;n + 1&lt;&#x2F;span&gt; times, each time hitting the maximum error.&lt;&#x2F;p&gt;
&lt;p&gt;We can find this optimum manually: by moving the points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; around we can reduce the error in an area by moving the points a little closer there, or moving them away from areas where the error is very small. If we keep doing this we will end up with all the &#x27;error&#x27; evenly spread out. Starting with the five term Chebyshev solution, after a lot of manual fiddling with values we find a &#x27;tuned&#x27; set of &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; that gives a decently flat error:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x_i = \small \begin{bmatrix} 0.11 &amp;amp; 0.72 &amp;amp; 1.51 &amp;amp; 2.34 &amp;amp; 2.92 \end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;poly-manual-5-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But this is a lot of work, let&#x27;s automate it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;remez-algorithm&quot;&gt;Remez algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;The hero of this story is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Evgeny_Yakovlevich_Remez&quot;&gt;Е.Я́. Ре́мез&lt;&#x2F;a&gt; (Remez) from Kyiv University. He&#x27;s known for the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Remez_algorithm&quot;&gt;Remez algorithm&lt;&#x2F;a&gt; that finds the optimal polynomial automatically. The algorithm works backwards from the equioscillation theorem: assume that our polynomial &lt;span class=&quot;math math-inline&quot;&gt;p(x)&lt;&#x2F;span&gt; satisfies the equioscillation theorem, then there is a set of points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x_i) = f(x_i) \pm e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; is the maximum error and &lt;span class=&quot;math math-inline&quot;&gt;\pm&lt;&#x2F;span&gt; alternates signs. This is the first great insight: instead of trying to interpolate the function perfectly, we interpolate it &lt;em&gt;with error included&lt;&#x2F;em&gt;. This way we control the error and can place it optimally. The points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; are the &lt;span class=&quot;math math-inline&quot;&gt;n+2&lt;&#x2F;span&gt; peaks where we want the maximum error to manifest. Writing this out for a five term polynomial we get equations&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_0 + p_1 ⋅ x_i + p_2 ⋅ x_i^2 + p_3 ⋅ x_i^3 + p_4 ⋅ x_i^4 \pm e = y_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we knew the values &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; this would again be a linear equation with unknowns &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt;. In fact, we have &lt;span class=&quot;math math-inline&quot;&gt;n+1&lt;&#x2F;span&gt; equations, so we can use the extra equation to also solve for the maximum error &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;. But we don&#x27;t know the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; coordinates of the error maxima. The second great insight Remez had was that: &lt;em&gt;if you start with approximate values &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; you will get better ones&lt;&#x2F;em&gt;. Cool! So let&#x27;s take the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; from our five term Chebyshev. That is, we find the &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; coordinates of all the peaks in the error:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;remez-5-nodes.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With these &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; we can write our equations as a linear algebra problem&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\def\arraystretch{1.3}
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; x_0^3 &amp;amp; x_0^4 &amp;amp; +1 \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; x_1^3 &amp;amp; x_1^4 &amp;amp; -1 \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; x_2^3 &amp;amp; x_2^4 &amp;amp; +1 \\
1 &amp;amp; x_3 &amp;amp; x_3^2 &amp;amp; x_3^3 &amp;amp; x_3^4 &amp;amp; -1 \\
1 &amp;amp; x_4 &amp;amp; x_4^2 &amp;amp; x_4^3 &amp;amp; x_4^4 &amp;amp; +1 \\
1 &amp;amp; x_5 &amp;amp; x_5^2 &amp;amp; x_5^3 &amp;amp; x_5^4 &amp;amp; -1 \\
\end{bmatrix}
\cdot
\begin{bmatrix}
c_0 \\ c_1 \\ c_2 \\ c_3 \\ c_4 \\ e
\end{bmatrix} =
\begin{bmatrix}
y_0 \\ y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This gets us values for &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;e=0.0209&lt;&#x2F;span&gt;. Neat! Let&#x27;s plot the error for our new five term polynomial:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;remez-5-1-iter-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is indeed looking more optimal than the Chebyshev we started with; the errors all look close to the same height! The actual error is &lt;span class=&quot;math math-inline&quot;&gt;0.0212&lt;&#x2F;span&gt;, that is a &lt;span class=&quot;math math-inline&quot;&gt;20\%&lt;&#x2F;span&gt; improvement. Note that the computed error &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; does not match the actual error, this is due to our &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s being inaccurate. The solution is already better than our hand-tuned one, but it&#x27;s not perfect yet as there are still slight difference in the peak heights.&lt;&#x2F;p&gt;
&lt;p&gt;Remez is an iterative method. We repeat the same process, this time picking &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s from the error peaks of the polynomial we just found. We get a new set of &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt;&#x27;s and &lt;span class=&quot;math math-inline&quot;&gt;e = 0.0208&lt;&#x2F;span&gt;. The actual error is also &lt;span class=&quot;math math-inline&quot;&gt;0.0208&lt;&#x2F;span&gt;. This is a sign that the algorithm is converging on the optimal polynomial. Doing more iterations doesn&#x27;t really change the result much, Remez converges pretty fast. This is what we get:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;remez-5-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is what perfection looks like! It goes back and forth six times, hitting the maximum error each time. By the equioscillation theorem, this is the best possible approximation with a five term polynomial. It is however only a &lt;span class=&quot;math math-inline&quot;&gt;\small 21\%&lt;&#x2F;span&gt; reduction of the error compared to Chebyshev. Generally Chebyshev polynomials are already close to optimal. This will change when we get to rational approximations in a moment.&lt;&#x2F;p&gt;
&lt;p&gt;When using Remez, it can sometimes happen that the error has more than &lt;span class=&quot;math math-inline&quot;&gt;n+1&lt;&#x2F;span&gt; peaks. If this happens a good strategy is to take a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Subsequence&quot;&gt;subsequence&lt;&#x2F;a&gt; of &lt;span class=&quot;math math-inline&quot;&gt;n+1&lt;&#x2F;span&gt; peaks such that their signs alternate and the smallest one is as large as possible.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rational-approximation&quot;&gt;Rational approximation&lt;&#x2F;h2&gt;
&lt;p&gt;What if we can do addition, multiplication, and also &lt;em&gt;division&lt;&#x2F;em&gt;? Every function we can construct with these will be a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rational_function&quot;&gt;rational function&lt;&#x2F;a&gt;. They are not nearly as well known a the polynomials and this needs to change! They are not very difficult as every rational function &lt;span class=&quot;math math-inline&quot;&gt;h(x)&lt;&#x2F;span&gt; can be written as a fraction of two polynomials&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
h(x) = \frac{p(x)}{q(x)} = \frac{p_0 + p_1 ⋅x + p_2 ⋅x^2}{q_0 + q_1 ⋅ x + q_2 ⋅ x^2 + q_3 ⋅ x^3}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We now need to pick the number of terms for both &lt;span class=&quot;math math-inline&quot;&gt;p(x)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;q(x)&lt;&#x2F;span&gt;. Let&#x27;s call the above the &lt;span class=&quot;math math-inline&quot;&gt;\small (3,4)&lt;&#x2F;span&gt;-term rational function. This formula looks like it has seven parameters, but it&#x27;s really one less: just like how fractions can be reduced, for example &lt;span class=&quot;math math-inline&quot;&gt;\frac{9}{12} = \frac{3}{4}&lt;&#x2F;span&gt;, the rational functions can also be &#x27;reduced&#x27; by dividing out a common factor. For example we can divide out &lt;span class=&quot;math math-inline&quot;&gt;q_0&lt;&#x2F;span&gt;, effectively setting &lt;span class=&quot;math math-inline&quot;&gt;q_0 = 1&lt;&#x2F;span&gt;. The other parameters can still take any value (though they will be different by a factor &lt;span class=&quot;math math-inline&quot;&gt;\frac{1}{q_0}&lt;&#x2F;span&gt;. We could have picked any parameter and fix it to any non-zero value, but &lt;span class=&quot;math math-inline&quot;&gt;q_0=1&lt;&#x2F;span&gt; makes the math easier. Another common convention is to set &lt;span class=&quot;math math-inline&quot;&gt;q_{n-1} = 1&lt;&#x2F;span&gt;, which saves a single multiplication when evaluating. It is easy to convert between the two.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s create a five-parameter rational approximation to compare with the five-parameter polynomial from before. Specifically let&#x27;s look at a &lt;span class=&quot;math math-inline&quot;&gt;\small (3,3)&lt;&#x2F;span&gt;-term rational function:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
h(x) = \frac{p(x)}{q(x)} = \frac{p_0 + p_1 ⋅x + p_2 ⋅x^2}{1 + q_1 ⋅ x + q_2 ⋅ x^2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Like before, to solve for &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;q_i&lt;&#x2F;span&gt; we interpolate through points &lt;span class=&quot;math math-inline&quot;&gt;(x_i, y_i)&lt;&#x2F;span&gt;. This time a bit more algebra is required:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\begin{aligned}
h(x_i) &amp;amp;= \frac{p(x_i)}{q(x_i)} = y_i &amp;amp;\Rightarrow&amp;amp;&amp;amp;
p(x_i) &amp;amp;= y_i ⋅ q(x_i) &amp;amp;\Rightarrow \[0.5em]
\end{aligned}&lt;&#x2F;p&gt;
&lt;p&gt;\begin{aligned}
&amp;amp;p_0 + p_1 ⋅x_i + p_2 ⋅x_i^2 = y_i ⋅\p{1 + q_1 ⋅ x + q_2 ⋅ x^2} \Rightarrow\[0.7em]
&amp;amp;p_0 + p_1 ⋅x_i + p_2 ⋅x_i^2 -  q_1 ⋅ y_i ⋅ x_i - q_2 ⋅ y_i ⋅ x_i^2 = y_i
\end{aligned}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;y_i&lt;&#x2F;span&gt; are constant, this is again linear and we can solve for &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;q_i&lt;&#x2F;span&gt;. The linear system is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\def\arraystretch{1.3}
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; - y_0 ⋅ x_0 &amp;amp; - y_0 ⋅ x_0^2 \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; - y_1 ⋅ x_1 &amp;amp; - y_1 ⋅ x_1^2 \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; - y_2 ⋅ x_2 &amp;amp; - y_2 ⋅ x_2^2 \\
1 &amp;amp; x_3 &amp;amp; x_3^2 &amp;amp; - y_3 ⋅ x_3 &amp;amp; - y_3 ⋅ x_3^2 \\
1 &amp;amp; x_4 &amp;amp; x_4^2 &amp;amp; - y_4 ⋅ x_4 &amp;amp; - y_4 ⋅ x_4^2 \\
\end{bmatrix} \cdot
\begin{bmatrix}
p_0 \\ p_1 \\ p_2 \\ q_0 \\ q_1
\end{bmatrix} =
\begin{bmatrix}
y_0 \\
y_1 \\
y_2 \\
y_3 \\
y_4 \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using the same five Chebyshev points &lt;span class=&quot;math math-inline&quot;&gt;(x_i, y_i)&lt;&#x2F;span&gt; as before we find the solution&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
p_i &amp;amp;= \small\begin{bmatrix} 0.99524975 &amp;amp; -0.72539761 &amp;amp;  0.13181353 \end{bmatrix} \\
q_i &amp;amp;= \small\begin{bmatrix} 1.00000000 &amp;amp; -0.77962832 &amp;amp;  0.93440655 \end{bmatrix}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;ratfn-3-3.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;ratfn-3-3-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The maximum error is now &lt;span class=&quot;math math-inline&quot;&gt;\small 0.02015&lt;&#x2F;span&gt;, this is even better than the optimal five-term polynomial we found. It does look like all the error is on the left now. Can we move points around and get a better result like before? Let&#x27;s manually move  the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s around again. After some fiddling and nudging the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s we find a set that works well:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x_i = \small \begin{bmatrix} 0.29 &amp;amp; 0.73 &amp;amp; 1.28 &amp;amp; 1.99 &amp;amp; 2.82 \end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;ratfn-manual-3-3-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We got the error to drop $\small 81$% and nearly got a whole extra digit of precision! So clearly rational functions are promising and fine-tuning them has a big impact. Notice that as it got better, it also starts to look more like a nice equioscillation error. It is a little know fact (not even Wikipedia mentions it) that &lt;em&gt;the equioscillation theorem also applies to rational functions&lt;&#x2F;em&gt;!&lt;&#x2F;p&gt;
&lt;p&gt;You may be wondering why we picked a &lt;span class=&quot;math math-inline&quot;&gt;\small (3,3)&lt;&#x2F;span&gt;-term rational function, and not one of the other five parameter options. The &lt;span class=&quot;math math-inline&quot;&gt;\small (5,1)&lt;&#x2F;span&gt;-term rational function is simply the five term polynomial we saw before. But let&#x27;s look at the &lt;span class=&quot;math math-inline&quot;&gt;\small (4,2)&lt;&#x2F;span&gt;-term one. We can solve the equations as before and get the solution:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
p_i &amp;amp;= \small\begin{bmatrix} 1.04506339 &amp;amp; -1.58632468 &amp;amp; 0.74871783 &amp;amp; -0.11232492 \end{bmatrix} \\
q_i &amp;amp;= \small\begin{bmatrix} 1.00000000 &amp;amp; -0.84949604 \end{bmatrix}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But when we plot &lt;span class=&quot;math math-inline&quot;&gt;h(x) = p(x)&#x2F;q(x)&lt;&#x2F;span&gt; function we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;ratfn-fail-4-2.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Whoops! That does not look good! It goes through the five points alright, but what happens between the second and third point? A bit of debugging and you find that at &lt;span class=&quot;math math-inline&quot;&gt;x = q_1^{-1} ≈ 1.18&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;q(x) = 0&lt;&#x2F;span&gt; and thus a division by zero. We can not use solutions where &lt;span class=&quot;math math-inline&quot;&gt;q(x)&lt;&#x2F;span&gt; has a zero in the domain. It turns out some combinations of &lt;span class=&quot;math math-inline&quot;&gt;(n,m)&lt;&#x2F;span&gt;-terms simply don&#x27;t work. A good strategy is to try all combinations and pick the one that gives the best result. For five terms &lt;span class=&quot;math math-inline&quot;&gt;\small (3,3)&lt;&#x2F;span&gt; is optimal.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rational-remez&quot;&gt;Rational-Remez&lt;&#x2F;h3&gt;
&lt;p&gt;For rational functions the Cehbyshev solution is good, but fine-tuning has a big impact. Let&#x27;s try to optimize this process with Remez algorithm again. We start the same by working backwards from the goal. The algebra is a bit more complex now, but we get&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
h(x_i) &amp;amp;= y_i \pm  e &amp;amp;\Rightarrow&amp;amp;&amp;amp;
\frac{p(x_i)}{q(x_i)} &amp;amp;= y_i \pm e &amp;amp;\Rightarrow&amp;amp;&amp;amp;
p(x_i) &amp;amp;= \p{y_i \pm  e} ⋅ q(x_i) \\[1em]
p_0 + p_1 ⋅ x_i + p_2 ⋅x_i^2
&amp;amp;= \p{y_i \pm  e} ⋅ \p{1 + q_1 ⋅ x_i + q_2 ⋅ x_i^2} \\[1em]
p_0 + p_1 ⋅ x_i + p_2 ⋅x_i^2 - q_1 ⋅ \p{y_i \pm  e} ⋅ x_i - q_2 ⋅ \p{y_i \pm  e} ⋅ x_i^2 \mp e
&amp;amp;= y_i
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Hmm. We now have &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; terms added to our &lt;span class=&quot;math math-inline&quot;&gt;y_i&lt;&#x2F;span&gt;&#x27;s. We can&#x27;t solve this like before where we guess &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;y_i&lt;&#x2F;span&gt; and solve for &lt;span class=&quot;math math-inline&quot;&gt;p_i&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;q_i&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;. Fortunately, we can also guess &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; from an approximate solution. We can still solve for the final &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; term, this will come in handy in a moment. Writing this out in linear algebra again&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\def\arraystretch{1.3}
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; - \p{y_0 + e} ⋅ x_0 &amp;amp; - \p{y_0 + e} ⋅ x_0^2 &amp;amp; -1 \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; - \p{y_1 - e} ⋅ x_0 &amp;amp; - \p{y_1 - e} ⋅ x_1^2 &amp;amp; +1 \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; - \p{y_2 + e} ⋅ x_0 &amp;amp; - \p{y_2 + e} ⋅ x_2^2 &amp;amp; -1 \\
1 &amp;amp; x_3 &amp;amp; x_3^2 &amp;amp; - \p{y_3 - e} ⋅ x_0 &amp;amp; - \p{y_3 - e} ⋅ x_3^2 &amp;amp; +1 \\
1 &amp;amp; x_4 &amp;amp; x_4^2 &amp;amp; - \p{y_4 + e} ⋅ x_0 &amp;amp; - \p{y_4 + e} ⋅ x_4^2 &amp;amp; -1 \\
1 &amp;amp; x_5 &amp;amp; x_5^2 &amp;amp; - \p{y_5 + e} ⋅ x_0 &amp;amp; - \p{y_5 + e} ⋅ x_5^2 &amp;amp; +1 \\
\end{bmatrix} \cdot
\begin{bmatrix}
p_0 \\ p_1 \\ p_2 \\ q_1 \\ q_2 \\ e&amp;#39;
\end{bmatrix} =
\begin{bmatrix}
y_0 \\ y_1 \\ y_2 \\ y_3 \\ y_4 \\ y_5
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Like before, we can start the Remez iteration with an initial Chebyshev solution. Take the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s from the error peaks, take &lt;span class=&quot;math math-inline&quot;&gt;y_i = f(x_i)&lt;&#x2F;span&gt;, and this time we also guess &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; to be the maximum error from the initial solution. This will give us an output error &lt;span class=&quot;math math-inline&quot;&gt;e&amp;#39;&lt;&#x2F;span&gt; that is likely different from our guessed &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;. The first step is to make these two equal by picking a better guess for &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;. There are different methods for doing this, but what worked well for me is taking the mean of the guess and computed value, i.e. the new guess for &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;\frac{e + e&amp;#39;}{2}&lt;&#x2F;span&gt;. If we iterate this process a couple of times &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;e&amp;#39;&lt;&#x2F;span&gt; will converge. This means we found a solution to our non-linear problem. We then take the resulting function, and like before update our guesses for the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s. We repeat this whole process a few times until the Rational-Remez converges, each time solving for &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; first before updating the &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;&#x27;s. The final result has an error that looks like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;ratfn-remez-3-3-err.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is the best possible &lt;span class=&quot;math math-inline&quot;&gt;\small (3,3)&lt;&#x2F;span&gt;-term rational function. It has a &lt;span class=&quot;math math-inline&quot;&gt;\small 6&lt;&#x2F;span&gt; times smaller error than the Chebyshev rational and &lt;span class=&quot;math math-inline&quot;&gt;\small 8&lt;&#x2F;span&gt; times smaller than the Chebyshev polynomial.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;method-comparison&quot;&gt;Method comparison&lt;&#x2F;h2&gt;
&lt;p&gt;I picked five parameters because it shows how things work while still allowing readable explicit formulas. The pattern should be clear and can be generalized to any number of parameters.&lt;&#x2F;p&gt;
&lt;p&gt;From equispaced to Remez-Rational, we now have five progressively more sophisticated approximation methods. To compare them, we can plot how many decimal digits of accuracy they give for increasing numbers of parameters:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;22&#x2F;approximation&#x2F;convergence.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In this figure we can see that Chebyshev polynomial approximations are significantly better than equispaced ones and in fact they are almost as good as the optimal Remez polynomials. This validates the common wisdom that for polynomials Chebyshev is good enough and Remez is not worth the complexity.&lt;&#x2F;p&gt;
&lt;p&gt;What we see here is that rational functions have a significant advantage over plain polynomials. Here Chebyshev points alone leave some accuracy on the table and optimizing using the rational Remez algorithm pays of.&lt;&#x2F;p&gt;
&lt;p&gt;All of the above assumes we are working with real numbers &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt; but in reality computers have limited precision. When finding and evaluation approximation functions it is convenient to use an arbitrary precision library like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.mpfr.org&#x2F;&quot;&gt;mpfr&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mpmath.org&#x2F;&quot;&gt;mpmath&lt;&#x2F;a&gt;. Then crank up the precision to much higher than your target. That way we don&#x27;t have to worry about it. You can find a Jupyter notebook implementation &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;recmo&#x2F;experiment-solexp&#x2F;blob&#x2F;main&#x2F;approximate_mpmath.ipynb&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-takeaways&quot;&gt;Key takeaways&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;🌟 Almost any function can be approximated efficiently.&lt;&#x2F;li&gt;
&lt;li&gt;👉 First use knowledge of your function to reduce the domain.&lt;&#x2F;li&gt;
&lt;li&gt;🚫  Don&#x27;t use Taylor series or equispaced points.&lt;&#x2F;li&gt;
&lt;li&gt;✅ Use Chebyshev approximation if you need a polynomial.&lt;&#x2F;li&gt;
&lt;li&gt;🚀 Rational functions can offer a significant improvement.&lt;&#x2F;li&gt;
&lt;li&gt;🤓 Remez on rational functions is difficult, but offers an improvement.&lt;&#x2F;li&gt;
&lt;li&gt;👉 Use a high-precision arithmetic library to find approximations.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;what-s-next&quot;&gt;What&#x27;s next&lt;&#x2F;h3&gt;
&lt;p&gt;Once you have found an approximation you are happy with, the next step is to implement it. This is where we have to leave arbitrary precision arithmetic behind and instead use integer, fixed-point or floating-point math. This introduces new errors that must be mitigated or accounted for. “Evaluating polynomials efficiently and accurately” is a topic for a future post.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;L.N. Trefethen (2019).
“Approximation Theory and Approximation Practice.”
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;epubs.siam.org&#x2F;doi&#x2F;book&#x2F;10.1137&#x2F;1.9781611975949&quot;&gt;available online&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;T.A. Driscoll, N. Hale, and L.N. Trefethen, editors (2014)
&quot;Chebfun Guide”
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.chebfun.org&#x2F;publications&#x2F;&quot;&gt;website&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;ARM Limited (2019).
Remez routine source code.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ARM-software&#x2F;optimized-routines&#x2F;blob&#x2F;4c32619682de9d8632fe039153a3e26a6f095482&#x2F;math&#x2F;tools&#x2F;remez.jl&quot;&gt;github&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;J.J. O&#x27;Connor and E.F. Robertson (2018).
“Evgeny Yakovlevich Remez”
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mathshistory.st-andrews.ac.uk&#x2F;Biographies&#x2F;Remez&#x2F;&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;N. Agrawal et al. (2021).
“Boost C++ v. 1.78.0: The Remez Method.”
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.boost.org&#x2F;doc&#x2F;libs&#x2F;1_78_0&#x2F;libs&#x2F;math&#x2F;doc&#x2F;html&#x2F;math_toolkit&#x2F;remez.html&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;C.B. Dunham (1975).
“Convergence of the Fraser-Hart Algorithm for Rational Chebyshev Approximation.”
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ams.org&#x2F;journals&#x2F;mcom&#x2F;1975-29-132&#x2F;S0025-5718-1975-0388732-9&#x2F;S0025-5718-1975-0388732-9.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Big thank you to Transmissions XI for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;transmissions11&#x2F;status&#x2F;1498880109830291462&quot;&gt;provoking me&lt;&#x2F;a&gt; to write this and great feedback on early versions of this article.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Signatures</title>
        <published>2022-01-29T00:00:00+00:00</published>
        <updated>2022-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/signatures/"/>
        <id>https://2π.com/22/signatures/</id>
        
        <content type="html" xml:base="https://2π.com/22/signatures/">&lt;h1 id=&quot;signatures&quot;&gt;Signatures&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{\left({#1}\right)}
\gdef\G{\mathrm{G}}
\gdef\H{\mathtt{H}}
\gdef\HP{\mathtt{H}_{\mathrm{P}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;\G&lt;&#x2F;span&gt; a generator of a group in which discrete logarithm is hard. Capital letters denote group elements, lower case are field elements in the groups multiplicative order, and bold are vectors of either. Take &lt;span class=&quot;math math-inline&quot;&gt;\H, \HP&lt;&#x2F;span&gt; hash functions mapping their inputs to a field element and a group element respectively.&lt;&#x2F;p&gt;
&lt;p&gt;The verification steps can all be checked using basic algebra. This is a useful exercise for the reader.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Warning.&lt;&#x2F;strong&gt; These formulas are just to clarify the basic schemes and omit many security critical checks.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;schnorr-signatures&quot;&gt;Schnorr Signatures&lt;&#x2F;h2&gt;
&lt;p&gt;Bob wants to authenticate a message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; to Alice. Bob generates a random number &#x27;private key&#x27; &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and computes &#x27;public key&#x27; &lt;span class=&quot;math math-inline&quot;&gt;B = b ⋅\G&lt;&#x2F;span&gt;. Bob securely shares &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; with Alice. Bob computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
R &amp;amp;= \H(b, m) ⋅ \G &amp;amp;
e &amp;amp;= \H(R, m) &amp;amp;
s &amp;amp;= \H(b, m) - e ⋅ b
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bob sends the message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and signature &lt;span class=&quot;math math-inline&quot;&gt;(e, s)&lt;&#x2F;span&gt; to Alice. Alice verifies by recovering &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; and checking &lt;span class=&quot;math math-inline&quot;&gt;\H(R, m) = e&lt;&#x2F;span&gt; using&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
R &amp;amp;= s ⋅ \G  + e ⋅ B &amp;amp;
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note: sometimes &lt;span class=&quot;math math-inline&quot;&gt;\H(R, B, m)&lt;&#x2F;span&gt; is used instead of &lt;span class=&quot;math math-inline&quot;&gt;\H(R, m)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As a variant, the signature is &lt;span class=&quot;math math-inline&quot;&gt;(R, s)&lt;&#x2F;span&gt; which is verified by recovering &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; using&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
B = \frac{R - s ⋅ G}{\H(R, m)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;elgamal-dsa-signatures&quot;&gt;ElGamal &#x2F; DSA Signatures&lt;&#x2F;h2&gt;
&lt;p&gt;Bob wants to authenticate a message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; to Alice. Bob generates a random number &#x27;private key&#x27; &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and computes &#x27;public key&#x27; &lt;span class=&quot;math math-inline&quot;&gt;B = b ⋅\G&lt;&#x2F;span&gt;. Bob securely shares &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; with Alice. Bob computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
R &amp;amp;= \H(b, m) ⋅ \G &amp;amp;
s &amp;amp;= \frac{\H(m) + \H(R) ⋅ b}{\H(b, m)}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bob sends the message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and signature &lt;span class=&quot;math math-inline&quot;&gt;(R, s)&lt;&#x2F;span&gt; to Alice. Alice verifies by checking&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\H(m) ⋅ \G + \H(R) ⋅ B - s ⋅ R = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively, Alice verifies by recovering &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; using&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
B = \frac{s ⋅ R - \H(m) ⋅ \G}{\H(R)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is common to take &lt;span class=&quot;math math-inline&quot;&gt;\H(R)&lt;&#x2F;span&gt; to be the &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;-coordinate of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;. This is not a good hash since &lt;span class=&quot;math math-inline&quot;&gt;\H(-R) = \H(R)&lt;&#x2F;span&gt;. In this case &lt;span class=&quot;math math-inline&quot;&gt;(-R, -s)&lt;&#x2F;span&gt; would also a valid signature.&lt;&#x2F;p&gt;
&lt;p&gt;If instead of &lt;span class=&quot;math math-inline&quot;&gt;\H(b,m)&lt;&#x2F;span&gt; an arbitrary non-trivial value &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; is used this also results in a valid signature. However, if the same &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; is used to sign multiple messages &lt;span class=&quot;math math-inline&quot;&gt;m_1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;m_2&lt;&#x2F;span&gt; with signatures &lt;span class=&quot;math math-inline&quot;&gt;(R_1, s_1), (R_2, s_2)&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;R_1 = R_2&lt;&#x2F;span&gt; and we can recover &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
k &amp;amp;= \frac{\H(m_1) - \H(m_2)}{s_1 - s_2} &amp;amp;
b &amp;amp;= \frac{k ⋅ s_1 - \H(m_1)}{\H(R)}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As a variant, the signature can be &lt;span class=&quot;math math-inline&quot;&gt;(\H(R), s)&lt;&#x2F;span&gt; which is then verified using&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\H\p{\frac{\H(m)}{s} ⋅ \G + \frac{\H(R)}{s} ⋅ B} = \H(R)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Again, if &lt;span class=&quot;math math-inline&quot;&gt;\H(R)&lt;&#x2F;span&gt; is simply the &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;-coordinate, &lt;span class=&quot;math math-inline&quot;&gt;\H(-R) = \H(R)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(\H(R), -s)&lt;&#x2F;span&gt; is also a valid signature.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;blind-signatures&quot;&gt;Blind Signatures&lt;&#x2F;h2&gt;
&lt;p&gt;Alice and Bob want Bob to sign &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; without revealing &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; to Bob. For example, Bob is notary that verifies Alice&#x27;s passport to authenticates Alice&#x27;s messages. Alice does not want Bob to know their content. Bob has a key pair &lt;span class=&quot;math math-inline&quot;&gt;b, B&lt;&#x2F;span&gt;. Bob generates a random number &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;, computes &lt;span class=&quot;math math-inline&quot;&gt;R&amp;#39; = k ⋅ \G&lt;&#x2F;span&gt; and sends &lt;span class=&quot;math math-inline&quot;&gt;R&amp;#39;&lt;&#x2F;span&gt; to Alice. Alice generates random numbers &lt;span class=&quot;math math-inline&quot;&gt;u, v&lt;&#x2F;span&gt; and computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
R &amp;amp;= u ⋅ R&amp;#39; + v ⋅\G &amp;amp;
m&amp;#39; &amp;amp;= \frac{\H(R, m)}{u}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Alice sends &lt;span class=&quot;math math-inline&quot;&gt;m&amp;#39;&lt;&#x2F;span&gt; to Bob. Bob computes &lt;span class=&quot;math math-inline&quot;&gt;s&amp;#39; = k - m&amp;#39; ⋅ b&lt;&#x2F;span&gt; and sends &lt;span class=&quot;math math-inline&quot;&gt;s&amp;#39;&lt;&#x2F;span&gt; to Alice. Alice computes &lt;span class=&quot;math math-inline&quot;&gt;s = u ⋅ s&amp;#39; + v&lt;&#x2F;span&gt; The signature is &lt;span class=&quot;math math-inline&quot;&gt;(R, s)&lt;&#x2F;span&gt;. Verification is as in Schnorr by recovering Bob&#x27;s key:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
B = \frac{R - s ⋅ \G}{\H(R, m)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ring-signatures&quot;&gt;Ring Signatures&lt;&#x2F;h2&gt;
&lt;p&gt;There are many Bob&#x27;s all with key pairs &lt;span class=&quot;math math-inline&quot;&gt;b_i, B_i&lt;&#x2F;span&gt;. Alice has public keys &lt;span class=&quot;math math-inline&quot;&gt;\vec B = B_1, \dots B_n&lt;&#x2F;span&gt;. Bob number &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; wants to send a message to Alice without revealing &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt;. Bob generates random numbers &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt; except &lt;span class=&quot;math math-inline&quot;&gt;r_s&lt;&#x2F;span&gt;. Bob computes the recursion (with indices wrapping around) and completes &lt;span class=&quot;math math-inline&quot;&gt;\vec r&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
c_s &amp;amp;= \H(\vec B, m, k ⋅ \G) &amp;amp;
c_i &amp;amp;= \H(\vec B, m, r_i ⋅ \G + c_{i - 1} ⋅ B_i) &amp;amp;
r_s &amp;amp;= k - c_{s - 1} ⋅ b_s
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bob sends &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and the signature &lt;span class=&quot;math math-inline&quot;&gt;(c_1, \vec r)&lt;&#x2F;span&gt; to Alice. Alice verifies by reconstruct &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;c_1&lt;&#x2F;span&gt; and the above recursion step. If this circles around and produces &lt;span class=&quot;math math-inline&quot;&gt;c_1&lt;&#x2F;span&gt; again then the signature is correct.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;linkable-ring-signatures&quot;&gt;Linkable Ring Signatures&lt;&#x2F;h2&gt;
&lt;p&gt;Same as ring signatures, but Alice can also determine if two messages came from the same Bob. Bob number &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; now computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
K &amp;amp;= b_s ⋅ \HP(B_s) \\
c_s &amp;amp;= \H(\vec B, m, k ⋅ \G, k ⋅ \HP(B_s)) \\
c_i &amp;amp;= \H(\vec B, m, r_i ⋅ \G + c_{i - 1} ⋅ B_i, r_i ⋅ \HP(B_i) + c_{i - 1} ⋅ K) \\
r_s &amp;amp;= k - c_{s - 1} ⋅ b_s
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bob sends &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and the signature &lt;span class=&quot;math math-inline&quot;&gt;(K, c_1, \vec r)&lt;&#x2F;span&gt; to Alice. Alice verifies by reconstruct &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt; using &lt;span class=&quot;math math-inline&quot;&gt;c_1&lt;&#x2F;span&gt; and the above recursion step. If this circles around and produces &lt;span class=&quot;math math-inline&quot;&gt;c_1&lt;&#x2F;span&gt; again then the signature is correct. Two signatures are by the same Bob iff the &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt; values are the same.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;stealth-addresses&quot;&gt;Stealth Addresses&lt;&#x2F;h2&gt;
&lt;p&gt;Alice wants to mention Bob without identifying him. Bob creates two keypairs &lt;span class=&quot;math math-inline&quot;&gt;(a, A)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(b, B)&lt;&#x2F;span&gt; and sends &lt;span class=&quot;math math-inline&quot;&gt;(A, B)&lt;&#x2F;span&gt; (&#x27;stealth address&#x27;) to Alice. To mention Bob, Alice picks a random number &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; and computes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
R &amp;amp;= r ⋅ \G &amp;amp;
P &amp;amp;= \H(r ⋅ A) ⋅ \G + B
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Alice mentions &lt;span class=&quot;math math-inline&quot;&gt;(P, R)&lt;&#x2F;span&gt;. Bob looks through all mentions and for each checks&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P = \H(a ⋅ R) ⋅ \G + B
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If this holds, then it was Bob who was mentioned and he can compute &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;P = p ⋅ \G&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p = \H(a ⋅ R) + b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bob proceeds with a signature algorithm using &lt;span class=&quot;math math-inline&quot;&gt;(p, P)&lt;&#x2F;span&gt; as the keypair to sign messages as the person mentioned without revealing his identity.&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;(a, B)&lt;&#x2F;span&gt; (&#x27;scanning key&#x27;) is sufficient to recognize mentions of Bob, but &lt;span class=&quot;math math-inline&quot;&gt;(a, b)&lt;&#x2F;span&gt; (&#x27;signing key&#x27;) is required to sign.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hierarchical-deterministic-wallets&quot;&gt;Hierarchical Deterministic Wallets&lt;&#x2F;h2&gt;
&lt;p&gt;Bob has private key &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and public key &lt;span class=&quot;math math-inline&quot;&gt;B = b ⋅ \G&lt;&#x2F;span&gt;. Bob wants to derive more key pairs. Both in a way that Alice can follow using the public key and not.&lt;&#x2F;p&gt;
&lt;p&gt;Bob creates a random &#x27;chain code&#x27; &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; and shares it with Alice. Bob&#x27;s &#x27;extended private key&#x27; is &lt;span class=&quot;math math-inline&quot;&gt;(b, c)&lt;&#x2F;span&gt; and Alice has the &#x27;extended public key&#x27; &lt;span class=&quot;math math-inline&quot;&gt;(B, c)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To create the &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;-th new key pair such that Alice can follow, compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
b&amp;#39; &amp;amp;= b + \H(c, B, i, 0) &amp;amp;
c&amp;#39; &amp;amp;= \H(c, B, i, 1)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The new extended private key is &lt;span class=&quot;math math-inline&quot;&gt;(b&amp;#39;, c&amp;#39;)&lt;&#x2F;span&gt; and Alice can derive the &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;-th new extended public key&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
B&amp;#39; &amp;amp;= B + \H(c, B, i, 0) ⋅ \G &amp;amp;
c&amp;#39; &amp;amp;= \H(c, B, i, 1)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To derive the &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;-th key pair that Alice can not follow, compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
b&amp;#39; &amp;amp;= b + \H(c, b, i, 0) &amp;amp;
c&amp;#39; &amp;amp;= \H(c, b, i, 1)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20140116100059&#x2F;https:&#x2F;&#x2F;sourceforge.net&#x2F;mailarchive&#x2F;message.php?msg_id=31813471&quot;&gt;CryptoNote&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.getmonero.org&#x2F;library&#x2F;Zero-to-Monero-2-0-0.pdf&quot;&gt;Zero to Monero v2.0.0&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;bips&#x2F;blob&#x2F;02de475efc528058bd04a0c4ad31b6422aed5f5f&#x2F;bip-0032.mediawiki&quot;&gt;BIP32&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>n-sphere</title>
        <published>2021-11-23T00:00:00+00:00</published>
        <updated>2021-11-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/21/n-sphere/"/>
        <id>https://2π.com/21/n-sphere/</id>
        
        <content type="html" xml:base="https://2π.com/21/n-sphere/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\R{\mathbb{R}}
\gdef\p#1{({#1})}
\gdef\norm#1{\lVert{#1}\rVert}
\gdef\set#1{\mathcal{#1}}
\gdef\setb#1#2{\{{#1} \mid {#2}\}}
\gdef\dummyarg{\operatorname{-}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;sphere&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-sphere&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\S{\mathrm{S}}
\gdef\darc{d_{\mathrm{arc}}}
\gdef\a#1#2{\mathrm{A}_{#1}\p{#2}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{S}_n(r)&lt;&#x2F;span&gt; be an &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-dimensional &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;N-sphere&quot;&gt;hypersphere&lt;&#x2F;a&gt;, or &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-sphere, of radius &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; centered at the origin:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\mathrm{S}_n(r) = \setb{\vec x ∈ \R^n}{\norm{\vec x}_2 = r}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The volume and surface area of are given by formulas involving the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gamma_function&quot;&gt;Gamma function&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;Γ\p{\dummyarg}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\mathrm{V}_{n}\p
{r} &amp;amp;= \frac{π^{\frac n2}}{\mathrm{Γ}\p{\frac n2 + 1}} r^n
&amp;amp;&amp;amp;&amp;amp;
\a{n}{r} &amp;amp;= \frac{2 π^{\frac n2}}{\mathrm{Γ}\p{\frac n2}} r^{n-1}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When the radius is left out it is implied to be one, so &lt;span class=&quot;math math-inline&quot;&gt;S_n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;V_n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;A_n&lt;&#x2F;span&gt; are the unit &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-sphere and its volume and surface area respectively.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;distance-metrics&quot;&gt;Distance Metrics&lt;&#x2F;h2&gt;
&lt;p&gt;There are two commonly used &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Metric_(mathematics)&quot;&gt;distance functions&lt;&#x2F;a&gt; on the unit &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-sphere, the chord distance, &lt;span class=&quot;math math-inline&quot;&gt;d_{\mathrm{chord}}&lt;&#x2F;span&gt;, and arc length &lt;span class=&quot;math math-inline&quot;&gt;d_{\mathrm{arc}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The chord length is simply the metric inherited from the surrounding &lt;span class=&quot;math math-inline&quot;&gt;\R^n&lt;&#x2F;span&gt; space&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
d_{\mathrm{chord}}(\vec a, \vec b) = \norm{\vec a - \vec b}_2
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The arc length, &lt;span class=&quot;math math-inline&quot;&gt;\darc&lt;&#x2F;span&gt;, or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Great-circle_distance&quot;&gt;great-circle distance&lt;&#x2F;a&gt;, is the length of the shortest path between two points on &lt;span class=&quot;math math-inline&quot;&gt;\S^n&lt;&#x2F;span&gt;. In one dimension &lt;span class=&quot;math math-inline&quot;&gt;\S^1 = \set{-1, 1}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\darc&lt;&#x2F;span&gt; is ill-defined because there is no connecting path on &lt;span class=&quot;math math-inline&quot;&gt;\S^1&lt;&#x2F;span&gt;. A natural extension in this case is to define &lt;span class=&quot;math math-inline&quot;&gt;\darc ∈ \set{0, \pi}&lt;&#x2F;span&gt;. We can compute &lt;span class=&quot;math math-inline&quot;&gt;\darc&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\darc\p{\vec a, \vec b}
= \cos^{-1}\p{\vec a ⋅ \vec b}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;While not technically a distance function, another popular function is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cosine_similarity&quot;&gt;&#x27;cosine distance&#x27;&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
d_{\mathrm{cos}}(\vec a, \vec b) = 1 - \vec a ⋅ \vec b
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can geometrically interpret the various distances by considering the plane spanned by &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; intersecting &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{S}_n&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;21&#x2F;n-sphere&#x2F;geodist.png&quot; alt=&quot;Geometric interpretation of distances&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The distances &lt;span class=&quot;math math-inline&quot;&gt;d_{\mathrm{arc}}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;d_{\mathrm{chord}}&lt;&#x2F;span&gt; are related by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
d_{\mathrm{chord}} &amp;amp;= 2 \sin\p{\frac{d_{\mathrm{arc}}}{2}}
&amp;amp;&amp;amp;&amp;amp;
d_{\mathrm{arc}} &amp;amp;= 2 \sin^{-1}\p{\frac{d_{\mathrm{chord}}}{2}}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;for small distances they are good approximations of each other with an error of &lt;span class=&quot;math math-inline&quot;&gt;O(d^3)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;distribution&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;\darc&lt;&#x2F;span&gt; Distribution&lt;&#x2F;h2&gt;
&lt;p&gt;Consider the uniform distribution on the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-sphere. Uniform here taken to mean the natural &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lebesgue_measure&quot;&gt;Lebesgue measure&lt;&#x2F;a&gt;. An elegant procedure to sample from this distribution is by generating &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Multivariate_normal_distribution#Standard_normal_random_vector&quot;&gt;standard normal random vectors&lt;&#x2F;a&gt; and normalizing them:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; sample_sphere&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;count&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; rng&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters&quot;&gt;random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;default_rng&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; rng&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;standard_normal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;count&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;linalg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;norm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; axis&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)[:,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;newaxis&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Draw a pair of vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; from the unit &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-sphere and consider their distance &lt;span class=&quot;math math-inline&quot;&gt;d_{\mathrm{arc}}\p{\vec a, \vec b}&lt;&#x2F;span&gt;. Let&#x27;s do this numerically by generating many distances and plotting the histogram. We do this for a number of dimensions to see how the distribution evolves:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;21&#x2F;n-sphere&#x2F;arc_length_num.png&quot; alt=&quot;Arc length distribution (numerical)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We see the exceptional bimodal behaviour in one dimension, in two dimensions the distances are uniformly distributed, and with higher dimensions the distribution converges to &lt;span class=&quot;math math-inline&quot;&gt;\frac π2&lt;&#x2F;span&gt;. The value &lt;span class=&quot;math math-inline&quot;&gt;\frac π2&lt;&#x2F;span&gt; is the distance from a pole to the equator. Intuitively as we increase the number of dimensions there will be more space orthogonal to a given vector.&lt;&#x2F;p&gt;
&lt;p&gt;My first guess was a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Beta_distribution&quot;&gt;Beta distribution&lt;&#x2F;a&gt; with parameters &lt;span class=&quot;math math-inline&quot;&gt;α = β = n - 1&lt;&#x2F;span&gt;. This matches the behaviour at dimensions &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;, and behaves similarly for higher dimensions. Unfortunately, for &lt;span class=&quot;math math-inline&quot;&gt;n=3&lt;&#x2F;span&gt; and higher it is very subtly wrong, as can be seen when we overlay it on a high resolution histogram&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;21&#x2F;n-sphere&#x2F;arc_length_beta.png&quot; alt=&quot;Arc length distribution&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So let&#x27;s find the true distribution. Given a point &lt;span class=&quot;math math-inline&quot;&gt;\vec a ∈ \S^n&lt;&#x2F;span&gt;, the set of points a distance &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; away from &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; is a &lt;span class=&quot;math math-inline&quot;&gt;n - 1&lt;&#x2F;span&gt;-sphere of radius &lt;span class=&quot;math math-inline&quot;&gt;\sin d&lt;&#x2F;span&gt;, that is &lt;span class=&quot;math math-inline&quot;&gt;\S^{n-1}\p{\sin d}&lt;&#x2F;span&gt;. The infinitesimal probability of hitting this set is (see appendix for derivation)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
f_n(d)
&amp;amp;= \frac{\a{n-1}{\sin θ}}{\a{n}{1}}
=\frac{\sin^{n-2} d}{Β\p{\frac 12, \frac n2 - \frac 12}}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;Β&lt;&#x2F;span&gt; is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Beta_function&quot;&gt;Beta function&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
Β\p{a,b} = \frac{Γ\p{a} Γ\p{b}}{Γ\p{a + b}}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For consecutive values of &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; the probability density function &lt;span class=&quot;math math-inline&quot;&gt;f_n\p{\darc}&lt;&#x2F;span&gt; looks like&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;21&#x2F;n-sphere&#x2F;arc_length.png&quot; alt=&quot;Arc length distribution&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;!--

$$
f_N\p{d_{\mathrm{chord}}} = \frac{d}{R^2 Β\p{\frac{N-1}{2}, \frac 12}} \p{\frac{d^2}{R^2} - \frac{d^4}{4R^4} }^{\frac{N-3}{2}}
$$

$$
\begin{align}
\acap{n}{r}
&amp;= \int_0^φ \a{n-1}{r \sin θ} r \d θ \\
&amp;= \frac 12  ⋅ \a{N}{R} ⋅ \mathrm{I}_{\sin^2 θ}\p{\frac{N-1}{2}, \frac 12}
\end{align}
$$

--&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;S. Li (2011).
Concise Formulas for the Area and Volume of a Hyperspherical Cap.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dx.doi.org&#x2F;10.3923&#x2F;ajms.2011.66.70&quot;&gt;https:&#x2F;&#x2F;dx.doi.org&#x2F;10.3923&#x2F;ajms.2011.66.70&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Panagiotis Sidiropoulos (2014).
N-sphere chord length distribution.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1411.5639v1&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1411.5639v1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;J.C. Baez, G. Egan, J.D. Cook, D. Piponi (2018).
Random Points on a Sphere (Part 1)
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;johncarlosbaez.wordpress.com&#x2F;2018&#x2F;07&#x2F;10&#x2F;random-points-on-a-sphere-part-1&#x2F;&quot;&gt;https:&#x2F;&#x2F;johncarlosbaez.wordpress.com&#x2F;2018&#x2F;07&#x2F;10&#x2F;random-points-on-a-sphere-part-1&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;appendix-derivation&quot;&gt;Appendix: Derivation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
f_n(d)
&amp;amp;= \frac{\a{n-1}{\sin θ}}{\a{n}{1}}
= \frac{\p{
    \frac{2 π^{\frac{n-1}{2}}}{\mathrm{Γ}\p{\frac {n-1}{2}}} \p{\sin θ}^{n-2}
}}{\p{
    \frac{2 π^{\frac n2}}{\mathrm{Γ}\p{\frac n2}} 1^{n-1}
}}
\\&amp;amp;= \frac{1}{\sqrt{π}}
\frac{\mathrm{Γ}\p{\frac n2}}{\mathrm{Γ}\p{\frac {n-1}{2}}}
\sin^{n-2} θ
=\frac{\mathrm{Γ}\p{\frac n2}}{\mathrm{Γ}\p{\frac 12}\mathrm{Γ}\p{\frac n2 - \frac 12}}
\sin^{n-2} d
\\&amp;amp;=
\frac{\sin^{n-2} d}{Β\p{\frac 12, \frac n2 - \frac 12}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;math.stackexchange.com&#x2F;questions&#x2F;1246748&#x2F;distribution-of-an-angle-between-a-random-and-fixed-unit-length-n-vectors&quot;&gt;https:&#x2F;&#x2F;math.stackexchange.com&#x2F;questions&#x2F;1246748&#x2F;distribution-of-an-angle-between-a-random-and-fixed-unit-length-n-vectors&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The MIT License (MIT)</title>
        <published>2021-02-03T00:00:00+00:00</published>
        <updated>2021-02-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/mit-license/"/>
        <id>https://2π.com/mit-license/</id>
        
        <content type="html" xml:base="https://2π.com/mit-license/">&lt;h1 id=&quot;the-mit-license-mit&quot;&gt;The MIT License (MIT)&lt;&#x2F;h1&gt;
&lt;p&gt;Copyright © 2021 Remco Bloemen&lt;&#x2F;p&gt;
&lt;p&gt;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and&#x2F;or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&lt;&#x2F;p&gt;
&lt;p&gt;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&lt;&#x2F;p&gt;
&lt;p&gt;THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Search</title>
        <published>2021-01-04T00:00:00+00:00</published>
        <updated>2021-01-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/search/"/>
        <id>https://2π.com/search/</id>
        
        <content type="html" xml:base="https://2π.com/search/">&lt;h1 id=&quot;search&quot;&gt;Search&lt;&#x2F;h1&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fluid Sim</title>
        <published>2020-12-31T00:00:00+00:00</published>
        <updated>2020-12-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/fluid-sim/"/>
        <id>https://2π.com/20/fluid-sim/</id>
        
        <content type="html" xml:base="https://2π.com/20/fluid-sim/">&lt;h1 id=&quot;fluid-sim&quot;&gt;Fluid Sim&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; Simulate performance of multi-hull ships.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;tetsuya-takahashi.github.io&#x2F;Monolith&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;Data on multihulls:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;http:&#x2F;&#x2F;www.multihulldynamics.com&#x2F;default.asp&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>About Me</title>
        <published>2020-12-31T00:00:00+00:00</published>
        <updated>2020-12-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/about/"/>
        <id>https://2π.com/about/</id>
        
        <content type="html" xml:base="https://2π.com/about/">&lt;h1 id=&quot;about-me&quot;&gt;About Me&lt;&#x2F;h1&gt;
&lt;p&gt;Remco Bloemen&lt;&#x2F;p&gt;
&lt;p&gt;Quick Bio: I graduated from Sir Stephen Hawking&#x27;s theoretical physics department at Cambridge
University, Business Administration at the University of Twente and the GSP of Singularity University
at NASA Ames. Since then I&#x27;ve co-founded a cybersecurity company, a blockchain company, and joined
0x project early.&lt;&#x2F;p&gt;
&lt;p&gt;I am driven by curiosity and a desire to build. I like to take problems, break them down to their
fundamentals and construct solutions that go beyond what has been done before.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Plonk&#x27;s Permutation check and variants</title>
        <published>2020-12-28T00:00:00+00:00</published>
        <updated>2020-12-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/22/plonk/"/>
        <id>https://2π.com/22/plonk/</id>
        
        <content type="html" xml:base="https://2π.com/22/plonk/">&lt;h1 id=&quot;plonk-s-permutation-check-and-variants&quot;&gt;Plonk&#x27;s Permutation check and variants&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\({\left (}
\gdef\){\right )}
\gdef\norm#1{\left\vert #1 \right\vert}
\gdef\set#1{\mathcal{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See the Plonk paper &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953&lt;&#x2F;a&gt;. Here follow some meditations on chapter 5 and appendix A.&lt;&#x2F;p&gt;
&lt;p&gt;Plonk uses the fact that polynomials can be uniquely represented as a vector of coefficients and as a multiset of irreducible factors to efficiently proof that one vector is a permutation of another. This is done using applications of the Schwartz-Zippel lemma.&lt;&#x2F;p&gt;
&lt;p&gt;IMHO, the two key innovations in Plonk&#x27;s permutation check are 1) a protocol for multiset equality checking and 2) a way of encoding a permutation check as a multiset equality check over pairs.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma A.2.&lt;&#x2F;strong&gt; &lt;em&gt;(Schwartz-Zippel). Let &lt;span class=&quot;math math-inline&quot;&gt;P(\vec X) ∈ \F_p[X^n]&lt;&#x2F;span&gt; be non-zero and &lt;span class=&quot;math math-inline&quot;&gt;\vec α ∈ S ⊆ \F_p^n&lt;&#x2F;span&gt; uniform random, then&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr\left[P(\vec α) = 0 \right] ≤ \frac{\deg P}{\norm S}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Corrolary.&lt;&#x2F;strong&gt; &lt;em&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P(X) ∈ \F_p[X]&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\deg P ≪ p&lt;&#x2F;span&gt; and uniform random &lt;span class=&quot;math math-inline&quot;&gt;α ∈ \F_p&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;P(α) = 0&lt;&#x2F;span&gt; with non-neglibile probability only when &lt;span class=&quot;math math-inline&quot;&gt;P = 0&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Corrolary.&lt;&#x2F;strong&gt; &lt;em&gt;(Polynomial identity). Given &lt;span class=&quot;math math-inline&quot;&gt;P(X), Q(X) ∈ \F_p[X]&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\deg P,\deg Q ≪ p&lt;&#x2F;span&gt; and uniform random &lt;span class=&quot;math math-inline&quot;&gt;α ∈ \F_p&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;P(α) = Q(α)&lt;&#x2F;span&gt; with non-neglibile probability only when &lt;span class=&quot;math math-inline&quot;&gt;P = Q&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma A.3.&lt;&#x2F;strong&gt; &lt;em&gt;(Multiset equality) Given two multisets &lt;span class=&quot;math math-inline&quot;&gt;\set A, \set B&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\norm{\set A}, \norm{\set  B} ≪ p&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;𝛾 ∈ \F&lt;&#x2F;span&gt; uniform random, then &lt;span class=&quot;math math-inline&quot;&gt;\set A = \set B&lt;&#x2F;span&gt; if the following holds with non-neglible probability:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\prod_{a ∈ \set A} \( a + γ \) =
\prod_{b ∈ \set B} \( b + γ \)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; Define &lt;span class=&quot;math math-inline&quot;&gt;P(X) ≝ \prod_{a ∈ A} (a + X)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q(X) ≝ \prod_{b ∈ B}(b + X)&lt;&#x2F;span&gt;. If the above holds with non-neglible probability then by the polynomial identity corrolary we have &lt;span class=&quot;math math-inline&quot;&gt;P = Q&lt;&#x2F;span&gt;. From the unique factorization of polynomials it follows that their irreducible factors are the same, which are given in their definition. From this follows &lt;span class=&quot;math math-inline&quot;&gt;\set A = \set B&lt;&#x2F;span&gt;. □&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; We do not require &lt;span class=&quot;math math-inline&quot;&gt;\norm{\set A} = \norm{\set B}&lt;&#x2F;span&gt; and the test will correctly fail when they are of unequal size.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Remark.&lt;&#x2F;strong&gt; Compared to lemma A.3 in the paper it is rephrased in terms of multisets and generalized to have multisets of unequal size. The protocol in chapter 5 is readily adjusted to become a multiset-equality protocol.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Rephrased permutation checking protocol as an instance of multiset-equality checking.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Is there utility in constructions where the irreducible factors are of higher degree?&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Vector equality).&lt;&#x2F;em&gt; Given two vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec a, \vec b ∈ \F_p^n&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;n ≪ p&lt;&#x2F;span&gt; and uniform random &lt;span class=&quot;math math-inline&quot;&gt;𝛽 ∈ \F_p&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;\vec a = \vec b&lt;&#x2F;span&gt; if the following holds with non-neglible probability:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i ∈ [n]} a_i ⋅ 𝛽^i =
\sum_{i ∈ [n]} b_i ⋅ 𝛽^i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; Define &lt;span class=&quot;math math-inline&quot;&gt;P(X) ≝ \sum_{i ∈ [n]} a_i ⋅ X^i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q(X) ≝ \sum_{i ∈ [n]} a_i ⋅ X^i&lt;&#x2F;span&gt;. If the above holds with non-neglible probability then by the polynomial identity corrolary we have &lt;span class=&quot;math math-inline&quot;&gt;P = Q&lt;&#x2F;span&gt;. From the uniqueness of the coefficient representation of polynomials it follows that &lt;span class=&quot;math math-inline&quot;&gt;\forall_{i \in [n]} a_i = b_i&lt;&#x2F;span&gt; and therefore &lt;span class=&quot;math math-inline&quot;&gt;\vec a = \vec b&lt;&#x2F;span&gt;. □&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Remark.&lt;&#x2F;strong&gt; If &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; have unequal size, the test can incorrectly pass if the final entries of the longer vector are zero, otherwise it should work correctly. The stated form requires them to be equal length. (&lt;em&gt;to do&lt;&#x2F;em&gt;: we could add a &lt;span class=&quot;math math-inline&quot;&gt;X^{n+1}&lt;&#x2F;span&gt; term to bind the length of the vector.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In the permutation check we use the vector equality check with &lt;span class=&quot;math math-inline&quot;&gt;n=2&lt;&#x2F;span&gt;, i.e. pairs.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; &lt;em&gt;(Efficient composability). Show that we can do a multiset check over vectors with only two random variables.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;permutation-check&quot;&gt;Permutation check&lt;&#x2F;h3&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;\vec a, \vec b ∈ \F_p^n&lt;&#x2F;span&gt; and a permutation &lt;span class=&quot;math math-inline&quot;&gt;𝜎: [n] → [n]&lt;&#x2F;span&gt;. We want to show that &lt;span class=&quot;math math-inline&quot;&gt;b_i = a_{𝜎(i)}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt; with distinct values (i.e. &lt;span class=&quot;math math-inline&quot;&gt;c_i = c_j ⇔ i = j&lt;&#x2F;span&gt;). Compose the multiset and vector equality protocols to prove the following equality:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{Bmatrix}
(a_0, c_0) \\
(a_1, c_1) \\
(a_2, c_2) \\
⋮
\end{Bmatrix} =
\begin{Bmatrix}
(b_0, c_{𝜎(0)}) \\
(b_1, c_{𝜎(1)}) \\
(b_2, c_{𝜎(2)}) \\
⋮
\end{Bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; Since the elements &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt; are unique, the pairs are unique and the multisets are just regular sets. Two sets are equal iff their elements can be brought in correspondance. Enumerate the elements as above, we are looking for correspondances between elements &lt;span class=&quot;math math-inline&quot;&gt;(a_i, c_i) ≟ (b_j, c_{𝜎(j)})&lt;&#x2F;span&gt;. The second element in the pair is equal only if &lt;span class=&quot;math math-inline&quot;&gt;i = 𝜎(j)&lt;&#x2F;span&gt;, this means a correspondence exists iff &lt;span class=&quot;math math-inline&quot;&gt;b_j = a_{𝜎(j)}&lt;&#x2F;span&gt;. □&lt;&#x2F;p&gt;
&lt;h3 id=&quot;plookup&quot;&gt;Plookup&lt;&#x2F;h3&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Claim A.1.&lt;&#x2F;strong&gt; &lt;em&gt;If the following holds with non-negligible probability over random &lt;span class=&quot;math math-inline&quot;&gt;𝛽, 𝛾 \in \mathbb F&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\prod_i \( a_i + β ⋅ i + γ \) =
\prod_i \( b_i + β ⋅ σ\(i\) + γ \)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;then &lt;span class=&quot;math math-inline&quot;&gt;∀_{i \in [n]} b_i = a_{𝜎(i)}&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Demonstrate this follows concretely from the above.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953.pdf&quot;&gt;Plonk&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;1400.pdf&quot;&gt;Redshift&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2020&#x2F;315.pdf&quot;&gt;Plookup&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;vitalik.ca&#x2F;general&#x2F;2019&#x2F;09&#x2F;22&#x2F;plonk.html&quot;&gt;https:&#x2F;&#x2F;vitalik.ca&#x2F;general&#x2F;2019&#x2F;09&#x2F;22&#x2F;plonk.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;derivative&quot;&gt;Derivative&lt;&#x2F;h3&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P(X)&lt;&#x2F;span&gt;, define&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
G(X, Y) = \frac{P(X) - P(Y)}{X - Y}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P&amp;#39;(X) = G(X, X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Square free polynomials:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gcd(P(X), P&amp;#39;(X)) = 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Scaling DeFi: Layer One</title>
        <published>2020-12-27T00:00:00+00:00</published>
        <updated>2020-12-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/scaling-defi/"/>
        <id>https://2π.com/20/scaling-defi/</id>
        
        <content type="html" xml:base="https://2π.com/20/scaling-defi/">&lt;h1 id=&quot;scaling-defi-layer-one&quot;&gt;Scaling DeFi: Layer One&lt;&#x2F;h1&gt;
&lt;p&gt;Originally published on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.0xproject.com&#x2F;scaling-defi-layer-one-7eeb24aca4f0&quot;&gt;0x Labs Blog&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;A visual tour of Ethereum&#x27;s scaling challenge.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;div style=&quot;float: right; text-align: center;&quot;&gt;
    &lt;img src=&quot;matcha-fees.png&quot;&#x2F;&gt;
    &lt;p&gt;&lt;small&gt;&lt;em&gt;
        Small trades can end up paying more than 10% in fees.
    &lt;&#x2F;em&gt;&lt;&#x2F;small&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;If you have used DeFi recently, you have experienced sticker shock from transaction fees. It is pretty normal nowadays to pay tens to hundreds of dollars in fees for an Ethereum transaction. At these prices only whales can trade profitably and you can forget about lofty goals like banking-the-unbanked or permissionless financial infrastructure for everyone. Ethereum is becoming a place for the rich.&lt;&#x2F;p&gt;
&lt;p&gt;The high fees are only a symptom of the larger &lt;em&gt;blockchain scalability problem&lt;&#x2F;em&gt;, a problem so notorious it has it&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bitcoin_scalability_problem&quot;&gt;own Wikipedia page&lt;&#x2F;a&gt;. It is the biggest limitation of current blockchains, but there are more limitations such as long finality times, susceptibility to front-running, cross-chain interoperability, etc.&lt;&#x2F;p&gt;
&lt;p&gt;We want to &lt;em&gt;create a tokenized world where all value can flow freely&lt;&#x2F;em&gt; and blockchain limitations are not helping our mission. This is why 0x Labs has a team of research engineers developing solutions to tackle those limitations. In this post we will explore what Ethereum&#x27;s limits look like and how it affects you, the DeFi user. We will also briefly cover next generation blockchains. In follow up posts we will explore a different class of solutions, &lt;em&gt;layer two&lt;&#x2F;em&gt;, and present our own strategy to serve the needs of DeFi.&lt;&#x2F;p&gt;
&lt;p&gt;To start, remember that Ethereum transactions have different sizes measured in &lt;em&gt;gas&lt;&#x2F;em&gt;. Transactions are collected in &lt;em&gt;blocks&lt;&#x2F;em&gt; which are created about every 13 seconds. Each block has room for a limited amount of transactions, known as the &lt;em&gt;gas limit&lt;&#x2F;em&gt;. Right now, each block has room for about 12 million gas worth of transactions. A plain ERC-20 token transfer takes about fifty thousand gas. This means blocks can contain at most 240 token transfers, or about 18 transactions per second. DeFi transactions often involve multiple token transfers and other bookkeeping which multiplies the cost and further limits the throughput. The gas limit and block time mean there is a constant supply of gas available for transactions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Let&#x27;s start by looking at how the gas supply and it&#x27;s usage have grown over Ethereum&#x27;s history.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gas-usage&quot;&gt;Gas Usage&lt;&#x2F;h2&gt;
&lt;p&gt;Each day about six thousand blocks are mined, creating room for a few billion gas worth of transactions. This amount has been changing and growing over time, mostly due to increases in the gas limit. Meanwhile the total gas consumed by transactions has also been growing as Ethereum get more and larger transactions.&lt;&#x2F;p&gt;
&lt;p&gt;Looking back at the entire history of Ethereum the supply (gray) and consumption (black) of gas looks like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;scaling-defi&#x2F;gas-usage.png&quot; alt=&quot;Ethereum gas usage grows over time&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;scaling-defi&#x2F;gas-seasonality.png&quot; alt=&quot;Gas usage fluctuate hourly and weekly&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;center&gt;&lt;small&gt;&lt;em&gt;
(You can tell Ethereum is enterprise grade when usage is higher on office days)
&lt;&#x2F;em&gt;&lt;&#x2F;small&gt;&lt;&#x2F;center&gt;
&lt;p&gt;Right before the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-609&quot;&gt;Byzantium&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1013&quot;&gt;Constantinople&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2387&quot;&gt;Muir Glacier&lt;&#x2F;a&gt; hardforks, there are jagged crashes in the gas supply. These are the effects of Ethereum&#x27;s &lt;em&gt;Difficulty Bomb&lt;&#x2F;em&gt;, also known as &lt;em&gt;Ice Age&lt;&#x2F;em&gt;. During an Ice Age, the block time increases exponentially causing fewer blocks to be mined in a day and thus a lower total daily gas supply. This is of course very undesirable and forces the network to adopt a hardfork to fix it. And that&#x27;s exactly what it is for: it prevents innovation stagnation by forcing hard forks which bring many improvements. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1679&quot;&gt;Istanbul&lt;&#x2F;a&gt; hardfork forgot to reset the bomb, so was quickly followed by Muir Glacier. The upcoming &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2070&quot;&gt;Berlin&lt;&#x2F;a&gt; hardfork is considering changing this mechanism (EIP &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2515&quot;&gt;2515&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Looking at the usage (in black) Ethereum has been running above 60% capacity since the ICO craze started in 2017. Since then the gas limit has increased fourfold in distinct jumps, each time followed by a commensurate increase in gas usage. For the last few months Ethereum seems stuck at 95% usage.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;To understand why Ethereum can&#x27;t go over 95% usage, we need to look at empty and ommer blocks.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;empty-and-ommer-blocks&quot;&gt;Empty and Ommer blocks&lt;&#x2F;h2&gt;
&lt;p&gt;Throughout it&#x27;s history, Ethereum never uses more than about 95% of the limit despite demand being there. Surprisingly this remaining 5% is wasted in blocks that are completely empty. These empty blocks happen regularly, about once every twenty blocks. Why would someone mine empty blocks when there are transactions that will pay for inclusion? Let&#x27;s look at the data:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;scaling-defi&#x2F;empty-blocks.png&quot; alt=&quot;Ethereum empty block rate grows over time&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The rate of empty blocks is steadily increasing over time, and currently at about 5%. All the mining pools contribute to it equally, so it&#x27;s not a malicious miner. Instead the real causes seems to be fast blocks. If the time to mine a block was less than 6 seconds, the chances of it being empty go up exponentially.&lt;&#x2F;p&gt;
&lt;p&gt;One explanation is that miners start mining the next block the moment they receive a new block header, but before they have processed the whole block. This trick, known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.bitmex.com&#x2F;empty-block-data-by-mining-pool&#x2F;&quot;&gt;SPV mining&lt;&#x2F;a&gt; in Bitcoin, helps miners get started on the next block immediately, but it can only produce empty blocks. Once the new block is fully processed, the miner can assemble a the next full block and switch to mining that one. Further evidence for this explanation is the empty block rate reduces by 25% if the same miner finds two blocks in quick succession.&lt;&#x2F;p&gt;
&lt;p&gt;The alternative to mining empty blocks is to keep mining on the previous block while you are processing the new one. This can cause multiple next blocks to be mined. If this happens Ethereum will pick a canonical block and remember the others as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;english.stackexchange.com&#x2F;a&#x2F;182426&quot;&gt;ommers&lt;&#x2F;a&gt;. Miners still get a small reward for the ommers. This happens at a steady rate:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;scaling-defi&#x2F;ommers.png&quot; alt=&quot;Ethereum ommer rate used to be a problem&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The ommer rate peaked during the 2018 usage spike, but has been decreasing to a stable rate of 5% of all blocks mined. This coincides with the increase in the empty block rate as miners likely switched strategies around this time.&lt;&#x2F;p&gt;
&lt;p&gt;It is not immediately obvious that the ommer rate hurts Ethereum scaling but it does. Since &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-100&quot;&gt;EIP-100&lt;&#x2F;a&gt; in Byzantium the difficulty adjustment maintains a constant rate of canonical &lt;em&gt;and&lt;&#x2F;em&gt; ommer blocks. So a high ommer rate means more blocks are wasted on ommers and fewer grow the chain. This shows up as an increase in block times and thus less total gas available per day. (The other major cause for increased block times being ice ages.)&lt;&#x2F;p&gt;
&lt;p&gt;Whether it&#x27;s ommers or empty blocks, these are important network health signals for Ethereum. An increase in either means that less daily total gas is available for transactions. Analysis of the ommer rate is the big part of the research backing EIPs &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2028&quot;&gt;2028&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1559&quot;&gt;1559&lt;&#x2F;a&gt; (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum-magicians.org&#x2F;t&#x2F;eip-2028-transaction-data-gas-cost-reduction&#x2F;3280&#x2F;24&quot;&gt;1&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum-magicians.org&#x2F;t&#x2F;eip-2028-transaction-data-gas-cost-reduction&#x2F;3280&#x2F;35&quot;&gt;2&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;research&#x2F;raw&#x2F;master&#x2F;papers&#x2F;pricing&#x2F;ethpricing.pdf&quot;&gt;3&lt;&#x2F;a&gt;). It is surprising though that neither mentions the empty block rate and that the research has methodological &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum-magicians.org&#x2F;t&#x2F;eip-2028-transaction-data-gas-cost-reduction&#x2F;3280&#x2F;36&quot;&gt;flaws&lt;&#x2F;a&gt;. It would be preferable to have a more rigourous analysis considering both ommer and empty rate using appropriate statistical methods like logistic regression.&lt;&#x2F;p&gt;
&lt;p&gt;There are ways to lower the ommer and empty rate. The presumed root cause is mining pools not having the latest state available due to network and processing delays. One simple but undesirable solution is to centralizing mining pools more so that latest state is in one place. Slightly more decentralized solutions like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;bloxroute&#x2F;ethereum-miner-test-results-8fbee68b7088&quot;&gt;bloxroute&lt;&#x2F;a&gt; are creating dedicated interconnects between pools. An idea inspired by &#x27;spy mining&#x27; would be for pools to pre-share the block that they are currently trying to mine. Other pools would prepare next blocks for each eventuality and once a pool successfully mines its block, they already know which block they want to mine on next and can switch in an instant. Going higher up the stack, improvements in node communication protocols and processing algorithms would help too, there is likely still some room for gains here. But in the end, lowering the ommer and empty rate by itself will improve the daily gas supply by at most about the 5% we saw.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;So it seems there is a 95% gas limit, but what happens if people want to use more that the 95%?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gas-prices&quot;&gt;Gas Prices&lt;&#x2F;h2&gt;
&lt;p&gt;What happens when Ethereum gets close to the gas limit? Miners are free to select transactions as they desire (more about that later), but in practice they process them in order of highest-gasprice-first as this (approximately) maximizes their profit. The net effect is a first price auction on the available gas.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;scaling-defi&#x2F;gas-price.png&quot; alt=&quot;Gas price goes up sharply as we get close to 95%&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;center&gt;&lt;small&gt;&lt;em&gt;
(&lt;a href=&quot;https:&#x2F;&#x2F;www.redbubble.com&#x2F;shop&#x2F;ap&#x2F;51175945&quot;&gt;Prints available&lt;&#x2F;a&gt;)
&lt;&#x2F;em&gt;&lt;&#x2F;small&gt;&lt;&#x2F;center&gt;
&lt;p&gt;The gas price has become a textbook example of &lt;em&gt;perfectly inelastic supply&lt;&#x2F;em&gt;. It starts to noticeably increase as the network goes beyond 80% utilization and takes over vertically at the 95% mark. Any potential further growth in demand will only increase the prices until demand is discouraged back to the same level. The only way for prices to go down is to raise the gas supply or decrease the demand and the recent increase in gas limit was not enough to meaningfully lower gas prices.&lt;&#x2F;p&gt;
&lt;p&gt;At first glance, any further interest in Ethereum will just raise the prices and not lead to more usage. In reality the lower value usage will be crowed out by higher value usage, there will be fewer trades of cheap game NFTs and more large DeFi trades.&lt;&#x2F;p&gt;
&lt;p&gt;Proposal EIP &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1559&quot;&gt;1559&lt;&#x2F;a&gt; aims to make the gas supply more elastic on short timescales. During periods of high demand larger blocks can be created (up to 20 million gas). This should help smooth out the peaks in gas price and let transactions be included sooner. What it won&#x27;t do however is change the long term supply inelasticity. Under EIP-1559 there will still be a long term fixed rate of gas, meaning the price will go up until demand is small enough. Under EIP-1559 there is still an incentive to pay a premium for being processed first within a block (assuming pools continue to author blocks in that order). This means front-running, gas-bidding-wars and miner extraction of value will continue to be a thing.&lt;&#x2F;p&gt;
&lt;p&gt;The numbers in the graph represent the minimal price to be included in the next block. If you are willing to wait longer the gas prices can be much lower. Historical data suggest a decent drop-off if you are willing to wait two minutes or longer. EIP-1559 should help to reduce the premium for faster processing.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;So gas prices go up when we hit the gas limit, how do we raise this limit?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gas-limit&quot;&gt;Gas Limit&lt;&#x2F;h2&gt;
&lt;p&gt;The mining pools decide the gas limit. Let&#x27;s quickly recap how miners and pools work: Nearly all miners pool their resources. Instead of all trying to find the next block and risk going for long times without any payout, they pool their resources and get a steady income stream. This is facilitated by &lt;em&gt;mining pools&lt;&#x2F;em&gt; that verify each miners contributions and author the next block to work on. The larger pools end up authoring a large fraction of all the blocks. Let&#x27;s look at how these shares developed in Ethereum&#x27;s history:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;scaling-defi&#x2F;miningpools.png&quot; alt=&quot;Mining pools&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Nowadays, Sparkpool, Ethermine and F2Pool together authored the majority of the blocks.&lt;&#x2F;p&gt;
&lt;p&gt;Besides participating in hard forks, pool operators have one important governance responsibility: they set Ethereum&#x27;s gas limit. Unlike block time and gasprice (which are emergent properties) the gas limit is actively decided on for each block. The new gas limit is constraint to be within 0.1% from the previous blocks, so each block can only make a small nudge up or down (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethereum.github.io&#x2F;yellowpaper&#x2F;paper.pdf&quot;&gt;yellow paper&lt;&#x2F;a&gt; eq. 47). If they all agree the nudges quickly compound so that in 2.5 hours the gas limit can double or halve. If there is no agreement the gas limit becomes the median weighted by pool size.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Currently , due to a lack of clear information about how miners will behave in reality, we are going with a fairly simple approach: a voting system. […] The hope is that in the future we will be able to soft-fork this into a more precise algorithm.&lt;&#x2F;p&gt;
&lt;p&gt;— &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eth.wiki&#x2F;en&#x2F;fundamentals&#x2F;design-rationale#gas-and-fees&quot;&gt;Ethereum Design rationale&lt;&#x2F;a&gt; (first added &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;Design-Rationale&#x2F;82606c7ab81f6dbe346bf438b057859f62676a98&quot;&gt;2015-03&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The way miners set the gas limit is a stop-gap solution from the early days of Ethereum. As with many stop-gap solutions that are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Worse_is_better&quot;&gt;good enough&lt;&#x2F;a&gt;, the stop-gap became semi-permanent. EIP &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1559&quot;&gt;1559&lt;&#x2F;a&gt; proposes a different mechanism and is currently discussed for the Berlin hardfork. Until then, the pool operator can govern the gas supply much like OPEC governs oil production:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The #Ethereum miners are voting to increase the Block Gas Limit from 10,000,000 to 12,500,000.&lt;&#x2F;p&gt;
&lt;p&gt;— &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;etherchain_org&#x2F;status&#x2F;1273912037274537984&quot;&gt;@etherchain_org&lt;&#x2F;a&gt; (Ethermine pool operator)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Recently the two largest mining pools made the somewhat controversial decision to raise the daily gas production by 25%. The goal is to provide much needed relieve from the high transaction fees by increasing the gas supply. From what we seen so far the demand for transactions grows faster than the gas limit can be increased, which means prices might get a temporary relief, but will eventually go up again.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;TL;DR: The #Ethereum miners don&#x27;t give a fuck about the long term health of the network nor about DoS attacks.&lt;&#x2F;p&gt;
&lt;p&gt;— &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;peter_szilagyi&#x2F;status&#x2F;1273921434700730369&quot;&gt;Péter Szilágyi&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Raising the gas limit comes with a big hidden cost on Ethereum&#x27;s security. As we have seen, the gas limit can increase the ommer and empty block rate. This increase is small under normal transaction load. But for security we are not interested in normal behavior, only in worst-case adversarial behavior. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1909.07220&quot;&gt;Perez &amp;amp; Livshits (2019)&lt;&#x2F;a&gt; study this worse case and generated transactions that are 100 times slower to process than normal ones for the same gas cost. If you fill a block with such transactions it would take a node 90 second to process it, causing nodes to fall behind and pools to miner ommers and empty blocks. Since publication there have been some mitigations, but it is far from solved. This caused two leading node developers &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;peter_szilagyi&#x2F;status&#x2F;1273921434700730369&quot;&gt;Péter Szilágyi&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;realLedgerwatch&#x2F;status&#x2F;1273949773062701056&quot;&gt;Alexey Akhunov&lt;&#x2F;a&gt; to criticize the decision to raise the gas limit.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;So gas prices go up when we hit the gas limit, and it looks like we shouldn&#x27;t increase the gas limit much further. What else can we do? Can we maybe lower the gas cost of transactions?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gas-cost&quot;&gt;Gas Cost&lt;&#x2F;h2&gt;
&lt;p&gt;The gas cost of a transaction is made up mostly by the cost EVM operations. Transactions are made up of many EVM operations and the cost of each operation is governed through EIPs and hard forks. In past hardforks, the gas cost of certain operations have been increased
(EIPs
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-150&quot;&gt;150&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-160&quot;&gt;160&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1884&quot;&gt;1884&lt;&#x2F;a&gt;)
or decreased
(EIPs
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1108&quot;&gt;1108&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2028&quot;&gt;2028&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2200&quot;&gt;2200&lt;&#x2F;a&gt;).
The planned &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2070&quot;&gt;Berlin hardfork&lt;&#x2F;a&gt; also considers a number of gas specific changes
(EIPs
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1380&quot;&gt;1380&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-1559&quot;&gt;1559&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2046&quot;&gt;2046&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2565&quot;&gt;2565&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eips.ethereum.org&#x2F;EIPS&#x2F;eip-2537&quot;&gt;2537&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The goal of all these changes is to make the fees more accurately reflect the true cost of the operations. This means the cost of computing operations will go down as computers and algorithms become faster. The cost of storage operations is a different story. The cost of storage and lookups depends and the size of the chain state, and the size of Ethereum&#x27;s state &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;etherscan.io&#x2F;chartsync&#x2F;chaindefault&quot;&gt;keeps growing&lt;&#x2F;a&gt;. This growth is not offset by improvements in storage devices or databases.&lt;&#x2F;p&gt;
&lt;p&gt;This means storage will continue to be a big cost in DeFi. Creating a new balance costs 20 thousand gas and modifying an existing one 5 thousand. A transfer modifies at least two balances, an exchange at least four and more complex DeFi transactions can involve many more costly pieces of state. There seems to be no easy way to reduce the amount of storage involved and the cost of it is looking to go up if anything. On the bright side layer two scaling solution, which tend to be storage light and compute heavy, will look more favorable.&lt;&#x2F;p&gt;
&lt;p&gt;Finally the same security concerns apply as with raising the gas limit: it&#x27;s the worst case that matters. Naively optimizing the gas cost for the current true average cost of operations is very dangerous.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;By now it is clear why scaling Ethereum is such a thorny problem. Before we talk about proposed solutions, we want to digress into one more limitation of current Ethereum that hurts DeFi users.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;miner-extractable-value&quot;&gt;Miner extractable value&lt;&#x2F;h2&gt;
&lt;p&gt;Block authors are bound by the consensus rules which provide some important freedoms such as transaction selection and ordering. For regular token transfers this does not matter much, but for DeFi transactions like exchange trades there is a significant economic value in front-running trades. More complicated exploits can be considered where a target transaction is sandwiched between two attacking ones. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1904.05234&quot;&gt;Daian et al. (2019)&lt;&#x2F;a&gt; call this &lt;em&gt;miner extractable value&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It does not appear that pools are maliciously using their transaction-ordering freedom, but they still benefit from it as if they did. Pools likely use Geth which orders transaction by gas price (see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;blob&#x2F;v1.9.19&#x2F;miner&#x2F;worker.go#L961&quot;&gt;1&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;blob&#x2F;v1.9.19&#x2F;core&#x2F;types&#x2F;transaction.go#L346&quot;&gt;2&lt;&#x2F;a&gt;). This creates a gas-price auction, the highest paying transaction goes in first. This has the unfortunate effect that anyone can &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;frontrun.me&#x2F;&quot;&gt;front-run&lt;&#x2F;a&gt; a trade by bidding higher. Competitive traders keep bidding the gas price up until the trade profit is entirely consumed by the gas fee. At this point all the exploitable value ends up as transactions fees in the miners pockets.&lt;&#x2F;p&gt;
&lt;p&gt;In other situations there is value in being right after another transaction, for example to be the first to liquidate a position after a price oracle update. This is called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum&#x2F;issues&#x2F;21350&quot;&gt;back-running&lt;&#x2F;a&gt; and also ends up profiting the miners.&lt;&#x2F;p&gt;
&lt;p&gt;The miner extractable value is ultimately extracted from regular DeFi users through bigger spreads, worse prices, higher fees and more failed transactions. For a great DeFi experience this should be addressed. The way to solve it is by restricting the transaction ordering freedom, for example by requiring transactions in a block to be ordered lowest-gas-price first.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Ok, so now we have a good overview of Ethereum&#x27;s limitations and how they affect DeFi. Surely all the rock-star teams working on scaling are going to solve it, right?&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;layer-one-version-two&quot;&gt;Layer One, Version Two&lt;&#x2F;h2&gt;
&lt;p&gt;There are many very impressive teams working on different solutions to the scaling problem. The solutions come in two flavors, &lt;em&gt;layer one&lt;&#x2F;em&gt; and &lt;em&gt;layer two&lt;&#x2F;em&gt;. Layer one solutions aim to build a more scalable alternative to Ethereum, layer two solutions build more scalable infrastructure on top of Ethereum. Let&#x27;s start with layer one and leave layer two for the next post.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s start with the obvious: improving the performance of existing Ethereum. This is essential what the &lt;em&gt;Eth1x&lt;&#x2F;em&gt; effort is doing. By improving the performance of Ethereum clients there is still a lot that can be done. Unfortunately Eth1x doesn&#x27;t get nearly the support it deserves, so progress is slow. To get an idea of the performance that can be achieved this way we only have to look at &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;solana.com&#x2F;&quot;&gt;Solana&lt;&#x2F;a&gt;, which achieves over a thousand times the throughput of Ethereum with room to grow. The main downside of this approach is that it requires sophisticated hardware to run a full node.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the other solutions have three things in common: the use of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;webassembly.org&#x2F;&quot;&gt;WebAssembly&lt;&#x2F;a&gt; as the virtual machine, architectures with minimal state, and most importantly, &lt;em&gt;sharding&lt;&#x2F;em&gt;. Current Ethereum executes all transactions in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jepsen.io&#x2F;consistency&#x2F;models&#x2F;serializable&quot;&gt;sequence&lt;&#x2F;a&gt;. In fact, putting transactions in a sequence is arguably the whole point of a blockchain. The downside of this model is that it is hard to do in parallel, so we can not solve scaling easily by throwing more resources at it. This is where &lt;em&gt;next generation&lt;&#x2F;em&gt; blockchains like Eth2.0 come in. By changing the way transactions are executed so they can be handled in parallel. This is done by splitting the blockchain in multiple loosely connected domains, a process called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Shard_(database_architecture)&quot;&gt;sharding&lt;&#x2F;a&gt;. Within a shard things can still happen sequentially but between shard they occur &lt;em&gt;asynchronously&lt;&#x2F;em&gt;. This allows all shard to run in parallel, scaling the network by roughly the number of shards. The domains we use for splitting also don&#x27;t have to correspond with shards, we can have multiple domains assigned to the same shard, or even move them around to get load balancing. See Near protocol&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;near.org&#x2F;papers&#x2F;nightshade&quot;&gt;Nighshade paper&lt;&#x2F;a&gt; for a more in-depth overview of sharding.&lt;&#x2F;p&gt;
&lt;p&gt;Exactly where and how the chain is split in domains depends on the particular next generation chain. They can be thought of on a spectrum from fine-grained (many tiny domains) to coarse grained (few large domains).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fine parallelization  &amp;lt;---------------------------------&amp;gt; coarse parallelization&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      DFinity                         Eth 2.0                        Polkadot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      actors                      (TBD. Contracts?)                   chains&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Two projects conveniently span the spectrum of granularity. DFinity is on the fine-grained end, where each &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sdk.dfinity.org&#x2F;docs&#x2F;language-guide&#x2F;actors-async.html&quot;&gt;actor&lt;&#x2F;a&gt; is its own little domain and every actor interaction is asynchronous. A bit less fine-grained is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;docs.near.org&#x2F;docs&#x2F;tutorials&#x2F;how-to-write-contracts-that-talk-to-each-other&quot;&gt;Near protocol&lt;&#x2F;a&gt; where each contract is its own domain. On the coarse-grained end is PolkaDot, where the domain is an entire shard, in this context more accurately called a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.polkadot.network&#x2F;docs&#x2F;en&#x2F;learn-parachains&quot;&gt;parachain&lt;&#x2F;a&gt;. It&#x27;s to early to tell where &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;UzysWse1Th240HELswKqVA&quot;&gt;Ethereum 2.0&lt;&#x2F;a&gt; will land from a Dapp developer perspective. The Eth1EE (the post-Eth2 future of Eth1) will be coarse and have the boundaries coincident with shards with current Ethereum becoming a single shard. A dedicated Eth2EE may go for a more fine-grained solution. The advantage of fine grained solutions is that they are transparent, they can make all inter-contract calls look the same, wether they cross shard boundaries or not. This in turn allows easy load balancing by moving contracts between shards.&lt;&#x2F;p&gt;
&lt;p&gt;The downside is that domain-crossing transactions are no longer atomic, instead they become &lt;em&gt;concurrent&lt;&#x2F;em&gt; and partially &lt;em&gt;irreversible&lt;&#x2F;em&gt;. In DFinity and Near this shows up as inter-contract calls being &lt;code&gt;async&lt;&#x2F;code&gt; and returning a promise that you need to &lt;code&gt;await&lt;&#x2F;code&gt;. During an &lt;code&gt;await&lt;&#x2F;code&gt;, all that has happened so far will get committed to the chain. And then other peoples transactions can get piled on top of it. At this point you can not revert what has happened so far. When the &lt;code&gt;await&lt;&#x2F;code&gt; finally resolves it can return return success or failure from the contract call. There are various proposals to avoid this and get some form of atomicity back across shards, but they have their own downsides. Embracing the non-atomicity looks like the natural outcome.&lt;&#x2F;p&gt;
&lt;p&gt;For DeFi an asynchronous &lt;code&gt;transferFrom&lt;&#x2F;code&gt; call poses quite a challenge. Imagine a simple exchange between two parties, Alice and Bob want to exchange Eth for Dai. The basic contract would look like&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; eth&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;alice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; bob&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dai&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;bob&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; alice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 300&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;but now we need to handle the errors. If the first transaction fails, we can simp ly stop the transactions. But if the second transaction fails, we need to give Alice back the 1 Eth. The problem is, Bob may have already spend it by the time we get there. One way to solve this is using an escrow&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; eth&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;alice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; escrow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; failed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Transaction failed: Alice can not pay&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dai&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;bob&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; alice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 300&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; failed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    result&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; await&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; eth&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;escrow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; alice&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # This can never fail.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Transaction failed: Bob can not pay&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;await&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; eth&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;transferFrom&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;escrow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; bob&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # This can never fail.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Good, no-one is losing tokens anymore. But now Bob has a free exclusive option on Alice&#x27;s offer. While Alice&#x27;s tokens are being held in escrow they are not available for other trades and it is not yet guaranteed that the transaction with Bob will succeed. You could solve this by penalizing bad behavior, but its hard to determine appropriate penalties as DeFi transactions can be very valuable. You could also solve it by requiring all market participants to have their funds in escrowed from the beginning in a single deposit contract, but this centralizes state again and essentially undoes the sharding.&lt;&#x2F;p&gt;
&lt;p&gt;The other thing to note is how tricky these concurrency issues can be. In a real exchange there is also the fill-state of the order that needs to be updated, which further complicates the protocol. The reentrancy bugs that have plagued Ethereum 1.0 are just butterflies compared to the bed bug infestation that is concurrency bugs. Concurrency bugs are non-deterministic and never seem to happen during testing. As we saw in the simple exchange, they require rethinking the architecture from the ground up because like bed bugs, the only reliable way to get rid of them is to tear everything down and rebuild it from the ground up.&lt;&#x2F;p&gt;
&lt;p&gt;Exchange is a foundation that the rest of DeFi builds on, and it is a notoriously serial process. We&#x27;ve seen how orderbook based exchanges pose a challenge. Automated market maker exchanges are simpler because they already have reserve funds in escrow, but in there the reserve balances themselves form the bottleneck preventing parallelization. Even in the fastest traditional exchanges the settlements are ultimately serialized on a single matching engine without concurrency (though hopefully with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Redundancy_(engineering)&quot;&gt;redundancy&lt;&#x2F;a&gt;, for an deep dive on how traditional exchange works, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=b1e4t2k2KJY&quot;&gt;Brian Nigito&#x27;s talk&lt;&#x2F;a&gt; is excellent.&lt;&#x2F;p&gt;
&lt;p&gt;That doesn&#x27;t mean these problems are impossible to solve. The simplest solution would be for all these protocols to deploy independent instances on each shards and have arbitrageurs keep them in sync. Or maybe we can get a a single synchronous shard to be performant enough to contain all of DeFi and we can stop worrying about concurrency.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;In this post, we went through into the details of Ethereum&#x27;s limitations when it comes to scaling DeFi. As we have seen, it&#x27;s a complex problem that has no easy solution. In the following posts, we will go through a specific class of solutions (L2) and present 0x&#x27;s own strategy.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1909.07220&quot;&gt;Daniel Perez &amp;amp; Benjamin Livshits (2019). &quot;Broken Metre: Attacking Resource Metering in EVM.&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1904.05234&quot;&gt;Daian et al. (2019). &quot;Flash Boys 2.0: Frontrunning, Transaction Reordering, and Consensus Instability in Decentralized Exchanges.&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=b1e4t2k2KJY&quot;&gt;Brian Nigito (2017). &quot;How to Build an Exchange.&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.ethereum.org&#x2F;2020&#x2F;06&#x2F;02&#x2F;the-state-of-eth2-june-2020&#x2F;&quot;&gt;Danny Ryan (2020). &quot;The State of Eth2, June 2020.&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;UzysWse1Th240HELswKqVA?view&quot;&gt;Scott Shapiro &amp;amp; William Villanueva (2020). “ETH 2 Phase 2 WIKI.”&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;near.org&#x2F;papers&#x2F;nightshade&#x2F;&quot;&gt;Near Protocol sharding design&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Scaling DeFi — Layer Two</title>
        <published>2020-12-27T00:00:00+00:00</published>
        <updated>2020-12-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/scaling-defi/02-scaling/"/>
        <id>https://2π.com/20/scaling-defi/02-scaling/</id>
        
        <content type="html" xml:base="https://2π.com/20/scaling-defi/02-scaling/">&lt;h1 id=&quot;scaling-defi-layer-two&quot;&gt;Scaling DeFi — Layer Two&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;key-takeaways&quot;&gt;Key takeaways&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;There are solutions with different security &#x2F; centralization &#x2F; devex &#x2F; performance trade-offs.&lt;&#x2F;li&gt;
&lt;li&gt;Appropriate trade-off depend on application requirements.&lt;&#x2F;li&gt;
&lt;li&gt;All solutions follow the same overall design.&lt;&#x2F;li&gt;
&lt;li&gt;This design inherently creates walled gardens, with limited functionality.&lt;&#x2F;li&gt;
&lt;li&gt;For DeFi we need highest security -- tremendous value at risk.&lt;&#x2F;li&gt;
&lt;li&gt;Often forgotten: transaction ordering and censorship are high value targets in DeFi.
&lt;ul&gt;
&lt;li&gt;Even in Ethereum, the transaction ordering is imperfect and the residual transaction ordering has real economic value, as evident by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;mev-auction-auctioning-transaction-ordering-rights-as-a-solution-to-miner-extractable-value&#x2F;6788&quot;&gt;Miner extractable Value&lt;&#x2F;a&gt;. In our security model we consider this an attack.&lt;&#x2F;li&gt;
&lt;li&gt;equivalent in classical exchanges, see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Flash_Boys&quot;&gt;flash boys&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;This value comes out of the traders pocket and is a major driver in the higher spreads.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Key insight: Different guarantees have different security requirements.&lt;&#x2F;li&gt;
&lt;li&gt;Key insight: Can use different solutions for different parts of the system.
&lt;ul&gt;
&lt;li&gt;Prioritize security for high value guarantees (i.e. ZKP for custody).&lt;&#x2F;li&gt;
&lt;li&gt;Prioritize devex&#x2F;performance where value is less (i.e. staked side-chains)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Minor takeaways.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Rollups don&#x27;t solve the problem.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Rollups still scale linearly with the gas cost.&lt;&#x2F;li&gt;
&lt;li&gt;Ethereum calldata not meant for data availability.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Optimistic proofs are difficult to make secure.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Watchtowers liveness (See MakerDAO auction)&lt;&#x2F;li&gt;
&lt;li&gt;Missing cases (See IDEX 50+ cases)&lt;&#x2F;li&gt;
&lt;li&gt;Ethereum availability (In times of crisis, gas cost may be prohibitive for fraud process)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;DeFi&#x2F;DEX usecase requires account based approach (not utxo)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Privacy hard (impossible?) on account based.&lt;&#x2F;li&gt;
&lt;li&gt;DeFI hard (impossible?) on utxo.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;All scaling solutions have &#x27;mass exit&#x27; problem in one form or the other.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In a mass exit, all state needs to be pushed to Ethereum L1.&lt;&#x2F;li&gt;
&lt;li&gt;Economic value of migrating state may not offset the cost of storing it on L1.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Data availability vs. Proof of Publication.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Data availability requires Storage in Ethereum.&lt;&#x2F;li&gt;
&lt;li&gt;Calldata only provides proof-of-publication.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;how-do-we-get-more-milage&quot;&gt;How do we get more milage?&lt;&#x2F;h3&gt;
&lt;p&gt;The basic formula is as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Only store fingerprint of L2 balances on Ethereum
&lt;ul&gt;
&lt;li&gt;Use Merkle tree hashes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Where are the balances stored?&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Process transactions somewhere
&lt;ul&gt;
&lt;li&gt;Process in batches and periodically send the new fingerprint&lt;&#x2F;li&gt;
&lt;li&gt;Batch size &#x2F; delay tradeoff&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;How do we know this is done correctly?&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Problem: Deposits&#x2F;withdrawals
&lt;ul&gt;
&lt;li&gt;Atomic interaction between Ethereum state and L2 state&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Synchronization delays&lt;&#x2F;strong&gt; (up to weeks, depending on solution)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Data availability problem&lt;&#x2F;strong&gt; requires balance to be known.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All L2 solutions currently follow this pattern. The pattern has one major downside:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;All L2 solutions are walled gardens with limited functionality.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;where-are-the-balances-stored&quot;&gt;Where are the balances stored?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Data is stored on-chain (Rollup):
&lt;ul&gt;
&lt;li&gt;State, state-delta, or equivalent information published to Ethereum.&lt;&#x2F;li&gt;
&lt;li&gt;Typically stored in cheap calldata instead of storage!&lt;&#x2F;li&gt;
&lt;li&gt;Example: zkSync, Loopring?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Data is on a side-chain:
&lt;ul&gt;
&lt;li&gt;State stored in a decentralized p2p consensus network.&lt;&#x2F;li&gt;
&lt;li&gt;Example: xDAI, 0xChain&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Data stored off-chain:
&lt;ul&gt;
&lt;li&gt;State stored on servers.&lt;&#x2F;li&gt;
&lt;li&gt;Example: StarkEx&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The on-chain approach is the most secure, but it can only lead to linear scaling. It also makes undue assumptions on the availability of calldata. (In Ethereum, storage has data-availability guarantees, but calldata is only around as a curtesy by nodes. As Ethereum grows, it will make less sense to store all historical transaction data.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;on-data-availability&quot;&gt;On Data Availability&lt;&#x2F;h4&gt;
&lt;p&gt;There is a much discussed problem common to all scaling solutions that only shows up during catastrophic times.&lt;&#x2F;p&gt;
&lt;p&gt;In order to claim your funds in a catastrophic unwinding, you need to proof the funds that you held. For this you need some evidence that links it back to the latest state root. The evidence changes with each state root, so it is critically important that you always have access to the latest evidence. This is known as the &lt;em&gt;data availability problem&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;One approach to solving this is called &lt;em&gt;rollups&lt;&#x2F;em&gt;. Here information required to construct a proof of funds is submitted together with the batch to Ethereum. The&lt;&#x2F;p&gt;
&lt;p&gt;It is important to note that Ethereum itself does not guarantee data-availability on &lt;code&gt;calldata&lt;&#x2F;code&gt;. The Ethereum protocol requires miners to share all transaction data in the latest blocks, but not necessarily that of historical ones. Storing the&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately for the network, &lt;em&gt;full nodes&lt;&#x2F;em&gt; provide this information altruistically as a service. There are also centralized services like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;etherscan.io&#x2F;txs&quot;&gt;etherscan&lt;&#x2F;a&gt; that offer this free of charge. This currently requires &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;etherscan.io&#x2F;chart2&#x2F;chaindatasizefast&quot;&gt;130 GB&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;While there are proposals to limit&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-do-we-know-if-transactions-are-processed-correctly&quot;&gt;How do we know if transactions are processed correctly?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;On-chain
&lt;ul&gt;
&lt;li&gt;Batch verify&lt;&#x2F;li&gt;
&lt;li&gt;Potentially use aggregate signatures (SKALE)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Side-chains
&lt;ul&gt;
&lt;li&gt;Example: Loom, PoA, xDAI, Parts of 0xChain&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Security only as good as the consensus&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Proof protocols
&lt;ul&gt;
&lt;li&gt;Fraud proofs (AKA Optimistic)
&lt;ul&gt;
&lt;li&gt;State-channels
&lt;ul&gt;
&lt;li&gt;Example: Lightning, Raiden&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Plasma
&lt;ul&gt;
&lt;li&gt;Example: Matic, OMG, OVM, Truebit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Succinct proofs (AKA Zero-Knowledge Proofs *)
&lt;ul&gt;
&lt;li&gt;Example: Loopring, Parts of 0xChain.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;* The academic definition of a zero-knowledge has some additional requirements that are stronger than required for succinct proofs. For scaling purposes often simplifications are made that make the proof system no longer zero-knowledge.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-problem-with-optimistic-proofs&quot;&gt;The problem with optimistic proofs&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s like you DIY your own Airbag in your car. You won&#x27;t know you forgot something until it is too late.&lt;&#x2F;p&gt;
&lt;p&gt;IDEX example. &quot;no fewer than 50 fraud proofs.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Can not depend on watchtowers being vigilant: See MakerDAO auction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;security-is-multifaceted&quot;&gt;Security is multifaceted&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Different kinds of security guarantees with different value.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-hybrid-approach&quot;&gt;The hybrid approach&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;ethtrader&#x2F;comments&#x2F;hfi1hs&#x2F;ethereum_l2_scaling_techniques&#x2F;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Scaling DeFi: Our Approach</title>
        <published>2020-12-27T00:00:00+00:00</published>
        <updated>2020-12-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/scaling-defi/03-scaling/"/>
        <id>https://2π.com/20/scaling-defi/03-scaling/</id>
        
        <content type="html" xml:base="https://2π.com/20/scaling-defi/03-scaling/">&lt;h1 id=&quot;scaling-defi-our-approach&quot;&gt;Scaling DeFi: Our Approach&lt;&#x2F;h1&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Securing DeFi</title>
        <published>2020-12-27T00:00:00+00:00</published>
        <updated>2020-12-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/scaling-defi/04-security/"/>
        <id>https://2π.com/20/scaling-defi/04-security/</id>
        
        <content type="html" xml:base="https://2π.com/20/scaling-defi/04-security/">&lt;h1 id=&quot;securing-defi&quot;&gt;Securing DeFi&lt;&#x2F;h1&gt;
&lt;p&gt;Back when blockchains where only used to store and transfer funds, security analysis was simple. There where a handful of concerns to worry about like &#x27;theft of funds&#x27;, &#x27;double spends&#x27;, &#x27;freezing funds&#x27;, etc. In Ethereum and especially DeFi the amount of potential attacks grows exponentially and it&#x27;s hard to enumerate them. Some examples are (MakerDAO auction failure, AMM price oracle manipulation, etc.)&lt;&#x2F;p&gt;
&lt;p&gt;We need to rethink security not as a matter of a set of attacks that we prevent.&lt;&#x2F;p&gt;
&lt;p&gt;Rather we need to think of security in terms of guarantees the system provides (like &#x27;your funds won&#x27;t move without your signature&#x27;). These guarantees are a formal contract that the system provides to its users.&lt;&#x2F;p&gt;
&lt;p&gt;For each guarantee we need to know two things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;What is the maximum economic gain an attacker could create if it where to break the guarantee.&lt;&#x2F;li&gt;
&lt;li&gt;What is the minimum economic cost to break the guarantee.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In a secure system we want the former to be much less than the latter, i.e.:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\forall_{\text{attack}}\ \text{value of attack} \ll \text{cost of attack}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since we often don&#x27;t know all the attacks, it&#x27;s prudent to instead work with:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\max_{\text{attack}} (\text{value of attack}) \ll \min_{\text{attack}} (\text{cost of attack})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where the maximum is taken over the entire attack surface.&lt;&#x2F;p&gt;
&lt;p&gt;And this naturally leads to a metric for the security:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\text{Security margin} = \frac{
    \min (\text{cost of attack})
}{
    \max (\text{value of attack})
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Stealing funds. The value of the funds. But add externalities like reputation damage to the system.&lt;&#x2F;li&gt;
&lt;li&gt;Value of locking funds. This is very similar to the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ultimatum_game&quot;&gt;ultimatum game&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Concerns like ordering and censorship have serious economic value in DeFi.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ordering&quot;&gt;Ordering&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2005.11791&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Realtime stepper motor control</title>
        <published>2020-12-27T00:00:00+00:00</published>
        <updated>2020-12-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/stepper-motor-control/"/>
        <id>https://2π.com/20/stepper-motor-control/</id>
        
        <summary type="html">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\d{\operatorname{d}\!}
\gdef\abs#1{\lvert{#1}\rvert}
\gdef\floor#1{\lfloor{#1}\rfloor}
\gdef\sign{\operatorname{sign}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;realtime-stepper-motor-control&quot;&gt;Realtime stepper motor control&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Abstract.&lt;&#x2F;strong&gt; Ideal stepper motor control requires generating step and direction signals for jerk-limited trajectories. For embedded realtime systems an efficient method is required to generate such signals.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Rational functions</title>
        <published>2020-12-26T00:00:00+00:00</published>
        <updated>2020-12-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/18/rational-functions/"/>
        <id>https://2π.com/18/rational-functions/</id>
        
        <content type="html" xml:base="https://2π.com/18/rational-functions/">&lt;h1 id=&quot;rational-functions&quot;&gt;Rational functions&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;em&gt;hpq&lt;&#x2F;em&gt;-FEM: approximate functions using a mesh (&lt;em&gt;h&lt;&#x2F;em&gt;) of rational functions of numerator degree &lt;em&gt;p&lt;&#x2F;em&gt; and denominator degree &lt;em&gt;q&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x) = \frac{a_0 + a_1 x + a_2 x^2 \cdots a_p x^p}{1 + b_1 x + b_2 x^2 \cdots b_q x^q}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The main goal is to reduce the number of degrees-of-freedom in the problem while still approximating the solution within the error tolerance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;evaluating-polynomials&quot;&gt;Evaluating Polynomials&lt;&#x2F;h2&gt;
&lt;p&gt;Two methods are optimal.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;langrange&quot;&gt;Langrange&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x) = \left(\prod_i (x - x_i)\right)
 \sum_i \frac{w_j }{(x - x_i)} f(x_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w_j = \frac{1}{\prod_{1\neq j} x_j - x_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;barycentric&quot;&gt;Barycentric&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p(x) = \frac
{\sum_i \frac{w_j }{x - x_i} f(x_i)}
{\sum_i \frac{w_j }{x - x_i}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with the same weigths &lt;span class=&quot;math math-inline&quot;&gt;w_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The barycentric one becomes unstable when &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; deviates to much from &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;. The Langrange version does not suffer from this instability.&lt;&#x2F;p&gt;
&lt;p&gt;Rational functions can be evaluated using two Langrange evaluations, dividing both results in the end.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;solving&quot;&gt;Solving&lt;&#x2F;h2&gt;
&lt;p&gt;We want to approximate &lt;span class=&quot;math math-inline&quot;&gt;f(x)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;p(x)&lt;&#x2F;span&gt;. We do this by equating the values on a set of points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;. Take &lt;span class=&quot;math math-inline&quot;&gt;y_i = f(x_i)&lt;&#x2F;span&gt; and set &lt;span class=&quot;math math-inline&quot;&gt;p(x_i) = y_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{a_0 + a_1 x_i + a_2 x_i^2 \cdots a_p x_i^p}{
1 + b_1 x_i + b_2 x_i^2 \cdots b_q x_i^q} = y_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_0 + a_1 x_i + a_2 x_i^2 \cdots a_p x_i^p
= y_i (1 + b_1 x_i + b_2 x_i^2 \cdots b_q x_i^q)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_0 + a_1 x_i + a_2 x_i^2 \cdots a_p x_i^p
= y_i + b_1 y_ix_i + b_2 y_ix_i^2 \cdots b_q y_i x_i^q
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;$$
a_0 + a_1 x_i + a_2 x_i^2 \cdots a_p x_i^p&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;b_1 y_i x_i - b_2 y_ix_i^2 \cdots b_q y_i x_i^q
= y_i
$$&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;or equivalently&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_0 + a_1 x_i + a_2 x_i^2 \cdots a_p x_i^p - b_1 y_i x_i - b_2 y_i x_i^2 \cdots b_q y_i x_i^q) = y_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This can be solved using the system&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; \cdots &amp;amp;x_0^p &amp;amp;
-y_0 x_0 &amp;amp; -y_0 x_0^2 &amp;amp; \cdots &amp;amp; -y_0 x_0^q \\
\vdots &amp;amp; \vdots &amp;amp;\vdots &amp;amp; \ddots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots\\
1 &amp;amp; x_n &amp;amp; x_n^2 &amp;amp; \cdots &amp;amp;x_n^p &amp;amp;
-y_n x_n &amp;amp; -y_n x_n^2 &amp;amp; \cdots &amp;amp; -y_n x_n^q \\
\end{bmatrix}
\begin{bmatrix}
a_0 \\
a_1 \\
\vdots \\
a_p \\
b_1 \\
\vdots \\
b_q
\end{bmatrix} =
\begin{bmatrix}
y_0 \\
y_1 \\
\vdots \\
y_n \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;n = p + q + 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Method from Numerical Recipes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
y_i = y_i + e \frac{e_i}{|e_i|}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; \cdots &amp;amp; x_0^p &amp;amp;
-y_0&amp;#39; x_0 &amp;amp; -y_0&amp;#39; x_0^2 &amp;amp; \cdots &amp;amp; -y_0&amp;#39; x_0^q \\
\vdots &amp;amp; \vdots &amp;amp;\vdots &amp;amp; \ddots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots\\
1 &amp;amp; x_n &amp;amp; x_n^2 &amp;amp; \cdots &amp;amp;x_n^p &amp;amp;
-y_n x_n &amp;amp; -y_n x_n^2 &amp;amp; \cdots &amp;amp; -y_n x_n^q \\
\end{bmatrix}
\begin{bmatrix}
a_0 \\
a_1 \\
\vdots \\
a_p \\
b_1 \\
\vdots \\
b_q
\end{bmatrix} =
\begin{bmatrix}
y_0&amp;#39; \\
y_1 \\
\vdots \\
y_n \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;degrees-of-freedom&quot;&gt;Degrees of freedom&lt;&#x2F;h2&gt;
&lt;p&gt;The degrees of freedom of an element is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p + q + 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adaptive-improvement&quot;&gt;Adaptive improvement&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;increase&quot;&gt;Increase &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;increase-1&quot;&gt;Increase &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;subdivide&quot;&gt;Subdivide&lt;&#x2F;h3&gt;
&lt;p&gt;An element &lt;span class=&quot;math math-inline&quot;&gt;(p,q)&lt;&#x2F;span&gt; can subdivided in two elements of degree &lt;span class=&quot;math math-inline&quot;&gt;(p_a, q_a)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(p_b, q_b)&lt;&#x2F;span&gt; if we allow the total degrees of freedom to increase by one, we are constraint by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_a + q_a + p_b + q_b = p + q
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The number of subdivision options is equal to the number of ways &lt;span class=&quot;math math-inline&quot;&gt;p+q&lt;&#x2F;span&gt; can be distributed into four bins. This is the stars-and-bars problem with solution:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\binom{p + q + 3}{p + q}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benchmark-problem&quot;&gt;Benchmark problem&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
u(0) &amp;amp;= γ_0 \\
u(1) &amp;amp;= γ_1 \\
-u&amp;#39;&amp;#39; &amp;amp;= f
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with &lt;span class=&quot;math math-inline&quot;&gt;γ_0&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;γ_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; such that exact solution is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
u(x) = \mathrm{atan} \left(60\left(x - \frac{\pi}{3}\right) \right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;x-FEM: Using discontinuous elements to model discontinuities on a fixed mesh. https:&#x2F;&#x2F;www.google.com&#x2F;url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=2&amp;amp;cad=rja&amp;amp;uact=8&amp;amp;ved=2ahUKEwi6h_GWusDfAhU2FjQIHU5-CZUQFjABegQIAhAC&amp;amp;url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.332.6687%26rep%3Drep1%26type%3Dpdf&amp;amp;usg=AOvVaw10mBHu6KIcshB_aaZkv7xG&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;hp-adaptive FEM. https:&#x2F;&#x2F;www.researchgate.net&#x2F;profile&#x2F;Leszek_Demkowicz&#x2F;publication&#x2F;257821115_A_Fully_Automatic_hp-Adaptivity&#x2F;links&#x2F;595c43a8aca272f3c0889aa7&#x2F;A-Fully-Automatic-hp-Adaptivity.pdf?origin=publication_detail&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Rational approximation. https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;math&#x2F;0101042.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Numerical Recipes 3rd edition page 248.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Comentary on the numerical recipes algorithm. https:&#x2F;&#x2F;chasethedevil.github.io&#x2F;post&#x2F;rational_fit&#x2F;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Alternative design matrix. https:&#x2F;&#x2F;math.stackexchange.com&#x2F;questions&#x2F;924482&#x2F;least-squares-regression-matrix-for-rational-functions&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The remez &#x2F; minimax implementation in Chebfun appears to be the state of the art for rational approximation. https:&#x2F;&#x2F;people.maths.ox.ac.uk&#x2F;trefethen&#x2F;remezR2_arxiv.pdf http:&#x2F;&#x2F;www.chebfun.org&#x2F; http:&#x2F;&#x2F;www.chebfun.org&#x2F;docs&#x2F;guide&#x2F;guide04.html http:&#x2F;&#x2F;www.chebfun.org&#x2F;examples&#x2F;approx&#x2F;RationalAbsx.html https:&#x2F;&#x2F;github.com&#x2F;chebfun&#x2F;chebfun&#x2F;blob&#x2F;master&#x2F;minimax.m https:&#x2F;&#x2F;jncf2018.lip6.fr&#x2F;files&#x2F;slides&#x2F;filip.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;people.maths.ox.ac.uk&#x2F;trefethen&#x2F;barycentric.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;people.maths.ox.ac.uk&#x2F;trefethen&#x2F;publication&#x2F;PDF&#x2F;2011_138.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;AAA algorithm. https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1612.00337 http:&#x2F;&#x2F;guettel.com&#x2F;rktoolbox&#x2F;examples&#x2F;html&#x2F;example_aaa.html http:&#x2F;&#x2F;www.chebfun.org&#x2F;examples&#x2F;approx&#x2F;AAAApprox.html https:&#x2F;&#x2F;jncf2018.lip6.fr&#x2F;files&#x2F;slides&#x2F;filip.pdf https:&#x2F;&#x2F;people.maths.ox.ac.uk&#x2F;trefethen&#x2F;AAAfinal.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;AAA-Lawson. https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1705.10132.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;History of rational approximation and Floater-Hormann. http:&#x2F;&#x2F;www.alglib.net&#x2F;interpolation&#x2F;rational.php https:&#x2F;&#x2F;cs.fit.edu&#x2F;~dmitra&#x2F;SciComp&#x2F;13Spr&#x2F;MikeChirstian-NRPresentation.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;chebfun&#x2F;chebfun&#x2F;blob&#x2F;a26ae3cab130646c05fca428c1cbdfdd95208a49&#x2F;minimax.m&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Optimiality of Barycentric evaluation. https:&#x2F;&#x2F;www.researchgate.net&#x2F;profile&#x2F;Richard_Baltensperger&#x2F;publication&#x2F;226684962_Recent_Developments_in_Barycentric_Rational_Interpolation&#x2F;links&#x2F;00b4951518a41531de000000.pdf
http:&#x2F;&#x2F;eprints.maths.ox.ac.uk&#x2F;1400&#x2F;1&#x2F;NA-11-11.pdf
http:&#x2F;&#x2F;faculty.cs.tamu.edu&#x2F;schaefer&#x2F;research&#x2F;pyramid.pdf&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Exploitation: Entropy &amp; Utility</title>
        <published>2020-12-17T00:00:00+00:00</published>
        <updated>2020-12-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/exploitation/"/>
        <id>https://2π.com/20/exploitation/</id>
        
        <content type="html" xml:base="https://2π.com/20/exploitation/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\R{\mathbb{R}}
\gdef\delim#1#2#3{\mathopen{}\mathclose{\left#1 #2 \right#3}}
\gdef\p#1{({#1})}
\gdef\dummyarg{\operatorname{-}}
\gdef\d{\operatorname{d}\!}
\gdef\Pr#1{\operatorname{Pr}\p{#1}}
\gdef\E#1{\operatorname{E}[{#1}]}
\gdef\Es#1{\operatorname{E}_{#1}}
\gdef\Var#1{\operatorname{Var}\p{#1}}
\gdef\DKL#1#2{\operatorname{D_{KL}}({#1} \Vert {#2})}
\gdef\argmax{\mathop{\operatorname{arg\,max}}\limits}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;exploitation-entropy-utility&quot;&gt;Exploitation: Entropy &amp;amp; Utility&lt;&#x2F;h1&gt;
&lt;p&gt;Given some probability distribution on future returns on a collection of assets,
what is our best strategy for exploiting this knowledge?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; When is it better to wait because future information will improve our strategy?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;goal&quot;&gt;Goal&lt;&#x2F;h2&gt;
&lt;p&gt;What to optimize for?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kelly_criterion&quot;&gt;Kelly criterion&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Von_Neumann%E2%80%93Morgenstern_utility_theorem&quot;&gt;Von Neumann–Morgenstern utility theorem&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a set of possible strategies &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; and stochastic portfolio value &lt;span class=&quot;math math-inline&quot;&gt;V_i(s)&lt;&#x2F;span&gt; for strategy &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; at time &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; the Kelly goal is to &lt;em&gt;maximize the expected geometric growth rate&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\max_{s ∈ S} \E{ \lim_{n → ∞} \frac{1}{n} \ln \frac{V_n(s)}{V_0} }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For convenience we define the &lt;em&gt;exponential rate of growth&lt;&#x2F;em&gt; as &lt;span class=&quot;math math-inline&quot;&gt;G_n(s) = \frac{1}{n} \ln \frac{V_n(s)}{V_0}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;G_∞ = \lim_{n → ∞} G_n&lt;&#x2F;span&gt;, the goal then becomes &lt;span class=&quot;math math-inline&quot;&gt;\max_{s ∈ S} \E{G_∞(s)}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Kelly strategy has several nice properties:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The maximized expected geometric growth rate equals the &lt;em&gt;information entropy&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;For any other essentially different strategy &lt;span class=&quot;math math-inline&quot;&gt;s&amp;#39;&lt;&#x2F;span&gt;, we have &lt;span class=&quot;math math-inline&quot;&gt;\lim_{n → ∞} \frac{V_n(s&amp;#39;)}{V_n(s)} → 0&lt;&#x2F;span&gt; almost surely.&lt;&#x2F;li&gt;
&lt;li&gt;For any value the &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; the Kelly strategy minimizes the expected time to reach this goal.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The set of strategies &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; is deliberately left unspecified. It can include strategies that uses previous realizations &lt;span class=&quot;math math-inline&quot;&gt;V_i(s)&lt;&#x2F;span&gt; to inform decisions and it can make use of external information. In many examples the strategy is a fixed allocation &lt;span class=&quot;math math-inline&quot;&gt;f \in \R^n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\sum_i f_i = 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;side-quests&quot;&gt;Side quests&lt;&#x2F;h3&gt;
&lt;p&gt;The common criticism on the Kelly strategy is that it has too much downside risk. While it maximizes long-term growth, it is willing to endure substantial short-term losses to get there. In repeated betting examples a reduction in risk taken (in the form of more allocation to a risk-free asset) leads to a substantial decrease in downside risk, while preserving much of the growth.&lt;&#x2F;p&gt;
&lt;p&gt;The Kelly strategy is also somewhat sensitive to errors. If the model used is optimisitc, it will lead to taking to much risk which increases the probability of ruin.&lt;&#x2F;p&gt;
&lt;p&gt;Both these reasons suggest lowering the risk. Thorp promotes a strategy called &lt;em&gt;fractional Kelly&lt;&#x2F;em&gt; where only a fraction &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; of the Kelly optimum is betted. (Q: How does this generalize to portfolio&#x27;s with a risk-free asset?)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;proebstring-s-paradox&quot;&gt;Proebstring&#x27;s paradox&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proebsting%27s_paradox&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proebsting%27s_paradox&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;statweb.stanford.edu&#x2F;~lpekelis&#x2F;papers&#x2F;3_12_proebsting_pekelis.pdf&quot;&gt;https:&#x2F;&#x2F;statweb.stanford.edu&#x2F;~lpekelis&#x2F;papers&#x2F;3_12_proebsting_pekelis.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-discrete-problem&quot;&gt;The discrete problem&lt;&#x2F;h2&gt;
&lt;p&gt;The story starts with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kelly_criterion&quot;&gt;Kelly betting&lt;&#x2F;a&gt;. In this simplified version of the problem there is a repeated opportunity to place a bet. In the simplest case where the bet results in a win of &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; with probability &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;, and nothing on loss, the optimal amount to bet is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p - \frac{1 - p}{b}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The method has been generalized and developed further by E.O. Thorp. Recently the discussion evolved to include probability distributions changing on new insights.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proebsting%27s_paradox&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;J.L. Kelly (1956). &quot;A New Interpretation of Information Rate&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.princeton.edu&#x2F;~wbialek&#x2F;rome&#x2F;refs&#x2F;kelly_56.pdf&quot;&gt;https:&#x2F;&#x2F;www.princeton.edu&#x2F;~wbialek&#x2F;rome&#x2F;refs&#x2F;kelly_56.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;E.O. Thorp (2007). &quot;The Kelly Criterion in Blackjack sports betting and the stock market&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wayback.archive-it.org&#x2F;all&#x2F;20090320125959&#x2F;http:&#x2F;&#x2F;www.edwardothorp.com&#x2F;sitebuildercontent&#x2F;sitebuilderfiles&#x2F;KellyCriterion2007.pdf&quot;&gt;https:&#x2F;&#x2F;wayback.archive-it.org&#x2F;all&#x2F;20090320125959&#x2F;http:&#x2F;&#x2F;www.edwardothorp.com&#x2F;sitebuildercontent&#x2F;sitebuilderfiles&#x2F;KellyCriterion2007.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Vasily Nekrasov (2014). &quot;Kelly criterion for multivariate portfolios:a model-free approach&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;papers.ssrn.com&#x2F;sol3&#x2F;papers.cfm?abstract_id=2259133&quot;&gt;https:&#x2F;&#x2F;papers.ssrn.com&#x2F;sol3&#x2F;papers.cfm?abstract_id=2259133&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-continuous-problem&quot;&gt;The continuous problem&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Merton%27s_portfolio_problem&lt;&#x2F;p&gt;
&lt;h2 id=&quot;models&quot;&gt;Models&lt;&#x2F;h2&gt;
&lt;p&gt;A simple way to model returns is as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.m.wikipedia.org&#x2F;wiki&#x2F;Geometric_Brownian_motion&quot;&gt;geometric Brownian motion&lt;&#x2F;a&gt;. This is how it is modelled in the Black-Scholes equation for example.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Solve for multi-asset GBM first, before looking into more complex models.&lt;&#x2F;p&gt;
&lt;p&gt;Extensions of this model have been developed under the heading of (Stochastic Volatility)[https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stochastic_volatility] models.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sportsbookreview.com&#x2F;forum&#x2F;handicapper-think-tank&#x2F;29009-expected-value-vs-expected-growth-kelly-criterion-part-i.html#post250260&quot;&gt;https:&#x2F;&#x2F;www.sportsbookreview.com&#x2F;forum&#x2F;handicapper-think-tank&#x2F;29009-expected-value-vs-expected-growth-kelly-criterion-part-i.html#post250260&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.sportsbookreview.com&#x2F;forum&#x2F;handicapper-think-tank&#x2F;29841-maximizing-expected-growth-kelly-criterion-part-ii.html&quot;&gt;https:&#x2F;&#x2F;www.sportsbookreview.com&#x2F;forum&#x2F;handicapper-think-tank&#x2F;29841-maximizing-expected-growth-kelly-criterion-part-ii.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.alphatheory.com&#x2F;2013&#x2F;01&#x2F;kelly-criterion-in-practice-grizzlyrock-capital-part-1.html&quot;&gt;https:&#x2F;&#x2F;blog.alphatheory.com&#x2F;2013&#x2F;01&#x2F;kelly-criterion-in-practice-grizzlyrock-capital-part-1.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.alphatheory.com&#x2F;2013&#x2F;01&#x2F;kelly-criterion-in-practice-grizzlyrock-capital-part-2.html&quot;&gt;https:&#x2F;&#x2F;blog.alphatheory.com&#x2F;2013&#x2F;01&#x2F;kelly-criterion-in-practice-grizzlyrock-capital-part-2.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;information-theory-recap&quot;&gt;Information Theory Recap&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;C.E. Shannon (1948). &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1002%2Fj.1538-7305.1948.tb01338.x&quot;&gt;&quot;A Mathematical Theory of Communication&quot;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Given a random variable &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; with discrete outcomes &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;, the entropy &lt;span class=&quot;math math-inline&quot;&gt;H(X)&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
H(X) = - \sum_i P(x_i) \log_2 P(x_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;I(x_i) = -\log_2 P(x_i)&lt;&#x2F;span&gt; term is the information content of outcome &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;I&lt;&#x2F;span&gt; is a new random variable derived from &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;H(X) = E(I)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
H\p{X \mid Y} = - \sum_{i,j} p_{i,j} \log \frac{p_{i,j}}{p_j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mutual information &lt;span class=&quot;math math-inline&quot;&gt;I(X;Y) = I(Y;X) \ge 0&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
I(X;Y) = \sum_{x\in X} \sum_{y \in Y} p(x, y) \log_2 \frac{p(x,y)}{p(x) \cdot p(y)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mutual_information#&#x2F;media&#x2F;File:Figchannel2017ab.svg&lt;&#x2F;p&gt;
&lt;h2 id=&quot;entropy&quot;&gt;Entropy&lt;&#x2F;h2&gt;
&lt;p&gt;My all-time favorite paper is Shannon&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;A_Mathematical_Theory_of_Communication&quot;&gt;&quot;A Mathematical Theory of Communication&quot;&lt;&#x2F;a&gt;. Available in PDF &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;people.math.harvard.edu&#x2F;~ctm&#x2F;home&#x2F;text&#x2F;others&#x2F;shannon&#x2F;entropy&#x2F;entropy.pdf&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The basic Shannon entropy&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\H{\operatorname{H}}
\gdef\I{\operatorname{I}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\H(X) = - \sum_i \Pr{x_i} ⋅ \log \Pr{x_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is the expected value &lt;span class=&quot;math math-inline&quot;&gt;\H(X) = \E{\I\p{X}}&lt;&#x2F;span&gt; of the information content &lt;span class=&quot;math math-inline&quot;&gt;\I&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\I(x) = - \log \Pr{x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The information content of a random variable is itself a random variable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kelly&quot;&gt;Kelly&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; I&#x27;m spending to much time on this. Kelly is nothing more than the observation that 1) log-utility maximizes growth, and 2) the maximal growth rate is related to the Shannon entropy.&lt;&#x2F;p&gt;
&lt;p&gt;Consider a simple bet &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; with two outcomes, with probability &lt;span class=&quot;math math-inline&quot;&gt;\frac 12&lt;&#x2F;span&gt; it pays out &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt; times the inlay &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; and with probability &lt;span class=&quot;math math-inline&quot;&gt;\frac 12&lt;&#x2F;span&gt; it pays nothing. The expected payoff of this bet is &lt;span class=&quot;math math-inline&quot;&gt;\E{X} = x&lt;&#x2F;span&gt;, so it is even money.&lt;&#x2F;p&gt;
&lt;p&gt;Suppose now we have access to perfect information on the outcomes and can always place the winning bet. The expected payoff is &lt;span class=&quot;math math-inline&quot;&gt;2 x&lt;&#x2F;span&gt;. For even odds this means we double our inlay each time. If we start with capital &lt;span class=&quot;math math-inline&quot;&gt;V_0&lt;&#x2F;span&gt; and place all of it in bets, after each bet we have capital &lt;span class=&quot;math math-inline&quot;&gt;V_i&lt;&#x2F;span&gt;. Define the rate of growth &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
G ≜ \lim_{N → ∞} \frac 1N \log_2 \frac {V_N}{V_0}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With our perfect information &lt;span class=&quot;math math-inline&quot;&gt;V_i&lt;&#x2F;span&gt; is almost surely &lt;span class=&quot;math math-inline&quot;&gt;2^i ⋅ V_0&lt;&#x2F;span&gt;, so the rate of growth is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\E{G} = \lim_{N → ∞} \frac 1N \log_2 \frac {2^N ⋅ V_0}{V_0} = \lim_{N → ∞} \frac 1N \log_2 2^N = 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Consider now the case where our information is imperfect and with error probability &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; and probability of being correct &lt;span class=&quot;math math-inline&quot;&gt;q = 1 - p&lt;&#x2F;span&gt;. If we continue betting all our capital on the predicted outcome each time the expected capital is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\E{V_N} = \p{2q}^N ⋅ V_0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;However, the expected value here is deceiving, as one misplaced bet will lead to ruin. The probability of this happening after &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt; bets is &lt;span class=&quot;math math-inline&quot;&gt;1 - q^N&lt;&#x2F;span&gt; and tends to one as &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt; increases. So with probability &lt;span class=&quot;math math-inline&quot;&gt;q^N&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;2^N ⋅ V_0&lt;&#x2F;span&gt; and zero otherwise. (The commutation of &lt;span class=&quot;math math-inline&quot;&gt;\E{\dummyarg}&lt;&#x2F;span&gt; with the limit is valid by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Expected_value#Interchanging_limits_and_expectation&quot;&gt;monotone convergence theorem&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\E{G}
&amp;amp;= \E{\lim_{N → ∞} \frac 1N \log_2 \frac {V_N}{V_0}} \\
&amp;amp;= \lim_{N → ∞} \frac 1N \E{\log_2 \frac {V_N}{V_0}} \\
&amp;amp;= \lim_{N → ∞} \frac 1N \p{  q^N \p{\log_2 \frac {2^N ⋅ V_0}{V_0}} + \p{1 - q^N} \p{\log_2 \frac {0}{V_0}}} \\
&amp;amp;= \lim_{N → ∞} \frac 1N \p{  q^N \p{\log_2 2^N} + \p{1 - q^N} \p{\log_2 0}} \\
&amp;amp;= \lim_{N → ∞} \frac 1N \p{  q^N ⋅N + \p{1 - q^N} \p{-∞}} \\
&amp;amp;= -∞
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So the expected growth is diverges to negative infinity. In fact this happens for all &lt;span class=&quot;math math-inline&quot;&gt;N ≥ 1&lt;&#x2F;span&gt;. We can see that this happens whenever there is a finite chance of ruin. &lt;span class=&quot;math math-inline&quot;&gt;\E{G}&lt;&#x2F;span&gt; strongly dislikes ruin.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fractional-bets&quot;&gt;Fractional bets&lt;&#x2F;h3&gt;
&lt;p&gt;Instead of betting everything we now bet a fraction &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt; of the capital each time. At bet &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt; our capital is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
V_N = (1 + l)^{W_N} ⋅ (1 - l)^{L_N} ⋅ V_0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;W_N&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;L_N = N - W_N&lt;&#x2F;span&gt; are random variables of the number of wins and losses in the &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt; bets. &lt;span class=&quot;math math-inline&quot;&gt;W_N&lt;&#x2F;span&gt; is binomially distributed with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{W_N = i} = \binom{N}{i} ⋅ q^i ⋅ p^{N - i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;linear-utility&quot;&gt;Linear utility&lt;&#x2F;h3&gt;
&lt;p&gt;The expected value can be computed using the binomial formula&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\E{V_N}
&amp;amp;= \sum_{i ∈ [0,N]} \binom{N}{i} ⋅ q^i ⋅ p^{N - i} ⋅ (1 + l)^i ⋅ (1 - l)^{N - i} ⋅ V_0 \\
&amp;amp;= V_0 ⋅ \sum_{i ∈ [0,N]} \binom{N}{i} ⋅ \p{q(1 + l)}^i ⋅ \p{p(1 - l)}^{N - i} \\
&amp;amp;= V_0 ⋅ \p{q(1 + l) + p(1 - l)}^N \\
&amp;amp;= \p{1 + (q-p)⋅l}^N ⋅ V_0 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;q-p = 2q -1&lt;&#x2F;span&gt; and we recover &lt;span class=&quot;math math-inline&quot;&gt;\p{2q}^N ⋅ V_0&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;l =1&lt;&#x2F;span&gt;. If we want to maximize &lt;span class=&quot;math math-inline&quot;&gt;\E{V_N}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
l_{\text{exp}}
&amp;amp;≜ \argmax_l \  \E{V_N} \\
&amp;amp;= \argmax_l \  (q - p) l \\
&amp;amp;= \begin{cases} +∞ &amp;amp; q-p &amp;gt; 0 \\ -∞ &amp;amp; q-p &amp;lt; 0 \end{cases}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The expectation maximizing strategy is basically to always take infinite leverage. Not exactly subtle. But at least it is sensible enough to bet against the information when &lt;span class=&quot;math math-inline&quot;&gt;q &amp;lt; \frac 12&lt;&#x2F;span&gt; and thus &lt;span class=&quot;math math-inline&quot;&gt;q-p &amp;lt; 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;log-utility&quot;&gt;Log utility&lt;&#x2F;h3&gt;
&lt;p&gt;Let&#x27;s try maximizing growth.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\E{G}
&amp;amp;= \E{\lim_{N → ∞} \frac 1N \log_2 \frac {V_N}{V_0}} \\
&amp;amp;= \E{\lim_{N → ∞} \frac 1N \log_2 \frac {(1 + l)^{W_N} ⋅ (1 - l)^{L_N} ⋅ V_0}{V_0}} \\
&amp;amp;= \E{\lim_{N → ∞} \frac 1N \log_2 \p{(1 + l)^{W_N} ⋅ (1 - l)^{L_N}}} \\
&amp;amp;= \E{\lim_{N → ∞} \p{ \frac{W_N}{N} \log_2 \p{1 + l} + \frac{L_N}{N} \log_2 \p{1 - l} } } \\
&amp;amp;= \E{ \p{\lim_{N → ∞} \frac{W_N}{N}} \log_2 \p{1 + l} + \p{\lim_{N → ∞} \frac{L_N}{N}} \log_2 \p{1 - l} } \\
&amp;amp;= q \log_2 \p{1 + l} + p \log_2 \p{1 - l} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To maximize we solve&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0 = \frac{\d \E{G}}{\d l} =
\frac{q}{\p{1 + l} \log 2} - \frac{p}{\p{1 - l} \log 2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{q}{\p{1 + l} \log 2} = \frac{p}{\p{1 - l} \log 2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{q}{1 + l} = \frac{p}{1 - l}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
q \p{1 - l} = p \p{1 + l}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
q - ql = p  + p l
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(q-p) = (q + p) l
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
l = \frac{q - p}{q + p} = q - p
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For this &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\E{G} &amp;amp;=
q \log_2 \p{1 + l} + p \log_2 \p{1 - l} \\
&amp;amp;= q \log_2 \p{1 + q - p} + p \log_2 \p{1 - q + p} \\
&amp;amp;= q \log_2 2q + p \log_2 2p \\
&amp;amp;= 1 + q \log_2 q + p \log_2 p \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;crra-utility&quot;&gt;CRRA utility&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\E{U(V_N)}
&amp;amp;= \E{-V_N^{1 - α}} \\
&amp;amp;= - \E{\p{(1 + l)^{W_N} ⋅ (1 - l)^{L_N} ⋅ V_0}^{1-α}} \\
&amp;amp;= - V_0^{1-α} ⋅ \E{(1 + l)^{W_N ⋅ \p{1-α}} ⋅ (1 - l)^{L_N ⋅ \p{1-α}}} \\
&amp;amp;= - V_0^{1-α} ⋅ \sum_{i ∈ [0,N]} \binom{N}{i} ⋅ q^i ⋅ p^{N - i} ⋅ (1 + l)^{i ⋅ \p{1-α}} ⋅ (1 - l)^{\p{N - i} ⋅ \p{1-α}} \\
&amp;amp;= - V_0^{1-α} ⋅ \sum_{i ∈ [0,N]} \binom{N}{i} ⋅ \p{q ⋅ (1 + l)^{1-α}}^i ⋅ \p{p ⋅ (1 - l)^{1-α} }^{N - i} \\
&amp;amp;= - V_0^{1-α} ⋅ \p{ q ⋅ (1 + l)^{1-α} + p ⋅ (1 - l)^{1-α} }^N \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\argmax_l \E{U(V_N)}
&amp;amp;= \argmax_l - V_0^{1-α} ⋅ \p{ q ⋅ (1 + l)^{1-α} + p ⋅ (1 - l)^{1-α} }^N \\
&amp;amp;= \argmax_l -\p{ q ⋅ (1 + l)^{1-α} + p ⋅ (1 - l)^{1-α} } \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;market-making&quot;&gt;Market making&lt;&#x2F;h2&gt;
&lt;p&gt;Consider a random variable &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; with some ground-truth distribution &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Pr}_r&lt;&#x2F;span&gt; and two market participants, maker and taker, each with their own statistical models &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Pr}_m&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Pr}_t&lt;&#x2F;span&gt; respectively, with which they try to best approximate &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Pr}_r&lt;&#x2F;span&gt;. The maker sells the taker a contract with payout function &lt;span class=&quot;math math-inline&quot;&gt;F\p{X}&lt;&#x2F;span&gt; at price &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-is-the-price-maker-should-charge&quot;&gt;What is the price maker should charge?&lt;&#x2F;h3&gt;
&lt;p&gt;One obvious choice would be &lt;span class=&quot;math math-inline&quot;&gt;f = \Es{m}\delim[{F}]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-are-the-contract-terms-taker-should-choose&quot;&gt;What are the contract terms taker should choose?&lt;&#x2F;h3&gt;
&lt;p&gt;Taker picks &lt;span class=&quot;math math-inline&quot;&gt;F&lt;&#x2F;span&gt; such that it maximizes taker&#x27;s expectation of taker&#x27;s utility function of the payout:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\argmax_F \Es{t}{U_t\p{F\p{X}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gambling_and_information_theory&lt;&#x2F;p&gt;
&lt;h3 id=&quot;divergence&quot;&gt;Divergence&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;-divergence&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{D}_f(P, Q) = \Es Q{f\p{\frac{\d P}{\d Q}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;Kullback-Leibler divergence&lt;&#x2F;em&gt;. Given two probability measures &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt;, the relative entropy of &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; with respect to &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\DKL P Q = \int_X \log\p{\frac{\d P}{\d Q}} \d P
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\DKL P Q = \Es{P}{\log\p{\frac{\d P}{\d Q}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\DKL P Q = \Es{x \sim P}{\log\p{\frac{P(x)}{Q(x)}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\DKL P Q = \Es{x \sim P}{\log P(x)} - \Es{x \sim P}{\log Q(x)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;\Es{x \sim P}{\log Q(x)}&lt;&#x2F;span&gt; is the expected log-likelihood of &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; given &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the discrete case this this simplifies to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\DKL P Q = \sum_{x ∈ X} P\p{x} \log\p{\frac{P(x)}{Q(x)}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\DKL P Q ≥ 0&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\DKL P Q = 0&lt;&#x2F;span&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;P = Q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Shannon Entropy&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{H}(P) = - \sum_{x ∈ X} P(x) \log P(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\DKL P Q = - \sum_{x ∈ X} P\p{x} \log\p{\frac{Q(x)}{P(x)}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Marginal entropy&lt;&#x2F;p&gt;
&lt;p&gt;Conditional entropy&lt;&#x2F;p&gt;
&lt;p&gt;Joint entropy&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{I}\p{P; Q} = \DKL{p_{(P,P)}}{p_Pp_Q}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;http:&#x2F;&#x2F;cs236.stanford.edu&#x2F;assets&#x2F;slides&#x2F;cs236_lecture4.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1606.00709.pdf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;utility-functions&quot;&gt;Utility functions&lt;&#x2F;h2&gt;
&lt;p&gt;We can taylor expand the expected utility around the mean &lt;span class=&quot;math math-inline&quot;&gt;μ = \E{X}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\small \E{U(X)} = U(μ) + \frac{U&amp;#39;(μ)}{1!} ⋅ \E{X - μ} + \frac{U&amp;#39;&amp;#39;(μ)}{2!} ⋅ \E{\p{X - μ}^2} + \cdots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this we can see how the derivatives of the utility function relate to the mean &lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt;, standard deviation &lt;span class=&quot;math math-inline&quot;&gt;σ&lt;&#x2F;span&gt; and higher standardized moments &lt;span class=&quot;math math-inline&quot;&gt;\tilde{μ}_n&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\small \E{U(X)} = U(μ) + U&amp;#39;&amp;#39;(μ)\frac{σ^2}{2} + U&amp;#39;&amp;#39;&amp;#39;(μ) \frac{\tilde{μ}_3σ^3}{6} + \cdots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Utility functions are invariant under affine transformation, if &lt;span class=&quot;math math-inline&quot;&gt;U(x)&lt;&#x2F;span&gt; is a utility function then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
U&amp;#39;(x) = a + b ⋅ U(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;for &lt;span class=&quot;math math-inline&quot;&gt;b &amp;gt; 0&lt;&#x2F;span&gt; will result in the same decisions because &lt;span class=&quot;math math-inline&quot;&gt;\E{a + b ⋅ U(x)} = a + b ⋅ \E{U(X)}&lt;&#x2F;span&gt;. We therefore consider these the same utility function.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;U(x) = x&lt;&#x2F;span&gt;. Risk neutral. Maximizes expected value. Can lead to ruin in simple bets.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;U(x) \log x&lt;&#x2F;span&gt;. Risk averse. Kelly criterion. Maximizes growth rate.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Arrow-Pratt measure of absolute risk aversion:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{ARA}(x; U) ≜ - \frac{U&amp;#39;&amp;#39;(x)}{U&amp;#39;(x)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Constant absolute risk utility function.&lt;&#x2F;p&gt;
&lt;p&gt;These are considered impractical because in a two-asset portfolio they would allocate a fixed amount to the risky asset and the rest to the risk-free asset regardless of wealth.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Arrow-Pratt measure of relative risk aversion:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{RRA}(x; U) ≜ - \frac{x ⋅ U&amp;#39;&amp;#39;(x)}{U&amp;#39;(x)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This has the advantage of being a dimensionless quantity.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{RRA}(x; U) = x ⋅ \operatorname{ARA}(x; U)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{1}{x} \operatorname{RRA}(x; U) = \operatorname{ARA}(x; U)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Constant relative risk utility function. Also known as CRRA utility, parameterized by the relative risk aversion &lt;span class=&quot;math math-inline&quot;&gt;α ∈ [0,∞]&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
U(x) =
\frac{x^{1-α} - 1}{1 - α} ≅
\begin{cases}
x          &amp;amp; α = 0\\
x^{1 - α}  &amp;amp; α ∈ (0,1) \\
\log x     &amp;amp; α → 1\\
-\frac{1}{x^{α - 1}} &amp;amp; α ∈ (1,∞) \\
0          &amp;amp; α → ∞
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Affine-simplified and limiting cases are given.&lt;&#x2F;p&gt;
&lt;p&gt;The first two derivatives are &lt;span class=&quot;math math-inline&quot;&gt;U&amp;#39;(x) = x^{-α}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;U&amp;#39;&amp;#39;(x) = -α ⋅ x^{-α - 1}&lt;&#x2F;span&gt; and from this it follows that the RRA is indeed &lt;span class=&quot;math math-inline&quot;&gt;α&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{RRA}(x; U)
= - \frac{x⋅\p{-α ⋅ x^{-α - 1}}}{x^{-α}}
= α
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;exploitation&#x2F;crra.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Figure.&lt;&#x2F;strong&gt; Plot of the CRRA-utility &lt;span class=&quot;math math-inline&quot;&gt;U(x)&lt;&#x2F;span&gt; for values of &lt;span class=&quot;math math-inline&quot;&gt;α&lt;&#x2F;span&gt; from &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; (top gray line) to &lt;span class=&quot;math math-inline&quot;&gt;∞&lt;&#x2F;span&gt; (bottom gray line) in increments of &lt;span class=&quot;math math-inline&quot;&gt;\frac 1{20}&lt;&#x2F;span&gt;. The graphs for &lt;span class=&quot;math math-inline&quot;&gt;a∈[1,2]&lt;&#x2F;span&gt; are shown in black.&lt;&#x2F;p&gt;
&lt;p&gt;Practical values of &lt;span class=&quot;math math-inline&quot;&gt;α&lt;&#x2F;span&gt; are discussed in Mehra &amp;amp; Prescott page 154 and seem to be between one and two. So going forward, the utility function of choice should be&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
-\frac{1}{x^{α - 1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; There are many alternative utility functions like CARA, exponential, quadratic, that are mathematically interesting but have little relevance to investment decisions.&lt;&#x2F;p&gt;
&lt;p&gt;http:&#x2F;&#x2F;web.stanford.edu&#x2F;class&#x2F;cme241&#x2F;lecture_slides&#x2F;UtilityTheoryForRisk.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Risk_aversion#Relative_risk_aversion&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hyperbolic_absolute_risk_aversion&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Isoelastic_utility&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Entropic_risk_measure&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Entropic_value_at_risk&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Coherent_risk_measure&lt;&#x2F;p&gt;
&lt;h2 id=&quot;time-preference&quot;&gt;Time preference&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
U(v, t)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Hypothesis: Our risk aversion stays constant over time:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
U(v, t) = U_v(v) ⋅ U_t(t) + U_{v0}(v)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;ocw.mit.edu&#x2F;courses&#x2F;economics&#x2F;14-05-intermediate-macroeconomics-spring-2013&#x2F;lecture-notes&#x2F;MIT14_05S13_LecNot_consu.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Discounted_utility
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Time_preference&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sharpe-ratio&quot;&gt;Sharpe ratio&lt;&#x2F;h2&gt;
&lt;p&gt;Define excess return &lt;span class=&quot;math math-inline&quot;&gt;R = \frac{x}{x_0} - R_f&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;R_f&lt;&#x2F;span&gt; the risk free rate then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
S(X) = \frac{\E{R}}{\sqrt{\Var{R}}} = \frac{\E{\frac{X}{x_0} - R_f}}{\sqrt{\Var{\frac{X}{x_0} - R_f}}}
= \frac{\frac{\E{X}}{x_0} - R_f}{\sqrt{\frac{1}{x_0^2}\Var{X}}}
= \frac{\E{X} - R_f ⋅ x_0}{\sqrt{\Var{X}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Suppose a portfolio allocation decision &lt;span class=&quot;math math-inline&quot;&gt;θ&lt;&#x2F;span&gt; is made by maximizing the Sharpe ratio&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\argmax_θ S(X(θ))
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Under the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Von_Neumann%E2%80%93Morgenstern_utility_theorem&quot;&gt;Von Neumann-Morgenstern theorem&lt;&#x2F;a&gt; we should either be able to find a utility function for this strategy, or find a reason why it is not VNM-rational. To find the Sharpe-ratio utility function &lt;span class=&quot;math math-inline&quot;&gt;U&lt;&#x2F;span&gt; we solve&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\argmax_θ S(X(θ)) = \argmax_θ \E{U(X(θ))}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\log S^2 = \log \frac{\p{\E{x} - R_f ⋅ x_0}^2}{\Var{x}}
= 2 \log \p{\E{x} - R_f ⋅ x_0} - \log \Var{x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Equal to quadratic utility &lt;span class=&quot;math math-inline&quot;&gt;U(x) = x - b ⋅ x^2&lt;&#x2F;span&gt;? https:&#x2F;&#x2F;www.d42.com&#x2F;portfolio&#x2F;analysis&#x2F;quadratic-utility&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\E{U(x)} = \E{x - b ⋅ x^2} = \E{x} - b ⋅ \E{x^2} = \E{x} - b ⋅ \p{\Var{x} + \E{x}^2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.princeton.edu&#x2F;~dixitak&#x2F;Teaching&#x2F;EconomicsOfUncertainty&#x2F;Slides&amp;amp;Notes&#x2F;Notes02.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.princeton.edu&#x2F;~dixitak&#x2F;Teaching&#x2F;EconomicsOfUncertainty&#x2F;Slides&amp;amp;Notes&#x2F;Notes03.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sharpe_ratio&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Treynor_ratio&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Information_ratio&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alpha&quot;&gt;Alpha&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Jensen%27s_alpha&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references-1&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;C.E. Shannon (1948). &quot;A Mathematical Theory of Communication&quot;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;people.math.harvard.edu&#x2F;~ctm&#x2F;home&#x2F;text&#x2F;others&#x2F;shannon&#x2F;entropy&#x2F;entropy.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;J.L. Kelly (1956). &quot;A New Interpretation of Information Rate&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.princeton.edu&#x2F;~wbialek&#x2F;rome&#x2F;refs&#x2F;kelly_56.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;E.O. Thorp (1997). &quot;The Kelly Criterion in Blackjack, Sports Betting, and the Stock Market&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wayback.archive-it.org&#x2F;all&#x2F;20090320125959&#x2F;http:&#x2F;&#x2F;www.edwardothorp.com&#x2F;sitebuildercontent&#x2F;sitebuilderfiles&#x2F;KellyCriterion2007.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;R. Mehra &amp;amp; E.C. Prescott (1985). &quot;The Equity Premium: A Puzzle&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.academicwebpages.com&#x2F;preview&#x2F;mehra&#x2F;pdf&#x2F;The%20Equity%20Premium%20A%20Puzzle.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;R. Mehra (2006) &quot;The Equity Premium Puzzle: A Review&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;pdfs.semanticscholar.org&#x2F;b833&#x2F;df28b64daa920e36c2b9947ab90b17bed454.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;A.N. Soklakov (2018). &quot;Economics of Disagreement&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1811.08308&quot;&gt;arxiv&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;W.F. Sahrpe (1966). &quot;Mutual Fund Performance&quot;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;dx.doi.org&#x2F;10.1086&#x2F;294846&quot;&gt;doi&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.finance.martinsewell.com&#x2F;fund-performance&#x2F;Sharpe1966.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.earnforex.com&#x2F;books&#x2F;en&#x2F;advanced-forex-trading&#x2F;The_Sharpe_Ratio.pdf&lt;&#x2F;p&gt;
&lt;p&gt;EXPLAINING THE CHARACTERISTICS OF THE POWER (CRRA)UTILITY FAMILY
https:&#x2F;&#x2F;personal.eur.nl&#x2F;wakker&#x2F;pdfspubld&#x2F;08.6powerut.pdf
https:&#x2F;&#x2F;doi.org&#x2F;10.1002&#x2F;hec.1331&lt;&#x2F;p&gt;
&lt;p&gt;Burr Utility
https:&#x2F;&#x2F;www.researchgate.net&#x2F;publication&#x2F;46433745_Burr_Utility&lt;&#x2F;p&gt;
&lt;p&gt;Closed Form Solutions in Economics
https:&#x2F;&#x2F;papers.ssrn.com&#x2F;sol3&#x2F;papers.cfm?abstract_id=2354226
https:&#x2F;&#x2F;poseidon01.ssrn.com&#x2F;delivery.php?ID=480102116097121106116095076098098030127059060050007025029030118007115009025067002011033056120123040008022109127112095001088105057004042083061118069096073003077009107030077052009069102116081120009068025012083066005100115065008091119015100105102006125013&amp;amp;EXT=pdf&amp;amp;INDEX=TRUE&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Animal Crossing Turnip Markets</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/animal-crossing/"/>
        <id>https://2π.com/20/animal-crossing/</id>
        
        <content type="html" xml:base="https://2π.com/20/animal-crossing/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{({#1})}
\gdef\powerset#1{\mathcal{P}\p{#1}}
\gdef\Pr#1{\operatorname{Pr}\p{#1}}
\gdef\Prc#1#2{\operatorname{Pr}({#1} \mid {#2})}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;animal-crossing-turnip-markets&quot;&gt;Animal Crossing Turnip Markets&lt;&#x2F;h1&gt;
&lt;p&gt;The goal is to use Bayesian estimation and Kelly strategy to optimally play the AC:NH turnip market.&lt;&#x2F;p&gt;
&lt;p&gt;It is interesting because it is a non-trivial model with some memory. An interesting question will be exploration vs. exploitation. To what extend do we want to take the current offer, versus waiting for more information.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;model&quot;&gt;Model&lt;&#x2F;h2&gt;
&lt;p&gt;In the reverse engineered &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;Treeki&#x2F;85be14d297c80c8b3c0a76375743325b&quot;&gt;source code&lt;&#x2F;a&gt; we find the following model:&lt;&#x2F;p&gt;
&lt;p&gt;Pattern state transition probabilities&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{pmatrix}
0.20 &amp;amp; 0.30 &amp;amp; 0.15 &amp;amp; 0.35 \\
0.50 &amp;amp; 0.05 &amp;amp; 0.20 &amp;amp; 0.25 \\
0.25 &amp;amp; 0.45 &amp;amp; 0.05 &amp;amp; 0.25 \\
0.45 &amp;amp; 0.25 &amp;amp; 0.15 &amp;amp; 0.15 \\
\end{pmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Based on the pattern, one of fo&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bayesian-inferencing&quot;&gt;Bayesian inferencing&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;exploitation&quot;&gt;Exploitation&lt;&#x2F;h2&gt;
&lt;p&gt;In the first week we observe the following values, starting on Thursday AM:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
57, 125, 64, 56, 124, 91
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Given this information, what is the probability distribution of &lt;code&gt;pattern&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(p) = \Prc{\mathtt{pattern} = p}{X_o = x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This matches pattern zero with &lt;code&gt;declen1 = 3&lt;&#x2F;code&gt;, &lt;code&gt;hilen1 = 4&lt;&#x2F;code&gt;, &lt;code&gt;hilen3 = 2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; Assuming it is indeed that pattern, what is the probability distribution for &lt;code&gt;baseprice&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\Prc{\mathtt{baseprice} = p}{X_o = x}
&amp;amp;=
\frac{
    \Pr{\mathtt{baseprice} = p ∩ X_o = x}
}{
    \Pr{X_o = x}
}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
= \Prc{\mathtt{baseprice} = p}{X_o = x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
X_0 &amp;amp;∼ U(90, 110) \\\\
X_1 &amp;amp;∼ U(0.9, 1.4) \\\\
X_2 &amp;amp;= X_0 ⋅ X_1
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{\vec X = \vec x} = \Pr{X_0 = x_0} ⋅ \Pr{X_1 = x_1} ⋅ \Prc{X_2 = x_2}{X_0 = x_0 ∧ X_1 = x_1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ermongroup.github.io&#x2F;cs228-notes&#x2F;&quot;&gt;https:&#x2F;&#x2F;ermongroup.github.io&#x2F;cs228-notes&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a set of vertices &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; and a parent function &lt;span class=&quot;math math-inline&quot;&gt;π: V → \powerset{V}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{\vec X = \vec x} = \prod_V^v \Prc{X_v = x_v}{\vec X_{π(v)} = \vec x_{π(v)}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_{\vec X}\p{\vec x} = \prod_V^v p_v\p{x_v, \vec x_{π(v)}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; How many Turnips should you buy on Sunday?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It looks like all prices are scaled by baseprice, so it should only depend on the probability distribution over patterns?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We want to maximize the long-term growth.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We want to limit risk of ruin.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We want to limit&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We want to take into account income streams.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We want to take into account occasional withdrawals.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We want to account for imperfect execution when evaluating strategy.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Q.&lt;&#x2F;strong&gt; When should you sell the Turnips?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What is the distribution of payoff?&lt;&#x2F;li&gt;
&lt;li&gt;When should we sell, and when should we wait for more data?&lt;&#x2F;li&gt;
&lt;li&gt;Should we sell all at once or spread the sell-off?&lt;&#x2F;li&gt;
&lt;li&gt;What is the cost of flawed strategy execution?&lt;&#x2F;li&gt;
&lt;li&gt;What is the cost of false assumptions?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bayesian Networks</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/bayesian-networks/"/>
        <id>https://2π.com/20/bayesian-networks/</id>
        
        <content type="html" xml:base="https://2π.com/20/bayesian-networks/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{({#1})}
\gdef\Pr#1{\operatorname{Pr}\p{#1}}
\gdef\Prc#1#2{\operatorname{Pr}({#1} \mid {#2})}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;bayesian-networks&quot;&gt;Bayesian Networks&lt;&#x2F;h1&gt;
&lt;p&gt;To do: See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bayesoptbook.com&#x2F;book&#x2F;bayesoptbook.pdf&quot;&gt;https:&#x2F;&#x2F;bayesoptbook.com&#x2F;book&#x2F;bayesoptbook.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph BT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    BN[Bayesian Networks];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    DBN[Dynamic Bayesian Networks]--&amp;gt;BN;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    HMM[Hidden Markov Model]--&amp;gt;DBN;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SARIMA--&amp;gt;DBN;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ARIFMA--&amp;gt;DBN;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ARIMA--&amp;gt;ARIFMA;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ARMA--&amp;gt;ARIMA;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    AR--&amp;gt;ARMA;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    MA--&amp;gt;ARMA;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    KF[Kalman Filter]--&amp;gt;BN;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;definition&quot;&gt;Definition&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bayesian_network&quot;&gt;Bayesian network&lt;&#x2F;a&gt; is a directed acyclic graph &lt;span class=&quot;math math-inline&quot;&gt;G = (V, E)&lt;&#x2F;span&gt; where each node &lt;span class=&quot;math math-inline&quot;&gt;x ∈ V&lt;&#x2F;span&gt; has a conditional probability distribution associated such that the joint probability on &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{V} = \prod_{x ∈ V} \Prc{x}{π_x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;π_x&lt;&#x2F;span&gt; denotes the parents of node &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A dynamic Bayesian Network is a pair &lt;span class=&quot;math math-inline&quot;&gt;(B_0, B_t)&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;B_0&lt;&#x2F;span&gt; is a Bayesian network representing the initial distribution (i.e. at time &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;) and &lt;span class=&quot;math math-inline&quot;&gt;B_t&lt;&#x2F;span&gt; is the transition network on the same nodes &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; but with a different set of edges allowing cycles and self-loops. Define with &lt;span class=&quot;math math-inline&quot;&gt;τ_x&lt;&#x2F;span&gt; the ancestors in the transition network.&lt;&#x2F;p&gt;
&lt;p&gt;Now replicate &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; for each time &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; so we have &lt;span class=&quot;math math-inline&quot;&gt;V_0, V_1, …&lt;&#x2F;span&gt; all containing the same nodes. Similarly we have &lt;span class=&quot;math math-inline&quot;&gt;x_0, x_1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{V_0} = \prod_{x_0 ∈ V_0} \Prc{x_0}{π_{x_0}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{V_t}{V_{t-1}} = \prod_{x_t ∈ V_t} \Prc{x_t}{π_{x_t}, τ_{x_{t-1}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Tracing:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{V_{0:T}} = \Pr{V_0} ⋅ \Pr{V_{1:T}} = \prod_{x ∈ V} \Prc{x}{π_x} ⋅ \prod_{t ∈ 1:T} \prod_{x_t ∈ V_t} \Prc{x_t}{π_{x_t}, τ_{x_{t-1}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative.&lt;&#x2F;strong&gt; A special case is when &lt;span class=&quot;math math-inline&quot;&gt;x_t&lt;&#x2F;span&gt; only depends on &lt;span class=&quot;math math-inline&quot;&gt;x_{t-1}&lt;&#x2F;span&gt; and other nodes at time &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt;. So history propagates directly. In this case &lt;span class=&quot;math math-inline&quot;&gt;E_t&lt;&#x2F;span&gt; only contains self-loops.&lt;&#x2F;p&gt;
&lt;p&gt;this leads to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{V_t}{V_{t-1}} = \prod_{x ∈ V} \prod_{π_x ∈ V} \Prc{x_t}{π_{x_t}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; This model is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Markov_property&quot;&gt;Markovian&lt;&#x2F;a&gt; in that temporal relations are only between &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;t+1&lt;&#x2F;span&gt;. If different lags are required we can add these as state variables. (Or modify the model, but state seems more meaningful).&lt;&#x2F;p&gt;
&lt;p&gt;Partial observation. Only a subset of &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; is observable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hidden_Markov_model&quot;&gt;&lt;em&gt;Hidden Markov Models&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; are a special case of dynamic bayesian models.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kalman_filter&quot;&gt;&lt;em&gt;Kalman Filters&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; are a special case of dynamic bayesian models.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dynamic_Bayesian_network&quot;&gt;Dynamic Bayesian Networks&lt;&#x2F;a&gt; are a special case of Bayesian Networks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Time series models &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Autoregressive_model&quot;&gt;&lt;em&gt;AR&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Moving-average_model&quot;&gt;&lt;em&gt;MA&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Autoregressive%E2%80%93moving-average_model&quot;&gt;&lt;em&gt;ARMA&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Autoregressive_integrated_moving_average&quot;&gt;&lt;em&gt;ARIMA&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Autoregressive_fractionally_integrated_moving_average&quot;&gt;&lt;em&gt;ARIFMA&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;(?) are special cases of dynamic bayesian networks. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Finite_impulse_response&quot;&gt;&lt;em&gt;FIR&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Infinite_impulse_response&quot;&gt;&lt;em&gt;IIR&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; filters have ARIMA structure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;learning-structure&quot;&gt;Learning structure&lt;&#x2F;h2&gt;
&lt;p&gt;It is possible to learn the structure of the graph from the data.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;For learning the base structure we can use all the available data for each variable, ignoring the temporal information. This is equivalent to learning a BN.
For learning the transition network we consider the temporal information, in particular the data for all variables in two consecutive time slices, &lt;span class=&quot;math math-inline&quot;&gt;X_t&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;X_{t+1}&lt;&#x2F;span&gt;.
Considering the base structure, we can then learn the dependencies between the variables at time &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;t+1&lt;&#x2F;span&gt;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~esucar&#x2F;Clases-mgp&#x2F;Notes&#x2F;c9-dbn.pdf&quot;&gt;[source]&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;learning-distributions-parameters-cma-es-on-cost-function&quot;&gt;Learning distributions parameters: CMA-ES on cost function&lt;&#x2F;h2&gt;
&lt;p&gt;In contracts with the &#x27;Expectation Maximization&#x27; method, the model is not optimized for distribution fit, but for a specified cost function. This makes the learning less sensitive to modelling errors.&lt;&#x2F;p&gt;
&lt;p&gt;One cost function is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Maximum_likelihood_estimation&quot;&gt;maximum likelihood&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;special-case-kalman-filters&quot;&gt;Special case: Kalman filters&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec x_{t+1} = A ⋅ \vec x_t + \vec c_t + \vec w_t
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec z_{t} = H ⋅ \vec x_t + \vec v_t
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With noise vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec w_t ∼ \mathcal{N}(0, Q_t)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec v_t ∼ \mathcal{N}(0, R_t)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{\vec x_{t+1}}{\vec x_t} \sim \mathcal{N}(A ⋅ \vec x_t, Q)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{\vec z_t}{\vec x_t} \sim \mathcal{N}(H ⋅ \vec x_t, R)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;special-case-arima&quot;&gt;Special case: ARIMA&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;multithreaded.stitchfix.com&#x2F;blog&#x2F;2016&#x2F;04&#x2F;21&#x2F;forget-arima&#x2F;&quot;&gt;https:&#x2F;&#x2F;multithreaded.stitchfix.com&#x2F;blog&#x2F;2016&#x2F;04&#x2F;21&#x2F;forget-arima&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Y_t = \mu_t + x_t \beta + S_t + e_t
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mu_{t+1} = \mu_t + v_t
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;A new approach to learning in Dynamic BayesianNetworks (DBNs)
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1812.09027.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1812.09027.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Kalman filter demystified: from intuition to probabilistic graphical model to real case in financial markets
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1811.11618.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1811.11618.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A TutorialonDynamicBayesianNetworks
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cs.ubc.ca&#x2F;~murphyk&#x2F;Papers&#x2F;dbntalk.pdf&quot;&gt;https:&#x2F;&#x2F;www.cs.ubc.ca&#x2F;~murphyk&#x2F;Papers&#x2F;dbntalk.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;M. I. Jordan. An introduction to probabilistic graphical models.  Berkeley, 2016
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.eecs.berkeley.edu&#x2F;~jordan&#x2F;prelims&#x2F;&quot;&gt;https:&#x2F;&#x2F;people.eecs.berkeley.edu&#x2F;~jordan&#x2F;prelims&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.amazon.com&#x2F;gp&#x2F;product&#x2F;0262018020&lt;&#x2F;li&gt;
&lt;li&gt;Learning temporal nodes Bayesian networks.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~emorales&#x2F;Papers&#x2F;2013&#x2F;2013-HernandezLearningTemporalNodes.pdf&quot;&gt;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~emorales&#x2F;Papers&#x2F;2013&#x2F;2013-HernandezLearningTemporalNodes.pdf&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~esucar&#x2F;Clases-mgp&#x2F;Notes&#x2F;c9-dbn.pdf&quot;&gt;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~esucar&#x2F;Clases-mgp&#x2F;Notes&#x2F;c9-dbn.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bayesserver.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.bayesserver.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; How does this relate to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bayesian_structural_time_series&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bayesian_structural_time_series&lt;&#x2F;a&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;courses.cs.washington.edu&#x2F;courses&#x2F;cse515&#x2F;09sp&#x2F;slides&#x2F;varel.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;ethz.ch&#x2F;content&#x2F;dam&#x2F;ethz&#x2F;special-interest&#x2F;mtec&#x2F;chair-of-entrepreneurial-risks-dam&#x2F;documents&#x2F;dissertation&#x2F;master%20thesis&#x2F;Master_Thesis_%20Morzywolek.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;jsyoon0823&#x2F;TimeGAN&lt;&#x2F;p&gt;
&lt;p&gt;http:&#x2F;&#x2F;isomorphisms.sdf.org&#x2F;maxdama.pdf&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Learning hard problems: CMA-ES</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/cma-es/"/>
        <id>https://2π.com/20/cma-es/</id>
        
        <content type="html" xml:base="https://2π.com/20/cma-es/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\N{\mathbb{N}}
\gdef\R{\mathbb{R}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;learning-hard-problems-cma-es&quot;&gt;Learning hard problems: CMA-ES&lt;&#x2F;h1&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;CMA-ES&quot;&gt;covariance matrix adaptation evolution strategy&lt;&#x2F;a&gt; is black-box optimization algorithm. That performs well in practice &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;1830761.1830790&quot;&gt;[source]&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We have a function &lt;span class=&quot;math math-inline&quot;&gt;f: \R^n → \R&lt;&#x2F;span&gt; that we want to minimize.&lt;&#x2F;p&gt;
&lt;p&gt;The algorithm iterates three steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Generate new solutions &lt;span class=&quot;math math-inline&quot;&gt;\vec x_i \in \R^n&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Sort solutions by fitness &lt;span class=&quot;math math-inline&quot;&gt;f(x_i) ≤ f(x_{i+1})&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Update the internal state using re-ordered samples.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Since &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; is only used to order the candidate solutions, very few assumptions on &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; are made.&lt;&#x2F;p&gt;
&lt;p&gt;The state of the algorithm is:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The mean &lt;span class=&quot;math math-inline&quot;&gt;\vec m ∈ \R^n&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The covariance matrix &lt;span class=&quot;math math-inline&quot;&gt;C ∈ \R^{n^2}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The step-size &lt;span class=&quot;math math-inline&quot;&gt;σ ∈ \R_{&amp;gt; 0}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The isotropic path &lt;span class=&quot;math math-inline&quot;&gt;\vec p ∈ \R^n&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The anisotropic path &lt;span class=&quot;math math-inline&quot;&gt;\vec q ∈ \R^n&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The initial values are &lt;span class=&quot;math math-inline&quot;&gt;C = I&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec p = \vec q = \vec 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The parameters of the algoritm are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;λ ∈ \N_{&amp;gt;0}&lt;&#x2F;span&gt; the number of candidate solutions to try.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\vec w ∈ \R^n&lt;&#x2F;span&gt; the recombination weights.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;generating-new-solutions&quot;&gt;Generating new solutions&lt;&#x2F;h2&gt;
&lt;p&gt;A total of &lt;span class=&quot;math math-inline&quot;&gt;λ&lt;&#x2F;span&gt; new solutions &lt;span class=&quot;math math-inline&quot;&gt;\vec x_0, \dots, \vec x_{λ -1}&lt;&#x2F;span&gt;  are drawn from the multinomial distribution&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec x_i ∼ \mathcal N (\vec m, σ^2 ⋅ C)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is the same as &lt;span class=&quot;math math-inline&quot;&gt;\vec m + σ ⋅ \mathcal N (\vec 0, C)&lt;&#x2F;span&gt;, the solutions are all pertubations of the mean &lt;span class=&quot;math math-inline&quot;&gt;\vec m&lt;&#x2F;span&gt;, which represents the current best estimate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sorting-solutions&quot;&gt;Sorting solutions&lt;&#x2F;h2&gt;
&lt;p&gt;Sort the solutions by &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f(\vec x_0) ≤ f(\vec x_1) ≤ \cdots ≤ f(\vec x_{λ - 1})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;update-the-mean&quot;&gt;Update the mean&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec m&amp;#39; = \sum_i w_i ⋅ \vec x_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;w_i&lt;&#x2F;span&gt; are the recombination weights such that &lt;span class=&quot;math math-inline&quot;&gt;\sum_i w_i = 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;w_i \geq w_{i+1}&lt;&#x2F;span&gt;. Typically there is a &lt;span class=&quot;math math-inline&quot;&gt;0 &amp;lt; μ ≤ λ&#x2F;2&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;w_i = \frac{1}{μ}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;i &amp;lt; μ&lt;&#x2F;span&gt; and zero otherwise.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
μ = \left\lfloor \frac{λ}{2} \right\rfloor
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
w_i = \frac{1}{\Sigma} \ln(μ + 2) - \ln i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;update-the-step-size&quot;&gt;Update the step-size&lt;&#x2F;h2&gt;
&lt;p&gt;First the isotropic path is updated&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec p&amp;#39; = (1 - c_p) \vec p +
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;update-the-covariance-matrix&quot;&gt;Update the covariance matrix&lt;&#x2F;h2&gt;
&lt;p&gt;First the anisotropic path is updated&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;CMA-ES&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;CMA-ES&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;BIPOP-CMA-ES. Benchmarking a BI-Population CMA-ES on theBBOB-2009 Function Testbed
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hal.inria.fr&#x2F;inria-00382093&#x2F;document&quot;&gt;https:&#x2F;&#x2F;hal.inria.fr&#x2F;inria-00382093&#x2F;document&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Comparing Results of 31 Algorithms from the Black-Box Optimization Benchmarking BBOB-2009
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;1830761.1830790&quot;&gt;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;pdf&#x2F;10.1145&#x2F;1830761.1830790&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linear Algebra</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/linear-algebra/"/>
        <id>https://2π.com/20/linear-algebra/</id>
        
        <content type="html" xml:base="https://2π.com/20/linear-algebra/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\R{\mathbb{R}}
\gdef\C{\mathbb{C}}
\gdef\p#1{({#1})}
\gdef\abs#1{\lvert{#1}\rvert}
\gdef\norm#1{\lVert{#1}\rVert}
\gdef\set#1{\mathcal{#1}}
\gdef\dummyarg{\operatorname{-}}
\gdef\pder#1{\frac{\partial}{\partial #1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;linear-algebra&quot;&gt;Linear Algebra&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; Every finite dimensional Hilbert space has scalar field either &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;\C&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Is this true? What about &lt;span class=&quot;math math-inline&quot;&gt;\R[X]&lt;&#x2F;span&gt; or quaternions?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a symmetric positive semi-definite matrix &lt;span class=&quot;math math-inline&quot;&gt;K ∈ \R^{n × n}&lt;&#x2F;span&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mahalanobis_distance&quot;&gt;&lt;em&gt;Mahalanobis norm&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\norm{\dummyarg}_K&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\norm{\vec x}_K ≜ \sqrt{\vec x^T ⋅ K ⋅ \vec x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a symmetric positive semi-definite matrix &lt;span class=&quot;math math-inline&quot;&gt;K ∈ \R^{n × n}&lt;&#x2F;span&gt;, a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Whitening_transformation&quot;&gt;&lt;em&gt;whitening transform&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is a matrix &lt;span class=&quot;math math-inline&quot;&gt;W ∈ \R^{n × n}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;W ⋅ K ⋅ W^T = I&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; There are many solutions &lt;span class=&quot;math math-inline&quot;&gt;W&lt;&#x2F;span&gt; that satisfy the above. In particular given any whitening matrix &lt;span class=&quot;math math-inline&quot;&gt;W&lt;&#x2F;span&gt; and unitary matrix &lt;span class=&quot;math math-inline&quot;&gt;U ∈ \R^{n × n}&lt;&#x2F;span&gt; the matrix &lt;span class=&quot;math math-inline&quot;&gt;U ⋅ W&lt;&#x2F;span&gt; is also a whitening matrix.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; The &lt;em&gt;Mahalanobis whitening&lt;&#x2F;em&gt; matrix is &lt;span class=&quot;math math-inline&quot;&gt;W = K^{- \frac 12}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; The &lt;em&gt;Cholesky transform&lt;&#x2F;em&gt; is &lt;span class=&quot;math math-inline&quot;&gt;W = L^T&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;L^T ⋅ L = K^{-1}&lt;&#x2F;span&gt; is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cholesky_decomposition&quot;&gt;Cholesky decomposition&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; The &lt;em&gt;ZCA-Cor transform&lt;&#x2F;em&gt; is &lt;span class=&quot;math math-inline&quot;&gt;W = P^{-\frac 12} ⋅ V^{- \frac 12}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; is the diagonal of &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;P = V^{-\frac 12} ⋅ K ⋅ V^{-\frac 12}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; ZCA-Cor maximizes the correlation between the original an whitened values. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1512.00809&quot;&gt;KLS16&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Proof that this actually is a norm. Explain https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Whitening_transformation and relationship to Euclidean norm.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; The whitening matrix is not unqiue see &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;aeolister.wordpress.com&#x2F;2018&#x2F;03&#x2F;19&#x2F;from-generalised-least-squares-to-linear-regression-via-singular-value-decomposition&#x2F;&quot;&gt;here&lt;&#x2F;a&gt; for two solutions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; When &lt;span class=&quot;math math-inline&quot;&gt;Ω = I&lt;&#x2F;span&gt; the Mahalanobis norm equals the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Norm_(mathematics)#Euclidean_norm&quot;&gt;Euclidean norm&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Summarize SVD and how it &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.uio.no&#x2F;studier&#x2F;emner&#x2F;matnat&#x2F;ifi&#x2F;nedlagte-emner&#x2F;INF-MAT3350&#x2F;h07&#x2F;undervisningsmateriale&#x2F;chap12slides.pdf&quot;&gt;&lt;em&gt;relates to almost everything else&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Discuss the Generalized SVD &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.netlib.org&#x2F;lapack&#x2F;lug&#x2F;node36.html&quot;&gt;GSVD&lt;&#x2F;a&gt; and its (potentia) application here.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Discuss Moore-Penrose pseudoinverse.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Jacobian_matrix_and_determinant&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hessian_matrix&lt;&#x2F;p&gt;
&lt;h2 id=&quot;norms-and-means&quot;&gt;Norms and means&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given &lt;span class=&quot;math math-inline&quot;&gt;p ∈ \R ∪ \set{-∞, +∞}&lt;&#x2F;span&gt; The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lp_space#The_p-norm_in_finite_dimensions&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;-norm&lt;&#x2F;a&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\norm{\vec x}_p ≜ \p{\sum_i \abs{x_i} ^p}^{\frac{1}{p}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The limiting cases &lt;span class=&quot;math math-inline&quot;&gt;\set{-∞, 0, +∞}&lt;&#x2F;span&gt; are not real norms.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The special case &lt;span class=&quot;math math-inline&quot;&gt;p=1&lt;&#x2F;span&gt; sL1-norm is also known as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Taxicab_geometry&quot;&gt;*Taxicab norm&lt;&#x2F;a&gt;, &lt;em&gt;Manhattan norm&lt;&#x2F;em&gt;, or in the case of one dimension, the &lt;a href=&quot;#&quot;&gt;&lt;em&gt;Absolute-value norm&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The limiting case of a &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;-norm is the Hamming weight. The corresponding distance is the Hamming distance.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;-norm is also known as the &lt;a href=&quot;#&quot;&gt;&lt;em&gt;Euclidean norm&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The &lt;span class=&quot;math math-inline&quot;&gt;+∞&lt;&#x2F;span&gt;-norm is also known as the &lt;span class=&quot;math math-inline&quot;&gt;∞&lt;&#x2F;span&gt;-norm, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Uniform_norm&quot;&gt;&lt;em&gt;infinity norm&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; or the &lt;a href=&quot;#&quot;&gt;&lt;em&gt;maximum norm&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; What happens with the negative norms?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Each norm has an associated &lt;em&gt;distance&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
d(\vec a, \vec b) = \norm{a - b}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Each &lt;em&gt;distance&lt;&#x2F;em&gt; has an associated nearest scalar value in the following sence:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
s = \arg \min_s d\p{\vec x, s ⋅ \vec 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The summary statistic from the &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;-norm is called the &lt;a href=&quot;#&quot;&gt;&lt;em&gt;mode&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; and is not unique.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The summary statistic from the &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;-norm is called the &lt;a href=&quot;#&quot;&gt;&lt;em&gt;median&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The summary statistic from the &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;-norm is called the &lt;a href=&quot;#&quot;&gt;&lt;em&gt;mean&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.johnmyleswhite.com&#x2F;notebook&#x2F;2013&#x2F;03&#x2F;22&#x2F;modes-medians-and-means-an-unifying-perspective&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.johnmyleswhite.com&#x2F;notebook&#x2F;2013&#x2F;03&#x2F;22&#x2F;using-norms-to-understand-linear-regression&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; For values  &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ \R^n&lt;&#x2F;span&gt; the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Generalized_mean&quot;&gt;&lt;em&gt;generalized mean&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\frac{1}{n} \sum_i x_i^p}^{\frac{1}{p}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lehmer_mean&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Quasi-arithmetic_mean&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The &lt;span class=&quot;math math-inline&quot;&gt;-∞&lt;&#x2F;span&gt;-norm is also known as the &lt;a href=&quot;#&quot;&gt;&lt;em&gt;minimum norm&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.johnmyleswhite.com&#x2F;notebook&#x2F;2014&#x2F;03&#x2F;24&#x2F;a-note-on-the-johnson-lindenstrauss-lemma&#x2F;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;matrix-calculus&quot;&gt;Matrix Calculus&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\pder{\vec x} \vec y
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;KLS16 Agnan Kessy, Alex Lewin, Korbinian Strimmer (2016) “Optimal whitening and decorrelation”
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1512.00809&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1512.00809&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Terrence Parr, Jeremy Howards (2018). “The Matrix Calculus You Need For Deep Learning”
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1802.01528&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1802.01528&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;explained.ai&#x2F;matrix-calculus&#x2F;&quot;&gt;https:&#x2F;&#x2F;explained.ai&#x2F;matrix-calculus&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Probability spaces</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/probability-spaces/"/>
        <id>https://2π.com/20/probability-spaces/</id>
        
        <content type="html" xml:base="https://2π.com/20/probability-spaces/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\N{\mathbb{N}}
\gdef\R{\mathbb{R}}
\gdef\∀{\forall}
\gdef\∪{\cup}
\gdef\delim#1#2#3{#1 #2 #3}
\gdef\p#1{({#1})}
\gdef\card#1{\lvert{#1}\rvert}
\gdef\norm#1{\lVert{#1}\rVert}
\gdef\set#1{\mathcal{#1}}
\gdef\powerset#1{\mathcal{P}\p{#1}}
\gdef\Union{\bigcup}
\gdef\Intersection{\bigcap}
\gdef\comp#1{\overline{#1}}
\gdef\d{\operatorname{d}\!}
\gdef\Pr#1{\operatorname{Pr}\p{#1}}
\gdef\Prc#1#2{\operatorname{Pr}({#1} \mid {#2})}
\gdef\E#1{\operatorname{E}[{#1}]}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;probability-spaces&quot;&gt;Probability spaces&lt;&#x2F;h1&gt;
&lt;p&gt;Naive probability theory is either discrete or continuous. Consider a six-sided die, we can talk about the expected value using the discrete definition &lt;span class=&quot;math math-inline&quot;&gt;\E{X} = \sum_x x ⋅ \Pr{X = x}&lt;&#x2F;span&gt; and find &lt;span class=&quot;math math-inline&quot;&gt;3.5&lt;&#x2F;span&gt;. Similarly, consider a wheel spinner with values &lt;span class=&quot;math math-inline&quot;&gt;\delim[{0,1})&lt;&#x2F;span&gt;, we can talk about the expected value using the continuous definition &lt;span class=&quot;math math-inline&quot;&gt;\E{X} = \int_0^1 x ⋅ p(x) \d x&lt;&#x2F;span&gt; and find &lt;span class=&quot;math math-inline&quot;&gt;0.5&lt;&#x2F;span&gt;. But now we do something interesting: we remove the &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; face of the die and in its place we put the spinner. Now when we roll the die, we get either the value &lt;span class=&quot;math math-inline&quot;&gt;2,3,4,5,6&lt;&#x2F;span&gt;, or a number in &lt;span class=&quot;math math-inline&quot;&gt;\delim[{0,1})&lt;&#x2F;span&gt;. If we roll this die a number of times and take the average, we find it is about &lt;span class=&quot;math math-inline&quot;&gt;3.4&lt;&#x2F;span&gt;, with a bit of reasoning we can deduce the exact value &lt;span class=&quot;math math-inline&quot;&gt;\frac{41}{12}&lt;&#x2F;span&gt;. The outcomes are neither discrete nor continuous, how do we rigorously define what we intuitively mean (no pun intended) with expected value?&lt;&#x2F;p&gt;
&lt;p&gt;Another limitation of naive probability theory is with distributions such as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dirac_delta_function&quot;&gt;Dirac delta function&lt;&#x2F;a&gt;. These are ill-defined in the normal understanding of real numbers and Riemann integrals. But again, they make intuitive sense and are useful in practice. How do we make them rigorous?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; I use the operator notation &lt;span class=&quot;math math-inline&quot;&gt;A_B^C&lt;&#x2F;span&gt; as shorthand for &lt;span class=&quot;math math-inline&quot;&gt;A_{C ∈ B}&lt;&#x2F;span&gt; meaning to apply operator &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; with bound variable &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; ranging over set &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt;, for example &lt;span class=&quot;math math-inline&quot;&gt;\sum_{[0,n)}^i x_i&lt;&#x2F;span&gt; denotes the sum over &lt;span class=&quot;math math-inline&quot;&gt;x_0, \dots x_{n-1}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;measure-theory&quot;&gt;Measure theory&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;s-algebra&quot;&gt;σ-algebra&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a set &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt;, a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;%CE%A3-algebra&quot;&gt;&lt;em&gt;σ-algebra&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; on &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt; is a set of subsets &lt;span class=&quot;math math-inline&quot;&gt;Σ ⊆ \powerset{Ω}&lt;&#x2F;span&gt; such that it includes itself,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\tag{1}
Ω ∈ Σ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;is closed under complements, for any &lt;span class=&quot;math math-inline&quot;&gt;S ∈ Σ&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\tag{2}
\p{Ω \setminus S} ∈ Σ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and is closed under countable unions, for any &lt;span class=&quot;math math-inline&quot;&gt;I ∈ \powerset{Σ}&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\card{I} ≤ \aleph_0&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\tag{3}
\p{\∪_{S ∈ I} S} ∈ Σ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Within a particular σ-algebra, &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt; acts as a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Universe_(mathematics)&quot;&gt;&lt;em&gt;universe&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; and  I will use &lt;span class=&quot;math math-inline&quot;&gt;\comp E&lt;&#x2F;span&gt; to denote the complement with respect to &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\comp E ≜ Ω \setminus E
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From the definition follows that &lt;span class=&quot;math math-inline&quot;&gt;∅ ∈ Ω&lt;&#x2F;span&gt; because &lt;span class=&quot;math math-inline&quot;&gt;∅ = \comp Ω&lt;&#x2F;span&gt; and for is closed under countable intersections, i.e. given &lt;span class=&quot;math math-inline&quot;&gt;I ∈ \powerset Σ&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\card{I} ≤ \aleph_0&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Intersection_{S ∈ I} S = \comp{\Union_{S ∈ I} \comp S} ∈ Σ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;measure-space&quot;&gt;Measure space&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; A pair &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ)&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Measurable_space&quot;&gt;&lt;em&gt;measurable space&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;Σ&lt;&#x2F;span&gt; is a σ-algebra over &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In the probability theory that follows below, the set &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt; will represent the outcome space and &lt;span class=&quot;math math-inline&quot;&gt;Σ&lt;&#x2F;span&gt; the event space.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a measurable space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ)&lt;&#x2F;span&gt;, a function &lt;span class=&quot;math math-inline&quot;&gt;μ: Σ → [0, ∞]&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Measure_(mathematics)&quot;&gt;&lt;em&gt;measure&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; on &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ)&lt;&#x2F;span&gt; iff&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\∀_F^E μ(E) \ge 0&lt;&#x2F;span&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;μ(∅) = 0&lt;&#x2F;span&gt;, and&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\∀_{\powerset{Σ}}^S \ \norm S ∈ \N ∧ \∀_S^A \∀_{S \setminus \set{A}}^B A ∩ B = ∅ → μ\p{\∪_S^E E} = \sum_S^E μ(E)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; While measure theory allows &lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt; to range over &lt;span class=&quot;math math-inline&quot;&gt;[0, ∞]&lt;&#x2F;span&gt;, in probability theory the measure will be a probability and be restricted to &lt;span class=&quot;math math-inline&quot;&gt;[0,1]&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;μ(Ω) = 1&lt;&#x2F;span&gt;, see below. For now it is kept generic.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; A triple &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, μ)&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Measure_space&quot;&gt;&lt;em&gt;measure space&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt; is a set.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;Σ&lt;&#x2F;span&gt; is a σ-algebra on set &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt; is a measure on &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; Given a measure space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, μ)&lt;&#x2F;span&gt; then&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;If &lt;span class=&quot;math math-inline&quot;&gt;S, T ∈ Σ&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;S ⊂ T&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;μ(S) ≤ μ(T)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Given countable &lt;span class=&quot;math math-inline&quot;&gt;I ∈ \powerset Σ&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;μ\p{\Union_{S ∈ I} S} ≤ \sum_{S ∈ I} μ(S)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Given ascending chain &lt;span class=&quot;math math-inline&quot;&gt;S_1 ⊂ S_2 ⊂ S_3 ⊂ ⋯&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;μ\p{\Union_i S_i} = \lim_{i \to ∞} μ(S_i)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Given descending chain &lt;span class=&quot;math math-inline&quot;&gt;S_1 ⊃ S_2 ⊃ S_3 ⊃ ⋯&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;μ\p{\Intersection_i S_i} = \lim_{i \to ∞} μ(S_i)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a measure space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, μ)&lt;&#x2F;span&gt;, a subset &lt;span class=&quot;math math-inline&quot;&gt;S ∈ Σ&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Null_set&quot;&gt;&lt;em&gt;μ-null set&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;μ(S) = 0&lt;&#x2F;span&gt;. A subset &lt;span class=&quot;math math-inline&quot;&gt;S ∈ Σ&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Full_measure_(mathematics)&quot;&gt;&lt;em&gt;μ-full measure set&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;\comp S&lt;&#x2F;span&gt; is a μ-null set.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a measure space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, μ)&lt;&#x2F;span&gt;, a property &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt; holds &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Almost_everywhere&quot;&gt;&lt;em&gt;μ-almost everywhere&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff there exists a μ-null set &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;P(x)&lt;&#x2F;span&gt; for all &lt;span class=&quot;math math-inline&quot;&gt;x ∈ \comp S&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In probability theory, this is also known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Almost_surely&quot;&gt;&lt;em&gt;μ-almost surely&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; and implies that the probability that the property holds is &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; A measure space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, μ)&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Complete_measure&quot;&gt;&lt;em&gt;complete measure space&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff for every μ-null set &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; we have &lt;span class=&quot;math math-inline&quot;&gt;\powerset S ⊆ Σ&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a measure space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, μ)&lt;&#x2F;span&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Complete_measure#Construction_of_a_complete_measure&quot;&gt;&lt;em&gt;completion&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is the smallest extensions such that the measure space is complete.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lebesgue-measure&quot;&gt;Lebesgue measure&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;lebesgue-s-decomposition-theorem&quot;&gt;Lebesgue&#x27;s decomposition theorem&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
μ = μ_{\text{continuous}} + \mu_{\text{discrete}} + \mu_{\text{singular}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;measurable-function&quot;&gt;Measurable function&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Define &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Measurable_function&quot;&gt;&lt;em&gt;measurable function&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pushforward-measure&quot;&gt;Pushforward measure&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given two measurable spaces &lt;span class=&quot;math math-inline&quot;&gt;(Ω_1, Σ_1)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(Ω_2, Σ_2)&lt;&#x2F;span&gt;, a measure &lt;span class=&quot;math math-inline&quot;&gt;μ: Σ_1 → \R ∪ \set{+∞}&lt;&#x2F;span&gt; and a measurable function &lt;span class=&quot;math math-inline&quot;&gt;f: Ω_1 → Ω_2&lt;&#x2F;span&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pushforward_measure&quot;&gt;&lt;em&gt;pushforward measure&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;f_* μ: Σ_2 → \R ∪ \set{+∞}&lt;&#x2F;span&gt; is defined by:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_* μ (X) ≜ μ\p{f^{-1}\p{B}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; The pushforward measure is a measure on &lt;span class=&quot;math math-inline&quot;&gt;(Ω_2, Σ_2)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lebesgue-integration&quot;&gt;Lebesgue integration&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Define the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lebesgue_integration&quot;&gt;Lebesgue integral&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\int_Ω ⋅ \d \Pr{ω}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\int_Ω f \d \operatorname{Pr} = \int_Ω f\p{x} \d \Pr{x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;radon-nikodym-theorem&quot;&gt;Radon-Nikodym theorem&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; Given a measurable space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ)&lt;&#x2F;span&gt; with two measures &lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;ν&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\forall_Σ^A\ μ(A) = 0 → ν(A) = 0&lt;&#x2F;span&gt; (i.e. &lt;span class=&quot;math math-inline&quot;&gt;ν ≪ μ&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;ν&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Absolute_continuity#Absolute_continuity_of_measures&quot;&gt;absolute continuous&lt;&#x2F;a&gt; with respect to &lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt;), then there exists a measurable function &lt;span class=&quot;math math-inline&quot;&gt;f: Ω → \R ∪ \set{+∞}&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\forall_Σ^A\ ν(A) = \int_A f(ω) \d μ(ω)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;furthermore this function is unique up to a &lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt;-null set.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Denote the function &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; from the above theorem as the &lt;em&gt;Radon–Nikodym derivative&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;\frac{\d ν}{\d μ}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;probability-theory&quot;&gt;Probability theory&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;probability-measure&quot;&gt;Probability measure&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; A measure &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Pr}&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ)&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Probability_measure&quot;&gt;&lt;em&gt;probability measure&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;\Pr{Ω} = 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; From this it follows &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Pr}: Σ → [0, 1]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;probability-space&quot;&gt;Probability space&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; A measure space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, \operatorname{Pr})&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Probability_space&quot;&gt;&lt;em&gt;probability space&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;P(Ω) = 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The set &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt; is known as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sample_space&quot;&gt;&lt;em&gt;sample space&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. The members of &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt; are known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Outcome_(probability)&quot;&gt;&lt;em&gt;outcomes&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. The set &lt;span class=&quot;math math-inline&quot;&gt;Σ&lt;&#x2F;span&gt; is known as the &lt;em&gt;event space&lt;&#x2F;em&gt; and members of &lt;span class=&quot;math math-inline&quot;&gt;Σ&lt;&#x2F;span&gt; are known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Event_(probability_theory)&quot;&gt;&lt;em&gt;events&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. If and event is a singleton (i.e. contains a single outcome) it is know as an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Elementary_event&quot;&gt;&lt;em&gt;elementary event&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; From the above definitions the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Probability_axioms&quot;&gt;Kolgomorov axioms&lt;&#x2F;a&gt; are apparent.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Elementary theorems from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ermongroup.github.io&#x2F;cs228-notes&#x2F;preliminaries&#x2F;probabilityreview&#x2F;&quot;&gt;https:&#x2F;&#x2F;ermongroup.github.io&#x2F;cs228-notes&#x2F;preliminaries&#x2F;probabilityreview&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;From here on, assume we are give a probability space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, \operatorname{Pr})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Given an event &lt;span class=&quot;math math-inline&quot;&gt;e ∈ Σ&lt;&#x2F;span&gt; and number &lt;span class=&quot;math math-inline&quot;&gt;n ∈ (0, \infty)&lt;&#x2F;span&gt;, the &lt;em&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Odds&quot;&gt;odds&lt;&#x2F;a&gt; of &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;&lt;&#x2F;em&gt; are “&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\frac{n ⋅ \Pr{e}}{1 - \Pr{e}}&lt;&#x2F;span&gt;” and the &lt;em&gt;odds against &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;&lt;&#x2F;em&gt; are “&lt;span class=&quot;math math-inline&quot;&gt;\frac{n⋅\p{1 - \Pr{e}}}{\Pr{e}}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;”. If &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is left out it is assumed &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;. The &lt;em&gt;logit&lt;&#x2F;em&gt; or &lt;em&gt;log-odds&lt;&#x2F;em&gt; of &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;\log \frac{\Pr{e}}{1 - \Pr{e}}&lt;&#x2F;span&gt;. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Log_probability&quot;&gt;&lt;em&gt;log-probability&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; of &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;\log \Pr e&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Odds_ratio https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Risk_ratio Values from here &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Odds_ratio#Numerical_example&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Odds_ratio#Numerical_example&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Odds_ratio#See_also&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Odds_ratio#See_also&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Category:Summary_statistics_for_contingency_tables&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Category:Summary_statistics_for_contingency_tables&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a basis &lt;span class=&quot;math math-inline&quot;&gt;b \in \R&lt;&#x2F;span&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Information_content&quot;&gt;&lt;em&gt;information content&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\operatorname I :Σ → \R ∪ \set{+∞}&lt;&#x2F;span&gt; is a measure on &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ)&lt;&#x2F;span&gt; defined by&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname I \p e ≜ - \log_b \Pr e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The information content is also called &lt;em&gt;self-information&lt;&#x2F;em&gt;, &lt;em&gt;surprisal&lt;&#x2F;em&gt; or &lt;em&gt;Shannon information&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; For basis &lt;span class=&quot;math math-inline&quot;&gt;b=2&lt;&#x2F;span&gt; the units of &lt;span class=&quot;math math-inline&quot;&gt;\operatorname I&lt;&#x2F;span&gt; are called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bit&quot;&gt;&lt;em&gt;bits&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Shannon_(unit)&quot;&gt;&lt;em&gt;shannons&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, for &lt;span class=&quot;math math-inline&quot;&gt;b=\operatorname e&lt;&#x2F;span&gt; they are called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Nat_(unit)&quot;&gt;&lt;em&gt;nats&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; and for &lt;span class=&quot;math math-inline&quot;&gt;b=10&lt;&#x2F;span&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hartley_(unit)&quot;&gt;&lt;em&gt;hartleys&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. These are collectively &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Units_of_information&quot;&gt;&lt;em&gt;units of information&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. From here on if the basis is not specified it is &lt;span class=&quot;math math-inline&quot;&gt;\operatorname e&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conditional-probability&quot;&gt;Conditional probability&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt;  Given &lt;span class=&quot;math math-inline&quot;&gt;A, B ∈ Σ&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc AB ≜ \frac{\Pr{A ∩ B}}{\Pr B}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Likelihood and such.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (Bayes rule)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc AB = \Prc BA ⋅ \frac{\Pr{A}}{\Pr B}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof&lt;&#x2F;em&gt;. Expand the definition of conditional probability&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\Pr{A ∩ B}}{\Pr B} = \frac{\Pr{B ∩ A}}{\Pr A} ⋅ \frac{\Pr{A}}{\Pr B}
&lt;&#x2F;span&gt;
∎&lt;&#x2F;p&gt;
&lt;h3 id=&quot;independence&quot;&gt;Independence&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt;  Given &lt;span class=&quot;math math-inline&quot;&gt;A, B ∈ Σ&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Independence_(probability_theory)&quot;&gt;&lt;em&gt;independent&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; iff&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{A ∩ B} = \Pr A ⋅ \Pr B
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Brent Nelson. &quot;The Lebesgue Integral&quot;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;math.berkeley.edu&#x2F;~brent&#x2F;files&#x2F;lebesgue_integral.pdf&quot;&gt;pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Quasi Monte Carlo Integration</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/qmc/"/>
        <id>https://2π.com/20/qmc/</id>
        
        <content type="html" xml:base="https://2π.com/20/qmc/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\floor#1{\lfloor{#1}\rfloor}
\gdef\mod#1{[{#1}]}
\gdef\dummyarg{\operatorname{-}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;quasi-monte-carlo-integration&quot;&gt;Quasi Monte Carlo Integration&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; I denote the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Modulo_operation&quot;&gt;modulo operation&lt;&#x2F;a&gt; with &lt;span class=&quot;math math-inline&quot;&gt;[\dummyarg]_n&lt;&#x2F;span&gt;. In particular &lt;span class=&quot;math math-inline&quot;&gt;[\dummyarg]_1&lt;&#x2F;span&gt; is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fractional_part&quot;&gt;fractional part&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mod{a}_b ≜ a - b ⋅ \floor{\frac a b}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;roberts-sequence&quot;&gt;Roberts sequence&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; The &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;-dimensional &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;extremelearning.com.au&#x2F;unreasonable-effectiveness-of-quasirandom-sequences&#x2F;&quot;&gt;Roberts sequence&lt;&#x2F;a&gt; is a particularly elegant &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Low-discrepancy_sequence&quot;&gt;low-discrepancy sequence&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\vec x_i &amp;amp;≜ \mod{i ⋅ \vec ϕ_d}_1 &amp;amp;
\vec ϕ_d &amp;amp;≜
\begin{bmatrix}
ϕ_d \\\\ ϕ_d^2 \\\\ \vdots \\\\ ϕ_d^d
\end{bmatrix}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;ϕ_d&lt;&#x2F;span&gt; is the unique positive root of &lt;span class=&quot;math math-inline&quot;&gt;x^{d+1} + x^d - 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mod{\dummyarg}_1&lt;&#x2F;span&gt; is taken element wise over vectors.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The root will be in &lt;span class=&quot;math math-inline&quot;&gt;(\frac 12, 1)&lt;&#x2F;span&gt;. Closed form solutions for &lt;span class=&quot;math math-inline&quot;&gt;ϕ_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;ϕ_2&lt;&#x2F;span&gt; are the reciprocals of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Golden_ratio&quot;&gt;golden ratio&lt;&#x2F;a&gt; and the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Plastic_number&quot;&gt;plastic number&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
ϕ_1 &amp;amp;= \frac{\sqrt{5} - 1}{2}
&amp;amp;
ϕ_2 &amp;amp;=
    \sqrt[3]{\frac{25 + \sqrt{207}}{54}} +
    \sqrt[3]{\frac{25 - \sqrt{207}}{54}}
    -\frac 1 3
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In Roberts&#x27; notes the &lt;span class=&quot;math math-inline&quot;&gt;ϕ_d&lt;&#x2F;span&gt; is defined in reciprocal form compared to here. These definitions are algebraically identical.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; A procedure to compute the nearest odd number &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;ϕ_d^j ⋅ 2^{64}&lt;&#x2F;span&gt;, this number will iterate through all &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt; numbers and can be implemented with a single overflowing multiplication or iterated addition:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
n_i &amp;amp;= \mod{i ⋅ k}\_{2^{64}} &amp;amp;
n_{i + 1} &amp;amp;= \mod{n_i + k}_{2^{64}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;to-do&quot;&gt;To do&lt;&#x2F;h2&gt;
&lt;p&gt;Does this work for rendering too?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~kmcrane&#x2F;Projects&#x2F;MonteCarloGeometryProcessing&#x2F;paper.pdf&quot;&gt;https:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~kmcrane&#x2F;Projects&#x2F;MonteCarloGeometryProcessing&#x2F;paper.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;http:&#x2F;&#x2F;extremelearning.com.au&#x2F;unreasonable-effectiveness-of-quasirandom-sequences&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=17873284&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;statweb.stanford.edu&#x2F;~owen&#x2F;mc&#x2F;Ch-quadrature.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;statweb.stanford.edu&#x2F;~owen&#x2F;mc&#x2F;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Random variables</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/random-variables/"/>
        <id>https://2π.com/20/random-variables/</id>
        
        <content type="html" xml:base="https://2π.com/20/random-variables/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\R{\mathbb{R}}
\gdef\C{\mathbb{C}}
\gdef\p#1{({#1})}
\gdef\set#1{\mathcal{#1}}
\gdef\setb#1#2{\{{#1} \mid {#2}\}}
\gdef\dummyarg{\operatorname{-}}
\gdef\d{\operatorname{d}\!}
\gdef\Pr#1{\operatorname{Pr}\p{#1}}
\gdef\Prs#1#2{\operatorname{Pr}_{#1}\p{#2}}
\gdef\Prc#1#2{\operatorname{Pr}({#1} \mid {#2})}
\gdef\E#1{\operatorname{E}[{#1}]}
\gdef\Es#1#2{\operatorname{E}_{#1}{#2}}
\gdef\Var#1{\operatorname{Var}\p{#1}}
\gdef\Vars#1#2{\operatorname{Var}_{#1}\p{#2}}
\gdef\Cov#1{\operatorname{Cov}\p{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;random-variables&quot;&gt;Random variables&lt;&#x2F;h1&gt;
&lt;p&gt;For the length of this chapter, assume we are give a probability space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, \operatorname{Pr})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a measurable space &lt;span class=&quot;math math-inline&quot;&gt;(Ω_X, Σ_X)&lt;&#x2F;span&gt;, a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Random_variable&quot;&gt;&lt;em&gt;random variable&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is a measurable function &lt;span class=&quot;math math-inline&quot;&gt;X: Ω → Ω_X&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The space &lt;span class=&quot;math math-inline&quot;&gt;(Ω_X, Σ_X)&lt;&#x2F;span&gt; is called the &lt;em&gt;observation space&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; The pushforward measure &lt;span class=&quot;math math-inline&quot;&gt;X_* \operatorname{Pr}&lt;&#x2F;span&gt; is denoted as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{Pr}_X ≜ X_* \operatorname{Pr}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; The measure &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{Pr}_X&lt;&#x2F;span&gt; is a probability measure and &lt;span class=&quot;math math-inline&quot;&gt;(Ω_X, Σ_X, \operatorname{Pr}_X)&lt;&#x2F;span&gt; is a probability space.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Later, we will use &lt;span class=&quot;math math-inline&quot;&gt;\Es X ⋅&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\Vars X ⋅&lt;&#x2F;span&gt;, etc. to denote expect value and other operators in the &lt;span class=&quot;math math-inline&quot;&gt;(Ω_X, Σ_X, \operatorname{Pr}_X)&lt;&#x2F;span&gt; probability space.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; For any &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Predicate_(mathematical_logic)&quot;&gt;predicate&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;P: E → \set{⊤,⊥}&lt;&#x2F;span&gt; we define the set&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P\p{X} ≜ \setb{ω \in Ω}{P\p{X\p{ω}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; It is not a-priory known if &lt;span class=&quot;math math-inline&quot;&gt;P\p{X} ∈ F&lt;&#x2F;span&gt;. To solve this we can assume that &lt;span class=&quot;math math-inline&quot;&gt;F&lt;&#x2F;span&gt; is constructed from &lt;span class=&quot;math math-inline&quot;&gt;Ω&lt;&#x2F;span&gt; in a &#x27;standard manner&#x27; such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Borel_set&quot;&gt;Borel sets&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{B}\p{\dummyarg}&lt;&#x2F;span&gt;. To avoid going deep into measure theory, let&#x27;s take the informal hand wavy assumption that any &#x27;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pathological_(mathematics)#Well-behaved&quot;&gt;well-behaved&lt;&#x2F;a&gt; set&#x27; is member of &lt;span class=&quot;math math-inline&quot;&gt;F&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; Consider the predicate &lt;span class=&quot;math math-inline&quot;&gt;X = x&lt;&#x2F;span&gt;, we can now derive&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{X = x} = \Pr{ \setb{ω ∈Ω}{X\p{ω} = x}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;real-valued-random-variables&quot;&gt;Real-valued random variables&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; A &lt;em&gt;real-valued random variable&lt;&#x2F;em&gt; is a random variable &lt;span class=&quot;math math-inline&quot;&gt;X: Ω → \R&lt;&#x2F;span&gt; measurable on the obervation space &lt;span class=&quot;math math-inline&quot;&gt;(\R, \mathcal{B}\p{\R})&lt;&#x2F;span&gt;, i.e. the real numbers with a Borel σ-algebra.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Again, to avoid less insightful digressions into measure theory, I will skip the measurability requirement from here on. You can safely assume that any practical function &lt;span class=&quot;math math-inline&quot;&gt;X:Ω → \R&lt;&#x2F;span&gt; is a real-valued random variable. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Measurable_function#Non-measurable_functions&quot;&gt;Non-measurable real-valued functions&lt;&#x2F;a&gt; are very rare in practice and tend to be very pathological. In fact, even the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dirichlet_function&quot;&gt;Dirichlet function&lt;&#x2F;a&gt; (the rational indicator function) is measurable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Generalize this to &lt;span class=&quot;math math-inline&quot;&gt;\C&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\R^n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\C^n&lt;&#x2F;span&gt;, ...&lt;&#x2F;p&gt;
&lt;h3 id=&quot;expected-value&quot;&gt;Expected value&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a random variable &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt;, it&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Expected_value&quot;&gt;&lt;em&gt;expected value&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\E X ≜ \int_Ω X\p{ω} \d \Pr{ω}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Entropy_(information_theory) https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mutual_information&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; The expected value is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Linear_map&quot;&gt;&lt;em&gt;linear map&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, i.e. &lt;span class=&quot;math math-inline&quot;&gt;\E{X + Y} = \E{X} + \E{Y}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\E{a ⋅ X} = a ⋅ \E{X}&lt;&#x2F;span&gt;.
If &lt;span class=&quot;math math-inline&quot;&gt;X ≤ Y&lt;&#x2F;span&gt; almost surely and &lt;span class=&quot;math math-inline&quot;&gt;\E{X}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\E{Y}&lt;&#x2F;span&gt; exist, then &lt;span class=&quot;math math-inline&quot;&gt;\E{X} ≤ \E{Y}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; (Jensen&#x27;s inequality) Given a random variable &lt;span class=&quot;math math-inline&quot;&gt;X: Ω → \R&lt;&#x2F;span&gt; and a convex function &lt;span class=&quot;math math-inline&quot;&gt;f:\R → \R&lt;&#x2F;span&gt;, then:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f\p{\E{X}} ≤ \E{f\p{X}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Proof.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Mean. Skewness. Kurtosis. Moments. Cumulants. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Moment_(mathematics)&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Moment_(mathematics)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;variance&quot;&gt;Variance&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a random variable &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt;, it&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Variance&quot;&gt;&lt;em&gt;variance&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Var X ≜ \E{\p{X - \E X}^2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\Var X = \E{X^2} - \E{X}^2&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;covariance&quot;&gt;Covariance&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given random variables &lt;span class=&quot;math math-inline&quot;&gt;X, Y&lt;&#x2F;span&gt;, their &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Covariance&quot;&gt;&lt;em&gt;covariance&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Cov{X, Y} ≜ \E{\p{X - \E X} ⋅ \p{Y - \E Y}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\Cov{X,Y} = \E{X⋅Y} - \E X ⋅ \E Y&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;\Cov{X,X} = \Var X&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;probability-density-function&quot;&gt;Probability density function&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given random variables &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; with values in measure space &lt;span class=&quot;math math-inline&quot;&gt;(Ω_X, Σ_X, μ)&lt;&#x2F;span&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Probability_density_function&quot;&gt;&lt;em&gt;probability density&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; of &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; with respect to &lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt; is the Radon-Nikodym derivative&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p_X ≜ \frac{\d \operatorname{Pr}_X}{\d μ}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; By definition &lt;span class=&quot;math math-inline&quot;&gt;p_X&lt;&#x2F;span&gt; satisfies&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\forall_{Σ_X}^A\ \Pr{X \in A} = \int_{X^{-1}\p{A}} \d \Pr{ω} = \int_A \d \Prs{X}{x} = \int_A p_X(x) \d μ(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; For a continuous random variable the reference measure &lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt; would be the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lebesgue_measure&quot;&gt;Lebesgue measure&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; For a discrete random variable the reference measure &lt;span class=&quot;math math-inline&quot;&gt;μ&lt;&#x2F;span&gt; would be the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Counting_measure&quot;&gt;counting measure&lt;&#x2F;a&gt; and &lt;span class=&quot;math math-inline&quot;&gt;p_X&lt;&#x2F;span&gt; becomes a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Probability_mass_function&quot;&gt;probability mass function&lt;&#x2F;a&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{X = b} = \Pr{X^{-1}\p{\set{b}}} = \int_{X^{-1}\p{\set{b}}} \d \Pr{ω} = \int_{\set{b}} p_X(x) \d μ\p{x} = p_X(b)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; How does this work for probability spaces that are neither discrete nor continuous, for example a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fock_space&quot;&gt;Fock space&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;Exponential family&lt;&#x2F;em&gt; (&lt;strong&gt;to do.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exponential_family#Table_of_distributions&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exponential_family#Table_of_distributions&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{X = \vec x}{\vec θ}  = h(x) ⋅ \exp\p{\vec \eta(\vec θ) ⋅ \vec T(\vec x) - A(\vec θ)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The natural family&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{X = \vec x}{\vec θ}  = h(x) ⋅ \exp\p{\vec θ ⋅ \vec x - A(\vec θ)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Probability distributions like Uniform and Normal.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;ermongroup.github.io&#x2F;cs228-notes&#x2F;representation&#x2F;directed&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;www.randomservices.org&#x2F;random&#x2F;dist&#x2F;Mixed.html&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scoring_rule https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Loss_function https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Regret_(decision_theory)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Regression</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/regression/"/>
        <id>https://2π.com/20/regression/</id>
        
        <content type="html" xml:base="https://2π.com/20/regression/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\R{\mathbb{R}}
\gdef\C{\mathbb{C}}
\gdef\p#1{({#1})}
\gdef\norm#1{\lVert{#1}\rVert}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;regression&quot;&gt;Regression&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph BT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph BT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GENRLS[Generalized Elastic-net-regularized least squares];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ENRLS[Elastic-net-regularized least squares]--&amp;gt;GENRLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    LASSO[Lasso regression]--&amp;gt;ENRLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GRLS[Generalized Tikhonov-regularized least squares]--&amp;gt;GENRLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    LR[Lavrentyev-regularized regularization]--&amp;gt;GRLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    RLS[Tikhonov-regularized least squares]--&amp;gt;ENRLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    RLS--&amp;gt;GRLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GLS[Generalized Least Squares]--&amp;gt;RLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    WLS[Weighted Least Squares]--&amp;gt;GLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    OLS[Ordinary Least Squares]--&amp;gt;WLS;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Fahrplan:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Present &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Regression_analysis&quot;&gt;regressions&lt;&#x2F;a&gt; as unintepreted mathematical constructions.&lt;&#x2F;li&gt;
&lt;li&gt;Present &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Estimation_theory&quot;&gt;parameter estimation&lt;&#x2F;a&gt; models and show how certain regressions solve them (Gauss-Markov-Aitken theorem).&lt;&#x2F;li&gt;
&lt;li&gt;Present &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Forecasting&quot;&gt;forecasting&lt;&#x2F;a&gt; models and show how to solve them.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;ryxcommar.com&#x2F;2019&#x2F;07&#x2F;14&#x2F;on-moving-from-statistics-to-machine-learning-the-final-stage-of-grief&#x2F;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;linear-regression&quot;&gt;Linear regression&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given an input set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal X&lt;&#x2F;span&gt; and an input vector &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ {\mathcal X}^n&lt;&#x2F;span&gt; and a set of &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Basis_function&quot;&gt;basis functions&lt;&#x2F;a&gt; &lt;span class=&quot;math math-inline&quot;&gt;f_i : \mathcal X → \R&lt;&#x2F;span&gt;, a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Linear_regression&quot;&gt;linear regression model&lt;&#x2F;a&gt; is the relation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec y = X(\vec x) ⋅ \vec b + \vec e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X(\vec x) ≜ \begin{bmatrix}
f_0(x_0) &amp;amp; f_1(x_0) &amp;amp; f_2(x_0) &amp;amp; ⋯ &amp;amp; f_m(x_0) \\
f_0(x_1) &amp;amp; f_1(x_1) &amp;amp; f_2(x_1) &amp;amp; ⋯ &amp;amp; f_m(x_1) \\
f_0(x_2) &amp;amp; f_1(x_2) &amp;amp; f_2(x_2) &amp;amp; ⋯ &amp;amp; f_m(x_2) \\
⋮ &amp;amp; ⋮ &amp;amp; ⋮ &amp;amp; ⋱ &amp;amp; ⋮ \\
f_0(x_n) &amp;amp; f_1(x_n) &amp;amp; f_2(x_n) &amp;amp; ⋯ &amp;amp; f_m(x_n) \\
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The generalization where the output space is higher dimensional &lt;span class=&quot;math math-inline&quot;&gt;\vec y ∈ \R^{n \times d}&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;f_i : \mathcal X → \R^d&lt;&#x2F;span&gt; is really just a special case where we treat each component as a separate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The matrix &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; is called the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Design_matrix&quot;&gt;&lt;em&gt;design matrix&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;em&gt;model matrix&lt;&#x2F;em&gt; or &lt;em&gt;regressor matrix&lt;&#x2F;em&gt;. The vector &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; is called the &lt;em&gt;response vector&lt;&#x2F;em&gt; or &lt;em&gt;dependent variable&lt;&#x2F;em&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; is called the &lt;em&gt;parameter vector&lt;&#x2F;em&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec e&lt;&#x2F;span&gt; is called the &lt;em&gt;error vector&lt;&#x2F;em&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; is called the &lt;em&gt;independent variable&lt;&#x2F;em&gt;, &lt;em&gt;predictor variable&lt;&#x2F;em&gt;, &lt;em&gt;regressor&lt;&#x2F;em&gt;, &lt;em&gt;covariate&lt;&#x2F;em&gt;, &lt;em&gt;explanatory variable&lt;&#x2F;em&gt;, &lt;em&gt;control variable&lt;&#x2F;em&gt; and in the context &lt;em&gt;exposure variable&lt;&#x2F;em&gt;, &lt;em&gt;risk factor&lt;&#x2F;em&gt;, &lt;em&gt;feature&lt;&#x2F;em&gt; or &lt;em&gt;input variable&lt;&#x2F;em&gt;. (See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dependent_and_independent_variables#Statistics_synonyms&quot;&gt;this overview&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; Can this be generalized from &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;\C&lt;&#x2F;span&gt; or arbitrary vector spaces? Are there even normed vector spaces not &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;\C&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Simple_linear_regression&quot;&gt;Simple least squares&lt;&#x2F;a&gt; is the special case with &lt;span class=&quot;math math-inline&quot;&gt;\mathcal X = \R&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;m = 2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;f_0(x) = 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f_1(x) = x&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ordinary_least_squares&quot;&gt;Ordinary least squares&lt;&#x2F;a&gt; is the special case with &lt;span class=&quot;math math-inline&quot;&gt;\mathcal X = \R^p&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;m = p + 1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;f_i(\vec x) = x_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f_p(\vec x) = 1&lt;&#x2F;span&gt;. In rare cases the &lt;span class=&quot;math math-inline&quot;&gt;f_p&lt;&#x2F;span&gt; can be left out.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_regression&quot;&gt;Polynomial regression&lt;&#x2F;a&gt; is the special case with &lt;span class=&quot;math math-inline&quot;&gt;\mathcal X = \R&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f_i(x) = x^i&lt;&#x2F;span&gt;. In this case the design matrix is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vandermonde_matrix&quot;&gt;Vandermonde matrix&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In ordinary least squares it is common to include a constant intercept by setting &lt;span class=&quot;math math-inline&quot;&gt;x_{0i} = 1&lt;&#x2F;span&gt;. Equivalently, a basis function &lt;span class=&quot;math math-inline&quot;&gt;f_{p}(\vec x) = 1&lt;&#x2F;span&gt; can be used. In either case, the coefficient associated with the constant function is called the &lt;em&gt;intercept&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; More special cases of the design matrix: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;ANOVA&quot;&gt;ANOVA&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Analysis_of_covariance&quot;&gt;ANCOVA&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Multivariate_analysis_of_covariance&quot;&gt;MANCOVA&lt;&#x2F;a&gt;, Linear regression, polynomial regression,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Goodness_of_fit&quot;&gt;&lt;em&gt;Goodness of fit&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; metrics such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Coefficient_of_determination&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;R^2&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Coefficient_of_determination#Adjusted_R2&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;\bar{R}^2&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;, Log-likelihood, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Durbin%E2%80%93Watson_statistic&quot;&gt;Durbin-Watson statistic&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Akaike_information_criterion&quot;&gt;Akaike criterion&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Schwarz_criterion&quot;&gt;Schwarz criterion&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;F-test&quot;&gt;F-test&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Wilks%27s_lambda_distribution&quot;&gt;Wilks&#x27;s Lambda&lt;&#x2F;a&gt;. (See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ordinary_least_squares#Example_with_real_data&quot;&gt;here&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Discuss other methods like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Total_least_squares&quot;&gt;total least squares&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Errors-in-variables_models&quot;&gt;Errors-in-variables&lt;&#x2F;a&gt; models, modelling uncertainty in &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Discuss other goals like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Least_absolute_deviations&quot;&gt;&lt;em&gt;least absolute deviations&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Median_absolute_deviation&quot;&gt;&lt;em&gt;median absolute deviation&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mean_absolute_difference#Relative_mean_absolute_difference&quot;&gt;&lt;em&gt;relative mean absolute difference&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Average_absolute_deviation&quot;&gt;&lt;em&gt;mean absolute deviation&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Minimax_approximation_algorithm&quot;&gt;&lt;em&gt;minimum maximal deviation&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lasso_(statistics)&quot;&gt;&lt;em&gt;Lasso regression&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Basis_pursuit_denoising&quot;&gt;Basis pursuit denoising&lt;&#x2F;a&gt;. See also &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Regularization_(mathematics)#Other_uses_of_regularization_in_statistics_and_machine_learning&quot;&gt;here&lt;&#x2F;a&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Iteratively_reweighted_least_squares&quot;&gt;Iteratively reweighted least squares&lt;&#x2F;a&gt; can solve goals that are &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;-norms.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;generalized-tikhonov-regularized-least-squares&quot;&gt;Generalized Tikhonov-regularized least squares&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a linear regression model, parameter mean &lt;span class=&quot;math math-inline&quot;&gt;{\vec b}_0 ∈ \R^m&lt;&#x2F;span&gt;, and a covariance matrices &lt;span class=&quot;math math-inline&quot;&gt;K_e ∈ \R^{n × n}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;K_b ∈ \R^{m × m}&lt;&#x2F;span&gt;, the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tikhonov_regularization#Generalized_Tikhonov_regularization&quot;&gt;Generalized Tikhonov-regularized least squares&lt;&#x2F;a&gt; estimator &lt;span class=&quot;math math-inline&quot;&gt;\hat{\vec b}&lt;&#x2F;span&gt; is the value of &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; that minimizes the combined Mahalanobis norm of the residual vector &lt;span class=&quot;math math-inline&quot;&gt;\vec e&lt;&#x2F;span&gt; and the parameter vector &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{\vec b} ≜ \arg\min_{\vec b} \norm{\vec y - X ⋅ \vec b}_{K_e}^2 + \norm{\vec b - {\vec b}_0}_{K_b}^2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The special case where &lt;span class=&quot;math math-inline&quot;&gt;K_b = \lambda I&lt;&#x2F;span&gt; is the (non-generalized) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tikhonov_regularization&quot;&gt;&lt;em&gt;Tikhonov regression&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; and also know as &lt;em&gt;Ridge regression&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;In statistics, the method is known as ridge regression, in machine learning it is known as weight decay, and with multiple independent discoveries, it is also variously known as the Tikhonov–Miller method, the Phillips–Twomey method, the constrained linear inversion method, and the method of linear regularization. It is related to the Levenberg–Marquardt algorithm for non-linear least-squares problems.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The special case where &lt;span class=&quot;math math-inline&quot;&gt;K_e = X&lt;&#x2F;span&gt; is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tikhonov_regularization#Lavrentyev_regularization&quot;&gt;&lt;em&gt;Lavrentyev regularization&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The special case where &lt;span class=&quot;math math-inline&quot;&gt;K_b = 0&lt;&#x2F;span&gt; is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Generalized_least_squares&quot;&gt;generalized least squares&lt;&#x2F;a&gt;. The generalized least squares is unbiased in &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;, but can ill-conditioned.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The special case where &lt;span class=&quot;math math-inline&quot;&gt;K_b = 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;K_e = \operatorname{diag}(\vec w)&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ordinary_least_squares&quot;&gt;weighted least squares&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The special case where &lt;span class=&quot;math math-inline&quot;&gt;K_b = 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;K_e = I&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ordinary_least_squares&quot;&gt;ordinary least squares&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The matrices &lt;span class=&quot;math math-inline&quot;&gt;X^T ⋅ \vec y&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;X^T ⋅ X&lt;&#x2F;span&gt; are &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Moment_matrix&quot;&gt;&lt;em&gt;moment matrix&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; The generalized Tikhonov-regularized least squares estimator has a closed form solution&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{\vec b} = \p{X^T ⋅ {K_e}^{-1} ⋅ X + K_{b}}^{-1} ⋅ \p{X^T ⋅ {K_e}^{-1} ⋅ \vec y + K_b ⋅ {\vec b}_0}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Proof by derivation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Derive expected value and variance of &lt;span class=&quot;math math-inline&quot;&gt;\hat{\vec b}&lt;&#x2F;span&gt; like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;statweb.stanford.edu&#x2F;~tibs&#x2F;sta305files&#x2F;Rudyregularization.pdf&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Algorithm.&lt;&#x2F;strong&gt; While the closed form solution can be used directly, it is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Numerical_stability&quot;&gt;numerically unstable&lt;&#x2F;a&gt;. A more stable algorithm is the following: First, the problem is reduced to a generalized least squares regression&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\hat{\vec b} &amp;amp;= \arg\min_{\vec b} \norm{
    \begin{bmatrix} \vec y \\ {\vec b}_0 \end{bmatrix} -
    \begin{bmatrix} X\p{\vec x}  \\ I \end{bmatrix} ⋅ \vec b
}_K
&amp;amp;
K &amp;amp;≜ \begin{bmatrix} K_e &amp;amp; 0 \\ 0 &amp;amp; K_b \end{bmatrix}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which is then reduced to an ordinary least squares using a whitening transform with &lt;span class=&quot;math math-inline&quot;&gt;W^*W = K^{-1}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{\vec b} ≜ \arg\min_{\vec b} \norm{
    W ⋅
    \begin{bmatrix} \vec y \\ {\vec b}_0 \end{bmatrix} -
    W ⋅
    \begin{bmatrix} X\p{\vec x} \\ I \end{bmatrix} ⋅ \vec b
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Finally, this is solved using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Moore%E2%80%93Penrose_inverse&quot;&gt;&lt;em&gt;Moore-Penrose inverse&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; computed using SVD.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; least_squares&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; X&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b_0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; X&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shape&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # Ordinary least squares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;eye&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,):&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; # Weighted least squares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;diag&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python z-keyword z-operator z-logical z-python&quot;&gt;    if not&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;isscalar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;ones&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;diag&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b_0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; None&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;            b_0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;        assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b_0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        # Reduce Tikhonov-regularization to generalized least squares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;concatenate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b_0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;eye&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)]])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            [&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; K_b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # Reduce generalized to ordinary least squares&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    W&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; whitening_transform&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;K_e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;matmul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;W&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    X&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;matmul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;W&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; X&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # Solve OLS using Moore-Penrose inverse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;matmul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;linalg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;pinv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;X&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;least-angle-regression&quot;&gt;Least Angle Regression&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a linear regression model, parameter mean &lt;span class=&quot;math math-inline&quot;&gt;{\vec b}_0 ∈ \R^m&lt;&#x2F;span&gt;, and a covariance matrices &lt;span class=&quot;math math-inline&quot;&gt;K_e ∈ \R^{n × n}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;K_b ∈ \R^{m × m}&lt;&#x2F;span&gt;, the Generalized Thikononv-Lasso estimator &lt;span class=&quot;math math-inline&quot;&gt;\hat{\vec b}&lt;&#x2F;span&gt; is the value of &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; that minimizes the combined Mahalanobis norm of the residual vector &lt;span class=&quot;math math-inline&quot;&gt;\vec e&lt;&#x2F;span&gt; and the parameter vector &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{\vec b} ≜ \arg\min_{\vec b}
 \norm{\vec y - X ⋅ \vec b}_{K_e}^2 +
 \norm{\vec b - {\vec b}_0}_{K_b}^2 +
 \norm{\vec b - {\vec b}_0}_{1,K_b&amp;#39;}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Elastic_net_regularization&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; The generalized Lasso problem and the LARS(Lasso) solution from Algorithm 3.2a in &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;regression&#x2F;#HTF09&quot;&gt;HTF09&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Least-angle_regression&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Equivalence to support vector machines and the efficient solving algorithms employed there.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gauss-markov-aitken-theorem&quot;&gt;Gauss-Markov-Aitken Theorem&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; This does not generalize to higher dimensions without the additional constraint that the estimator is unbiased. See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stein%27s_example&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stein%27s_example&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;James%E2%80%93Stein_estimator&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;James%E2%80%93Stein_estimator&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gauss%E2%80%93Markov_theorem#Generalized_least_squares_estimator&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Best_linear_unbiased_prediction&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Minimum_mean_square_error&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bayesian_interpretation_of_kernel_regularization https:&#x2F;&#x2F;stats.stackexchange.com&#x2F;questions&#x2F;163388&#x2F;why-is-the-l2-regularization-equivalent-to-gaussian-prior&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Generalized-Tikhonov has multinormal prior on &lt;span class=&quot;math math-inline&quot;&gt;\hat{\vec b}&lt;&#x2F;span&gt;. Lasso has Laplacian prior.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;general-linear-model&quot;&gt;General linear model&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;General_linear_model&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Y = X ⋅ B + U
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mixed-model&quot;&gt;Mixed model&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mixed_model&lt;&#x2F;p&gt;
&lt;h2 id=&quot;non-linear-regression-model&quot;&gt;Non-linear regression model&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given an input set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal X&lt;&#x2F;span&gt;, parameter set &lt;span class=&quot;math math-inline&quot;&gt;\mathcal B&lt;&#x2F;span&gt;, input vector &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ {\mathcal X}^n&lt;&#x2F;span&gt; and model function &lt;span class=&quot;math math-inline&quot;&gt;f : \mathcal X \times \mathcal B → \R&lt;&#x2F;span&gt;, a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Nonlinear_regression&quot;&gt;nonlinear regression model&lt;&#x2F;a&gt; is the relation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
y_i = f(x_i, b) + e_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;for some &lt;span class=&quot;math math-inline&quot;&gt;b ∈ \mathcal B&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nonlinear-least-squares&quot;&gt;Nonlinear least squares&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Nonlinear least squares https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Non-linear_least_squares&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{\vec b} ≜ \arg\min_{b} \norm{\vec e}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;No closed form solution. Can be solved using global optimizers. Depending on &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; a gradient may be available.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Algorithm.&lt;&#x2F;strong&gt; One method for solving is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Levenberg%E2%80%93Marquardt_algorithm&quot;&gt;Levenberg–Marquardt algorithm&lt;&#x2F;a&gt;. Special cases are the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gauss%E2%80%93Newton_algorithm&quot;&gt;Gauss-Newton algorithm&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gradient_descent&quot;&gt;gradient descent&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Extend to norms other than Euclidean.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;partial-least-squares&quot;&gt;Partial least squares&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Partial_least_squares_regression&lt;&#x2F;p&gt;
&lt;h3 id=&quot;principal-component-regression&quot;&gt;Principal component regression&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Principal_component_analysis&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Principal_component_regression&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rational-function-regression&quot;&gt;Rational function regression&lt;&#x2F;h3&gt;
&lt;p&gt;Initiate the optimization problem using a good seed value provided by solving the linear model &lt;span class=&quot;math math-inline&quot;&gt;p(x) - q(x) y&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec y = \p{P(\vec x) ⋅ \vec b_p} ⊘ \p{Q(\vec x)⋅ \vec b_q} + \vec e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;⊘&lt;&#x2F;span&gt; is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hadamard_product_(matrices)#Analogous_operations&quot;&gt;Hadamard division&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{Q ⋅ \vec b_q} ⊙ \vec y = P ⋅ \vec b_p + \p{Q ⋅ \vec b_q} ⊙ \vec e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{diag} \p{Q ⋅ \vec b_q} ⋅ \vec y = P ⋅ \vec b_p + \operatorname{diag} \p{Q ⋅ \vec b_q} ⋅ \vec e
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\operatorname{diag} \p{Q ⋅ \vec b_q} ⋅ \vec e = \operatorname{diag} \p{Q ⋅ \vec b_q} ⋅ \vec y - P ⋅ \vec b_p
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec e = \operatorname{diag} \p{Q ⋅ \vec b_q}^{-1} ⋅ \p {\operatorname{diag} \p{Q ⋅ \vec b_q} ⋅ \vec y - P ⋅ \vec b_p }
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec e = \vec y - \operatorname{diag} \p{Q ⋅ \vec b_q}^{-1} ⋅ P ⋅ \vec b_p
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat{\vec b} ≜ \arg\min_{\vec b} \norm{\vec e}_Ω
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;universal-kriging&quot;&gt;Universal Kriging&lt;&#x2F;h2&gt;
&lt;p&gt;http:&#x2F;&#x2F;www.kgs.ku.edu&#x2F;Conferences&#x2F;IAMG&#x2F;&#x2F;Sessions&#x2F;D&#x2F;Papers&#x2F;boogaart.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.nersc.no&#x2F;sites&#x2F;www.nersc.no&#x2F;files&#x2F;Basics2kriging.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Regression-kriging&lt;&#x2F;p&gt;
&lt;p&gt;Special case: Gaussian-Process-Regression&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;people.cs.umass.edu&#x2F;~wallach&#x2F;talks&#x2F;gp_intro.pdf&lt;&#x2F;p&gt;
&lt;p&gt;http:&#x2F;&#x2F;www.gaussianprocess.org&#x2F;gpml&#x2F;chapters&#x2F;RW2.pdf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rational-regression-kriging&quot;&gt;Rational Regression Kriging&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; Find the best fit Rational-Kriging model for a &lt;span class=&quot;math math-inline&quot;&gt;\R^m → \R^n&lt;&#x2F;span&gt; function given samples from &lt;span class=&quot;math math-inline&quot;&gt;\R^m × \R^n&lt;&#x2F;span&gt; .&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec F(\vec x) = \vec m(\vec x) + \vec \epsilon&amp;#39;(\vec x) + \vec \epsilon&amp;#39;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\vec m&lt;&#x2F;span&gt; is rational function and &lt;span class=&quot;math math-inline&quot;&gt;\epsilon&amp;#39;&lt;&#x2F;span&gt; is a Gaussian process and &lt;span class=&quot;math math-inline&quot;&gt;\vec \epsilon&amp;#39;&amp;#39;&lt;&#x2F;span&gt; are normally distributed residual errors.&lt;&#x2F;p&gt;
&lt;p&gt;The hyper-parameters of the model are the numerator and denominator degree of the rational function, the covariance kernel of the Gaussian process and the variance of the residual errors.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Regression-kriging&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Generalized_least_squares&lt;&#x2F;p&gt;
&lt;p&gt;Rational trend model&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_regression&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_and_rational_function_modeling&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; What if we have uncertainty in &lt;span class=&quot;math math-inline&quot;&gt;\vec x&lt;&#x2F;span&gt; like we have in &lt;span class=&quot;math math-inline&quot;&gt;\vec y&lt;&#x2F;span&gt; through &lt;span class=&quot;math math-inline&quot;&gt;\vec \epsilon&amp;#39;&amp;#39;&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Can we add gradients to the input values like in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gradient-enhanced_kriging&quot;&gt;Gradient-enhanced kriging&lt;&#x2F;a&gt; ?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hal-emse.ccsd.cnrs.fr&#x2F;emse-01525674&#x2F;file&#x2F;paperHAL.pdf&quot;&gt;https:&#x2F;&#x2F;hal-emse.ccsd.cnrs.fr&#x2F;emse-01525674&#x2F;file&#x2F;paperHAL.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; The polynomial and rational &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Equioscillation_theorem&quot;&gt;&lt;em&gt;Equioscillation Theorem&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;&#x2F;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gradient-enhanced-krigin&quot;&gt;Gradient Enhanced Krigin&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gradient-enhanced_kriging&lt;&#x2F;p&gt;
&lt;h2 id=&quot;support-vector-machines&quot;&gt;Support Vector Machines&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Support_vector_machine&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bayesian-optimization&quot;&gt;Bayesian Optimization&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=vz3D36VXefI&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1807.02811&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1009.5419&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Markov_decision_process&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;math.stackexchange.com&#x2F;questions&#x2F;924482&#x2F;least-squares-regression-matrix-for-rational-functions&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;ref&quot; name=&quot;HTF09&quot;&gt;&lt;&#x2F;a&gt;
Trevor Hastie, Robert Tibshirani &amp;amp; Jerome Friedman (2009).
“The Elements of Statistical Learning: Data Mining, Inference, and Prediction”.
Available &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.stanford.edu&#x2F;~hastie&#x2F;ElemStatLearn&#x2F;&quot;&gt;online&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;ref&quot; name=&quot;RW06&quot;&gt;&lt;&#x2F;a&gt;
Carl Edward Rasmussen &amp;amp; Christopher K. I. Williams (2006).
“Gaussian Processes for Machine Learning”.
Available &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.gaussianprocess.org&#x2F;gpml&#x2F;&quot;&gt;online&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;https:&#x2F;&#x2F;stats.stackexchange.com&#x2F;questions&#x2F;396914&#x2F;why-is-computing-ridge-regression-with-a-cholesky-decomposition-much-quicker-tha&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.analyticsvidhya.com&#x2F;blog&#x2F;2016&#x2F;01&#x2F;ridge-lasso-regression-python-complete-tutorial&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;statweb.stanford.edu&#x2F;~tibs&#x2F;sta305files&#x2F;Rudyregularization.pdf&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Philippe Rigollet (2016).
“18.650 Statistics for Applications”.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ocw.mit.edu&#x2F;courses&#x2F;mathematics&#x2F;18-650-statistics-for-applications-fall-2016&#x2F;index.htm&quot;&gt;MIT OCW&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1705.02511&quot;&gt;Sung, Hung et al. (2018)&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Stochastic processes</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/stochastic-processes/"/>
        <id>https://2π.com/20/stochastic-processes/</id>
        
        <content type="html" xml:base="https://2π.com/20/stochastic-processes/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\R{\mathbb{R}}
\gdef\p#1{({#1})}
\gdef\dummyarg{\operatorname{-}}
\gdef\Prc#1#2{\operatorname{Pr}({#1} \mid {#2})}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;stochastic-processes&quot;&gt;Stochastic processes&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;graph BT;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SP[Stochastic Process];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GSP[Gaussian Stochastic Process]--&amp;gt;SP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    PP[Point Process]--&amp;gt;SP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    RF[Random Field]--&amp;gt;SP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    MRF[Markov Random Field]--&amp;gt;RF;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    IM[Ising Model]--&amp;gt;MRF;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    CTP[Continuous Time Process]--&amp;gt;RF;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    DTP[Discrete Time Process]--&amp;gt;SP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    MP[Markov Process]--&amp;gt;CTP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    MP[Markov Process]--&amp;gt;MRF;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    MC[Markov Chain]--&amp;gt;DTP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GMP[Gauss-Markov Process]--&amp;gt;GSP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    GMP--&amp;gt;MP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    OUP[Ornstein-Uhlenbeck Process]--&amp;gt;GMP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    PPP[Poisson Point Process]--&amp;gt;PP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    PPP--&amp;gt;MP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    LP[Lévy process]--&amp;gt;MP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    WP[Wiener Process]--&amp;gt;LP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    HP[Hawkes Process]--&amp;gt;PP;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the length of this chapter, assume we are give a probability space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, \operatorname{Pr})&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; Given a probability space &lt;span class=&quot;math math-inline&quot;&gt;(Ω, Σ, \operatorname{Pr})&lt;&#x2F;span&gt;, a measurable space &lt;span class=&quot;math math-inline&quot;&gt;(Ω_X, Σ_X)&lt;&#x2F;span&gt; and a set &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt;,
a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stochastic_process&quot;&gt;&lt;em&gt;stochastic process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; is a function &lt;span class=&quot;math math-inline&quot;&gt;X: T \times Ω  → Ω_X&lt;&#x2F;span&gt; such that for each &lt;span class=&quot;math math-inline&quot;&gt;t ∈ T&lt;&#x2F;span&gt; the restricted function &lt;span class=&quot;math math-inline&quot;&gt;X\p{t, \dummyarg}: Ω  → Ω_X&lt;&#x2F;span&gt; is a random variable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The set &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; is called the &lt;em&gt;index set&lt;&#x2F;em&gt; or &lt;em&gt;parameter set&lt;&#x2F;em&gt; of the stochastic process. The set &lt;span class=&quot;math math-inline&quot;&gt;Ω_X&lt;&#x2F;span&gt; is called the &lt;em&gt;state space&lt;&#x2F;em&gt;. Given &lt;span class=&quot;math math-inline&quot;&gt;ω ∈ Ω&lt;&#x2F;span&gt; the restricted function &lt;span class=&quot;math math-inline&quot;&gt;X\p{\dummyarg, ω}: T  → Ω_X&lt;&#x2F;span&gt; is called a &lt;em&gt;sample function&lt;&#x2F;em&gt;, &lt;em&gt;realization&lt;&#x2F;em&gt;, &lt;em&gt;sample path&lt;&#x2F;em&gt;, &lt;em&gt;trajectory&lt;&#x2F;em&gt;, &lt;em&gt;path function&lt;&#x2F;em&gt;, or &lt;em&gt;path&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Depending on the nature of the index set &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt;, a stochastic process can be called many things:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; If the index set &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Topological_space&quot;&gt;topological space&lt;&#x2F;a&gt; then &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Random_field&quot;&gt;&lt;em&gt;random field&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Nearly all stochastic processes are random fields by definition, but the term is generally reserved for when &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; has more than one dimension.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; If the index set &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; is a countable ordered set then &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Discrete-time_stochastic_process&quot;&gt;&lt;em&gt;discrete-time process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; If the index set &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; is an interval of &lt;span class=&quot;math math-inline&quot;&gt;\R&lt;&#x2F;span&gt; then &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Continuous-time_stochastic_process&quot;&gt;&lt;em&gt;continuous-time process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; If the index set &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; are the vertices of a graph and satisfies &lt;strong&gt;To do.&lt;&#x2F;strong&gt; properties, then &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Markov_random_field&quot;&gt;&lt;em&gt;Markov random field&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Similarly to the above definitions, a stochastic process can also be named based on the state space &lt;span class=&quot;math math-inline&quot;&gt;Ω_X&lt;&#x2F;span&gt;. &lt;em&gt;discrete stochastic process&lt;&#x2F;em&gt;, &lt;em&gt;integer-valued stochastic process&lt;&#x2F;em&gt;, &lt;em&gt;real-valued stochastic process&lt;&#x2F;em&gt;, &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-&lt;em&gt;dimensional vector process&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stationary_process&quot;&gt;&lt;em&gt;Stationary process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Markov_chain&quot;&gt;&lt;em&gt;Markov process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Martingale_(probability_theory)&quot;&gt;&lt;em&gt;Martingale&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;L%C3%A9vy_process&quot;&gt;&lt;em&gt;Lévy process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bernoulli_process&quot;&gt;&lt;em&gt;Bernoulli process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Random_walk&quot;&gt;&lt;em&gt;Random walk&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Wiener_process&quot;&gt;&lt;em&gt;Wiener process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; &lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; Every continuous-time independent-increment process is a Gaussian process. Proof using central limit theorem.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.whoi.edu&#x2F;cms&#x2F;files&#x2F;lecture06_21268.pdf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;point-processes&quot;&gt;Point processes&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Point_process&quot;&gt;&lt;em&gt;Point process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Poisson_point_process&quot;&gt;&lt;em&gt;Poisson point process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Cox_process&quot;&gt;&lt;em&gt;Cox process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Point_process#Hawkes_(self-exciting)_processes&quot;&gt;&lt;em&gt;Hawkes process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1507.02822&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gaussian-processes&quot;&gt;Gaussian processes&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gaussian_process&quot;&gt;&lt;em&gt;Gaussian process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Kernel&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Covariance_function&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cs.toronto.edu&#x2F;~duvenaud&#x2F;cookbook&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{\vec f_*}{\vec x_*, \vec x, \vec y}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Kernel trick.&lt;&#x2F;p&gt;
&lt;p&gt;http:&#x2F;&#x2F;www.gaussianprocess.org&#x2F;gpml&#x2F;chapters&#x2F;RW4.pdf&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gauss%E2%80%93Markov_process&quot;&gt;&lt;em&gt;Gauss-Markov process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mat%C3%A9rn_covariance_function&quot;&gt;&lt;em&gt;Matérn kernel&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Radial_basis_function_kernel&quot;&gt;&lt;em&gt;Squared exponential kernel&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; aka &lt;em&gt;RBF kernel&lt;&#x2F;em&gt;. Special case of Matérn  &lt;span class=&quot;math math-inline&quot;&gt;\nu = \infty&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rational_quadratic_covariance_function&quot;&gt;&lt;em&gt;Rational quadratic kernel&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Ornstein%E2%80%93Uhlenbeck_process&quot;&gt;&lt;em&gt;Ornstein–Uhlenbeck process&lt;&#x2F;em&gt;&lt;&#x2F;a&gt;. Aka absolute exponential. Special case of Matérn with &lt;span class=&quot;math math-inline&quot;&gt;\nu = \frac 12&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gaussian-process-regression&quot;&gt;Gaussian Process Regression&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; (Gaussian process regression)[https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gaussian_process_regression] is also known as &lt;em&gt;Kriging&lt;&#x2F;em&gt; and &lt;em&gt;Wiener–Kolmogorov prediction&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Time Series</title>
        <published>2020-12-08T00:00:00+00:00</published>
        <updated>2020-12-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/time-series/"/>
        <id>https://2π.com/20/time-series/</id>
        
        <content type="html" xml:base="https://2π.com/20/time-series/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{({#1})}
\gdef\Pr#1{\operatorname{Pr}\p{#1}}
\gdef\Prc#1#2{\operatorname{Pr}({#1} \mid {#2})}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;time-series&quot;&gt;Time Series&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dynamic_Bayesian_network&quot;&gt;Dynamic Bayesian Networks&lt;&#x2F;a&gt; are a general class of state-space time series model encompassing as special cases&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Hidden Markov Models&lt;&#x2F;li&gt;
&lt;li&gt;Kalman Filters&lt;&#x2F;li&gt;
&lt;li&gt;ARMA&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;definition&quot;&gt;Definition&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bayesian_network&quot;&gt;Bayesian network&lt;&#x2F;a&gt; is a directed acyclic graph &lt;span class=&quot;math math-inline&quot;&gt;G = (V, E)&lt;&#x2F;span&gt; where each node &lt;span class=&quot;math math-inline&quot;&gt;x ∈ V&lt;&#x2F;span&gt; has a conditional probability distribution associated such that the joint probability on &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{V} = \prod_{x ∈ V} \Prc{x}{π_x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;π_x&lt;&#x2F;span&gt; denotes the parents of node &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A dynamic Bayesian Network is a pair &lt;span class=&quot;math math-inline&quot;&gt;(B_0, B_t)&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;B_0&lt;&#x2F;span&gt; is a Bayesian network representing the initial distribution (i.e. at time &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;) and &lt;span class=&quot;math math-inline&quot;&gt;B_t&lt;&#x2F;span&gt; is the transition network on the same nodes &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; but with a different set of edges allowing cycles and self-loops. Define with &lt;span class=&quot;math math-inline&quot;&gt;τ_x&lt;&#x2F;span&gt; the ancestors in the transition network.&lt;&#x2F;p&gt;
&lt;p&gt;Now replicate &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; for each time &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; so we have &lt;span class=&quot;math math-inline&quot;&gt;V_0, V_1, …&lt;&#x2F;span&gt; all containing the same nodes. Similarly we have &lt;span class=&quot;math math-inline&quot;&gt;x_0, x_1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{V_0} = \prod_{x_0 ∈ V_0} \Prc{x_0}{π_{x_0}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{V_t}{V_{t-1}} = \prod_{x_t ∈ V_t} \Prc{x_t}{π_{x_t}, τ_{x_{t-1}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Tracing:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr{V_{0:T}} = \Pr{V_0} ⋅ \Pr{V_{1:T}} = \prod_{x ∈ V} \Prc{x}{π_x} ⋅ \prod_{t ∈ 1:T} \prod_{x_t ∈ V_t} \Prc{x_t}{π_{x_t}, τ_{x_{t-1}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Alternative.&lt;&#x2F;strong&gt; A special case is when &lt;span class=&quot;math math-inline&quot;&gt;x_t&lt;&#x2F;span&gt; only depends on &lt;span class=&quot;math math-inline&quot;&gt;x_{t-1}&lt;&#x2F;span&gt; and other nodes at time &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt;. So history propagates directly. In this case &lt;span class=&quot;math math-inline&quot;&gt;E_t&lt;&#x2F;span&gt; only contains self-loops.&lt;&#x2F;p&gt;
&lt;p&gt;this leads to&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{V_t}{V_{t-1}} = \prod_{x ∈ V} \prod_{π_x ∈ V} \Prc{x_t}{π_{x_t}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; This model is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Markov_property&quot;&gt;Markovian&lt;&#x2F;a&gt; in that temporal relations are only between &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;t+1&lt;&#x2F;span&gt;. If different lags are required we can add these as state variables. (Or modify the model, but state seems more meaningful).&lt;&#x2F;p&gt;
&lt;p&gt;Partial observation. Only a subset of &lt;span class=&quot;math math-inline&quot;&gt;V&lt;&#x2F;span&gt; is observable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;learning-structure&quot;&gt;Learning structure&lt;&#x2F;h2&gt;
&lt;p&gt;It is possible to learn the structure of the graph from the data.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;For learning the base structure we can use all the available data for each variable, ignoring the temporal information. This is equivalent to learning a BN.
For learning the transition network we consider the temporal information, in particular the data for all variables in two consecutive time slices, &lt;span class=&quot;math math-inline&quot;&gt;X_t&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;X_{t+1}&lt;&#x2F;span&gt;.
Considering the base structure, we can then learn the dependencies between the variables at time &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;t+1&lt;&#x2F;span&gt;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~esucar&#x2F;Clases-mgp&#x2F;Notes&#x2F;c9-dbn.pdf&quot;&gt;[source]&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;learning-distributions-parameters-cma-es-on-cost-function&quot;&gt;Learning distributions parameters: CMA-ES on cost function&lt;&#x2F;h2&gt;
&lt;p&gt;In contracts with the &#x27;Expectation Maximization&#x27; method, the model is not optimized for distribution fit, but for a specified cost function. This makes the learning less sensitive to modelling errors.&lt;&#x2F;p&gt;
&lt;p&gt;One cost function is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Maximum_likelihood_estimation&quot;&gt;maximum likelihood&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;special-case-kalman-filters&quot;&gt;Special case: Kalman filters&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec x_{t+1} = A ⋅ \vec x_t + \vec c_t + \vec w_t
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\vec z_{t} = H ⋅ \vec x_t + \vec v_t
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With noise vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec w_t ∼ \mathcal{N}(0, Q_t)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec v_t ∼ \mathcal{N}(0, R_t)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{\vec x_{t+1}}{\vec x_t} \sim \mathcal{N}(A ⋅ \vec x_t, Q)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Prc{\vec z_t}{\vec x_t} \sim \mathcal{N}(H ⋅ \vec x_t, R)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;special-case-arima&quot;&gt;Special case: ARIMA&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;multithreaded.stitchfix.com&#x2F;blog&#x2F;2016&#x2F;04&#x2F;21&#x2F;forget-arima&#x2F;&quot;&gt;https:&#x2F;&#x2F;multithreaded.stitchfix.com&#x2F;blog&#x2F;2016&#x2F;04&#x2F;21&#x2F;forget-arima&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Y_t = \mu_t + x_t \beta + S_t + e_t
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mu_{t+1} = \mu_t + v_t
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;A new approach to learning in Dynamic BayesianNetworks (DBNs)
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1812.09027.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1812.09027.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Kalman filter demystified: from intuition to probabilistic graphical model to real case in financial markets
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1811.11618.pdf&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1811.11618.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A TutorialonDynamicBayesianNetworks
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cs.ubc.ca&#x2F;~murphyk&#x2F;Papers&#x2F;dbntalk.pdf&quot;&gt;https:&#x2F;&#x2F;www.cs.ubc.ca&#x2F;~murphyk&#x2F;Papers&#x2F;dbntalk.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;M. I. Jordan. An introduction to probabilistic graphical models.  Berkeley, 2016
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;people.eecs.berkeley.edu&#x2F;~jordan&#x2F;prelims&#x2F;&quot;&gt;https:&#x2F;&#x2F;people.eecs.berkeley.edu&#x2F;~jordan&#x2F;prelims&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.amazon.com&#x2F;gp&#x2F;product&#x2F;0262018020&lt;&#x2F;li&gt;
&lt;li&gt;Learning temporal nodes Bayesian networks.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~emorales&#x2F;Papers&#x2F;2013&#x2F;2013-HernandezLearningTemporalNodes.pdf&quot;&gt;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~emorales&#x2F;Papers&#x2F;2013&#x2F;2013-HernandezLearningTemporalNodes.pdf&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~esucar&#x2F;Clases-mgp&#x2F;Notes&#x2F;c9-dbn.pdf&quot;&gt;https:&#x2F;&#x2F;ccc.inaoep.mx&#x2F;~esucar&#x2F;Clases-mgp&#x2F;Notes&#x2F;c9-dbn.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bayesserver.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.bayesserver.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; How does this relate to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bayesian_structural_time_series&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bayesian_structural_time_series&lt;&#x2F;a&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;courses.cs.washington.edu&#x2F;courses&#x2F;cse515&#x2F;09sp&#x2F;slides&#x2F;varel.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;ethz.ch&#x2F;content&#x2F;dam&#x2F;ethz&#x2F;special-interest&#x2F;mtec&#x2F;chair-of-entrepreneurial-risks-dam&#x2F;documents&#x2F;dissertation&#x2F;master%20thesis&#x2F;Master_Thesis_%20Morzywolek.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;github.com&#x2F;jsyoon0823&#x2F;TimeGAN&lt;&#x2F;p&gt;
&lt;p&gt;http:&#x2F;&#x2F;isomorphisms.sdf.org&#x2F;maxdama.pdf&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>~~Smart~~ Order Routing</title>
        <published>2020-02-25T00:00:00+00:00</published>
        <updated>2020-02-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/smart-order-routing/"/>
        <id>https://2π.com/20/smart-order-routing/</id>
        
        <content type="html" xml:base="https://2π.com/20/smart-order-routing/">&lt;h1 id=&quot;smart-order-routing&quot;&gt;&lt;del&gt;Smart&lt;&#x2F;del&gt; Order Routing&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; (Fill function) A &lt;em&gt;fill function&lt;&#x2F;em&gt; &lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt; specifies how much of a desired asset we can maximally get for a given amount of the provided asset.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; (Monotonicity) &lt;em&gt;Fill functions are monotonic&lt;&#x2F;em&gt;. If a fill function provided more of the desired asset for fewer of the provided, we can simply provide it fewer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Problem.&lt;&#x2F;strong&gt; Given a maker asset amount &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; and a set of fill functions &lt;span class=&quot;math math-inline&quot;&gt;f_i&lt;&#x2F;span&gt;, we want to partition &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; into &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; to maximize.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
g(x) = \max_{\vec x} \, \sum_i f_i(x_i) \text{ subject to } \sum_i x_i \le x \text{ and } x_i \ge 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Dynamic programming: The resulting function &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is also a fill function. Given two fill functions, we can compute their combined function. So we only need to solve the case for two functions, and can then use this recursively.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;solving&quot;&gt;Solving&lt;&#x2F;h3&gt;
&lt;p&gt;If the fillable function is concave, the optimization problem is a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Convex_optimization&quot;&gt;Convex Programming&lt;&#x2F;a&gt; problem. In particular this means any local minimum is a global minimum and we can use any way to minimize (for example grandient descent).&lt;&#x2F;p&gt;
&lt;p&gt;Usually fillable functions are concave, with the notable exception of Kyber.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Question.&lt;&#x2F;strong&gt; If two fillable functions are concave, is their combination also concave?&lt;&#x2F;p&gt;
&lt;p&gt;If the fillable functions are note concave, the problem is&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-hop-routing&quot;&gt;1-hop routing&lt;&#x2F;h2&gt;
&lt;p&gt;Now we have more than two assets and multiple fill functions between two assets.&lt;&#x2F;p&gt;
&lt;p&gt;First, for each pair of tokens &lt;span class=&quot;math math-inline&quot;&gt;(i,j)&lt;&#x2F;span&gt; we compute the optimal fill function &lt;span class=&quot;math math-inline&quot;&gt;f_{ij}&lt;&#x2F;span&gt; using the above two-asset solution.&lt;&#x2F;p&gt;
&lt;p&gt;Define &lt;span class=&quot;math math-inline&quot;&gt;f_{ii}&lt;&#x2F;span&gt; to be the identity function.&lt;&#x2F;p&gt;
&lt;p&gt;Now the optimal &lt;span class=&quot;math math-inline&quot;&gt;\{0,1\}&lt;&#x2F;span&gt;-hop routes are&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f&amp;#39;_{ij}(x) = \max_{\vec x} \, \sum_k f_{kj}(f_{ik}(x_k)) \,\,\text{ subject to }\,\, \sum_k x_k \le x
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, we can define 3-hop routes &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;&amp;#39;_{ij}&lt;&#x2F;span&gt; by itterating this procedure on &lt;span class=&quot;math math-inline&quot;&gt;f&amp;#39;&lt;&#x2F;span&gt;, and 7-hop, 15-hop and so on, doubling the number of hops each time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inf-hop-routing&quot;&gt;∞-hop routing&lt;&#x2F;h2&gt;
&lt;p&gt;The optimal unlimited hop solutions &lt;span class=&quot;math math-inline&quot;&gt;f^∞_{ij}&lt;&#x2F;span&gt; should be invariant under adding one more hop, so it should satisfy&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f^∞_{ij}(x) = \max_{\vec x} \, \sum_k f^∞_{ik}(f^∞_{kj}(x_k)) \,\,\text{ subject to }\,\, \sum_k x_k \le x
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Flavours of Plonk</title>
        <published>2020-02-23T00:00:00+00:00</published>
        <updated>2020-02-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/flavours-of-plonk/"/>
        <id>https://2π.com/20/flavours-of-plonk/</id>
        
        <content type="html" xml:base="https://2π.com/20/flavours-of-plonk/">&lt;h1 id=&quot;flavours-of-plonk&quot;&gt;Flavours of Plonk&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;secret-circuit-plonk&quot;&gt;Secret Circuit Plonk&lt;&#x2F;h2&gt;
&lt;p&gt;Make the selector and permutation polynomials witness, accumulated hashes of them as part of the evaluation, provide hashes as public input.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;self-modifying-plonk&quot;&gt;Self modifying Plonk&lt;&#x2F;h2&gt;
&lt;p&gt;Add a second permutation check, have the permutation polynomial be a witness.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Check that it&#x27;s valid by verifying that it accumulates to the identity permutation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Stanford Research Workshop</title>
        <published>2020-02-22T00:00:00+00:00</published>
        <updated>2020-02-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/stanford-research-workshop/"/>
        <id>https://2π.com/20/stanford-research-workshop/</id>
        
        <content type="html" xml:base="https://2π.com/20/stanford-research-workshop/">&lt;h1 id=&quot;stanford-research-workshop&quot;&gt;Stanford Research Workshop&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\O{\mathcal{O}}
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Context.&lt;&#x2F;strong&gt; We are given a prime field &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt;, a size parameter &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\log_2 p &amp;gt; 250&lt;&#x2F;span&gt; (the prime is of &lt;em&gt;cryptographic size&lt;&#x2F;em&gt;),&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;2^n \,\vert\, p - 1&lt;&#x2F;span&gt; (the field has roots of unity &lt;span class=&quot;math math-inline&quot;&gt;\omega_n&lt;&#x2F;span&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;n = 2^k &amp;lt; 2^{28}&lt;&#x2F;span&gt; (we can realistically compute operations that ar &lt;span class=&quot;math math-inline&quot;&gt;O(n \log n)&lt;&#x2F;span&gt;, but not &lt;span class=&quot;math math-inline&quot;&gt;O(n ^2)&lt;&#x2F;span&gt;).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; If it helps, you may assume additional restricions on the prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt;, for example the existance of other roots of unity. (Depending on how common these primes are, the result may no longer be relevant in pairing cryptography, but it will still be relevant for FRI and DARK based constructions). You may even outright pick a prime.&lt;&#x2F;p&gt;
&lt;p&gt;We denote the set of polynomials of degree less than &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;\F_{&amp;lt; k}[X]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As is common in Cryptography, we accept probabilistic results as long as the probability is larger than &lt;span class=&quot;math math-inline&quot;&gt;1 - 2^{\lambda}&lt;&#x2F;span&gt;, where &lt;span class=&quot;math math-inline&quot;&gt;\lambda&lt;&#x2F;span&gt; is the number of &lt;em&gt;bits of security&lt;&#x2F;em&gt;. We typically require at least &lt;span class=&quot;math math-inline&quot;&gt;\lambda &amp;gt; 80&lt;&#x2F;span&gt;, but higher is better.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, we are working in interactive proofs where there is dialogue between a prover and a verifier. Given a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P \in \F_{&amp;lt; n}&lt;&#x2F;span&gt; we have existing protocols that allow us to send an &lt;em&gt;oracle&lt;&#x2F;em&gt; for this polynomial to the verfier, and the verifier can then ask for evaluations of these polynomials. Note that this existing protocol only works for polynomials of degree less than &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; (Polynomial identity test). Given two polynomials &lt;span class=&quot;math math-inline&quot;&gt;P, Q \in \F_{&amp;lt; n}[X]&lt;&#x2F;span&gt; we want to convice the verifier that they are equal. The prover sends oracles for &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; to the verifier, the verifier responds by asking for evaluations on a random point &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; and checks that they are equal.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Proof.&lt;&#x2F;strong&gt; By the Schwartz-Sippel lemma.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Problem.&lt;&#x2F;strong&gt; (Efficient zeros). An &lt;em&gt;efficiently evaluable polynomial&lt;&#x2F;em&gt; of degree &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; has an &lt;span class=&quot;math math-inline&quot;&gt;\O(\log n)&lt;&#x2F;span&gt; sized circuit of &lt;span class=&quot;math math-inline&quot;&gt;+&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;\times&lt;&#x2F;span&gt; operations that evaluates it. We are looking for efficiently evaluable polynomials that have as roots a subbset of the roots of unity &lt;span class=&quot;math math-inline&quot;&gt;\omega_n^i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For example &lt;span class=&quot;math math-inline&quot;&gt;X^n -1&lt;&#x2F;span&gt; is efficiently evaluable and has all the roots of unity as roots. &lt;span class=&quot;math math-inline&quot;&gt;X^{n&#x2F;2} -1&lt;&#x2F;span&gt; is efficient and has a roots all even powers of &lt;span class=&quot;math math-inline&quot;&gt;\omega_n^i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Problem.&lt;&#x2F;strong&gt; (Composition) Given &lt;span class=&quot;math math-inline&quot;&gt;F,G,H \in \F_{&amp;lt; n}[X]&lt;&#x2F;span&gt;, we want to interactively proof that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
F(G(X)) \!\!\!\!\mod H(X) = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can send &lt;em&gt;oracles&lt;&#x2F;em&gt; to the verifier, but only for polynomials in &lt;span class=&quot;math math-inline&quot;&gt;\F_{\le n}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The current proof protocols use&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
F(G(X)) = H(X) Z(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and then writes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Z(X) = Z_0(X^n) + X \cdot Z_1(X^n) + \cdots + X^n Z_n(X^n)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And sends oracles for &lt;span class=&quot;math math-inline&quot;&gt;Z_0 \dots Z_n&lt;&#x2F;span&gt; and uses identity testing. The problem is this uses &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; operations, and we&#x27;d like a protocol that uses at most &lt;span class=&quot;math math-inline&quot;&gt;\O(\log n)&lt;&#x2F;span&gt; exchanges.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Restrictions.&lt;&#x2F;strong&gt; Feel free to assume any of&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;H(X) = X^n -1&lt;&#x2F;span&gt; or any other efficient polynomial.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;F(X) = X^n -1&lt;&#x2F;span&gt; or any polynomial.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Generalizations.&lt;&#x2F;strong&gt; Same problem, but now with &lt;span class=&quot;math math-inline&quot;&gt;F&lt;&#x2F;span&gt; a multivariate over multiple &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
F(G_0(X), G_1(X), G_2(X), \dots, G_) = H(X) Z(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Solution by &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;20&#x2F;stanford-research-workshop&#x2F;rwbarton@gmail.com&quot;&gt;Reid Barton&lt;&#x2F;a&gt; for &lt;span class=&quot;math math-inline&quot;&gt;F&lt;&#x2F;span&gt; an efficient polynomial.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
G_1(X) - G(X)^2 &amp;amp;= H(X) Z_1(X) \\
G_2(X) - G(X)^2 &amp;amp;= H(X) Z_2(X) \\
&amp;amp; \,\,\,\vdots \\
G_k(X) - G(X)^2 &amp;amp;= H(X) Z_k(X) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to write any function in Solidity</title>
        <published>2020-02-11T00:00:00+00:00</published>
        <updated>2020-02-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/any-function-solidity/"/>
        <id>https://2π.com/20/any-function-solidity/</id>
        
        <content type="html" xml:base="https://2π.com/20/any-function-solidity/">&lt;h1 id=&quot;how-to-write-any-function-in-solidity&quot;&gt;How to write any function in Solidity&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;rational-approximations&quot;&gt;Rational approximations&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{P(x_i)}{Q(x_i)} = f(x_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x) = p_0 + p_1 x + p_2 x^2 + \dots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(x) = 1 + q_1 x + q_2 x^2 + \dots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x_i) = Q(x_i) f(x_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; \cdots \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; \cdots \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; \cdots \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots
\end{bmatrix}
\begin{bmatrix}
p_0 \\ p_1 \\ p_2 \\ \vdots
\end{bmatrix}
= \begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; \cdots \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; \cdots \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; \cdots \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots
\end{bmatrix}
\begin{bmatrix}
1 \\ q_1 \\ q_2 \\ \vdots
\end{bmatrix}
\odot
\begin{bmatrix}
f(x_0) \\ f(x_1) \\ f(x_2) \\ \vdots
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; \cdots \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; \cdots \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; \cdots \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots
\end{bmatrix}
\begin{bmatrix}
p_0 \\ p_1 \\ p_2 \\ \vdots
\end{bmatrix}
= \begin{bmatrix}
f(x_0) &amp;amp; f(x_0) x_0 &amp;amp; f(x_0) x_0^2 &amp;amp; \cdots \\
f(x_1) &amp;amp; f(x_1)x_1 &amp;amp; f(x_1)x_1^2 &amp;amp; \cdots \\
f(x_2) &amp;amp; f(x_2)x_2 &amp;amp; f(x_2)x_2^2 &amp;amp; \cdots \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots
\end{bmatrix}
\begin{bmatrix}
1 \\ q_1 \\ q_2 \\ \vdots
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; \cdots \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; \cdots \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; \cdots \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots
\end{bmatrix}
\begin{bmatrix}
p_0 \\ p_1 \\ p_2 \\ \vdots
\end{bmatrix}
= \begin{bmatrix}
f(x_0) x_0 &amp;amp; f(x_0) x_0^2 &amp;amp; \cdots \\
f(x_1)x_1 &amp;amp; f(x_1)x_1^2 &amp;amp; \cdots \\
f(x_2)x_2 &amp;amp; f(x_2)x_2^2 &amp;amp; \cdots \\
\vdots &amp;amp; \vdots &amp;amp; \ddots
\end{bmatrix}
\begin{bmatrix}
q_1 \\ q_2 \\ \vdots
\end{bmatrix}
+
\begin{bmatrix}
f(x_0) \\ f(x_1) \\ f(x_2) \\ \vdots
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; \cdots &amp;amp; -f(x_0)x_0 &amp;amp; -f(x_0)x_0^2 &amp;amp; \cdots \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; \cdots &amp;amp; -f(x_1)x_1 &amp;amp; -f(x_1)x_1^2 &amp;amp; \cdots \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; \cdots &amp;amp; -f(x_2)x_2 &amp;amp; -f(x_2)x_2^2 &amp;amp; \cdots  \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots
\end{bmatrix}
\begin{bmatrix}
p_0 \\ p_1 \\ p_2 \\ \vdots \\ q_1 \\ q_2 \\ \vdots
\end{bmatrix}
= \begin{bmatrix}
f(x_0) \\ f(x_1) \\ f(x_2) \\ \vdots
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remez-algorithm&quot;&gt;Remez algorithm&lt;&#x2F;h2&gt;
&lt;p&gt;By the Equioscilation theorem we know that when &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; are optimal, the errors is oscilating between &lt;span class=&quot;math math-inline&quot;&gt;\pm E&lt;&#x2F;span&gt;. Given the points of extremal error, &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;, this means&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{P(x_i)}{Q(x_i)} - f(x_i) = (-1)^i E
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This formula is the basis of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Remez_algorithm&quot;&gt;Remez algorithm&lt;&#x2F;a&gt;. We itteratively solve for this equation, and use the result to find better approximations of the extremal points &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{bmatrix}
1 &amp;amp; x_0 &amp;amp; x_0^2 &amp;amp; \cdots &amp;amp; -f(x_0)x_0 &amp;amp; -f(x_0)x_0^2 &amp;amp; \cdots &amp;amp; -1 \\
1 &amp;amp; x_1 &amp;amp; x_1^2 &amp;amp; \cdots &amp;amp; -f(x_1)x_1 &amp;amp; -f(x_1)x_1^2 &amp;amp; \cdots &amp;amp; +1 \\
1 &amp;amp; x_2 &amp;amp; x_2^2 &amp;amp; \cdots &amp;amp; -f(x_2)x_2 &amp;amp; -f(x_2)x_2^2 &amp;amp; \cdots &amp;amp; -1 \\
\vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots
\end{bmatrix}
\begin{bmatrix}
p_0 \\ p_1 \\ p_2 \\ \vdots \\ q_1 \\ q_2 \\ \vdots \\ E
\end{bmatrix}
= \begin{bmatrix}
f(x_0) \\ f(x_1) \\ f(x_2) \\ \vdots
\end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO.&lt;&#x2F;strong&gt; In the complex domain, the ideal errors seem to be &lt;span class=&quot;math math-inline&quot;&gt;e^{\pi i \frac{i}{n}} E&lt;&#x2F;span&gt;, this suggests that in the real domain we can use &lt;span class=&quot;math math-inline&quot;&gt;\cos \frac{i}{n} E&lt;&#x2F;span&gt;. In a way, this is a generalization of the &#x27;Modified Remez Algorithm&#x27; that also adds zero-error points &lt;span class=&quot;math math-inline&quot;&gt;\frac{P(x_i)}{Q(x_i)} - f(x_i) = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;clenshaw-algorithm-and-generalization-of-basis&quot;&gt;Clenshaw algorithm and generalization of basis&lt;&#x2F;h2&gt;
&lt;p&gt;We started out with polynomials of the form&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x) = p_0 + p_1 x + p_2 x^2 + \dots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;\vert x \vert &amp;gt; 1&lt;&#x2F;span&gt;, the &lt;span class=&quot;math math-inline&quot;&gt;x^i&lt;&#x2F;span&gt; terms will grow exponentially, which can lead to numericall instabilities. A simple trick to avoid this is to apply a linear function to the domain to map it into &lt;span class=&quot;math math-inline&quot;&gt;[-1, 1]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A more sophisticated way of avoiding it is by changing our basis polynomials. Let&#x27;s say that till now we have used the basis&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\phi_i(x) = x^i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x) = p_0 \phi_0(x) + p_1 \phi_1(x) + p_2 \phi_2(x) + \dots
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If these basis functions satisfy a recurrence&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\phi_{i+1}(x) = \alpha_i(x) \phi_i(x) + \beta_i(x) \phi_{i-1}(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;then a generalization of Horner&#x27;s evaluation mechanism applies:&lt;&#x2F;p&gt;
&lt;p&gt;The regular basis &lt;span class=&quot;math math-inline&quot;&gt;\phi_i(x) = x^i&lt;&#x2F;span&gt; satisfies with &lt;span class=&quot;math math-inline&quot;&gt;\alpha_i(x) = x&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\beta_i(x) = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The Chebyshev basis satisfies &lt;span class=&quot;math math-inline&quot;&gt;\alpha_i(x) = 2x&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\beta_i(x) = -1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
r_k = p_k + \alpha_k(x) r_{k+1} + \beta_{k+1} r_{k+2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Assuming &lt;span class=&quot;math math-inline&quot;&gt;\alpha&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\beta&lt;&#x2F;span&gt; do not depend on the index:&lt;&#x2F;p&gt;
&lt;p&gt;Horner case using one variable&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a = p_k + x * a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Chebyshev case using two variables&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a = p_4 + 2x * b - a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b = p_3 + 2x * a - b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a = p_2 + 2x * b - a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b = p_1 + 2x * a - b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Chebyshev uses one more variable and has an additional subtraction, but same number of multiplications.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt; Barycentric basis&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20200211232711&#x2F;https:&#x2F;&#x2F;www.mn.uio.no&#x2F;math&#x2F;english&#x2F;people&#x2F;aca&#x2F;michaelf&#x2F;papers&#x2F;rational.pdf&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Closure analysis</title>
        <published>2020-01-23T00:00:00+00:00</published>
        <updated>2020-01-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/20/closure-analysis/"/>
        <id>https://2π.com/20/closure-analysis/</id>
        
        <content type="html" xml:base="https://2π.com/20/closure-analysis/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\code#1{\mathtt{#1}}
\gdef\closure#1{\mathcal C_{#1}}
\gdef\par#1{\left( {#1} \right)}
\gdef\set#1{\left\{ {#1} \right\}}
\gdef\union{\cup}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;closure-analysis&quot;&gt;Closure analysis&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fact n return: isZero n base recurse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    base: return 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    recurse: sub n 1 step1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        step1 m: fact m step2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        step2 f: mul n f return&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;main return1: fact 5 m0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    m0 f: print f m1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    m1: return1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Take the exemplar line&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\code{step1}\ \code{m}\ \code{return}\ \code{:}\ \code{isZero}\ \code{n}\ \code{base}\ \code{recurse}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Turn this into a equation where we take all indentifiers in the call. For each identifier that is a name, we add a the closure. For each identifier that is a parameter, we just add it plain. Then subtract the parameters of the declaration itself.&lt;&#x2F;p&gt;
&lt;p&gt;This creates a set of equations:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\closure{\code{fact}} &amp;amp;=
    \set{\code{n}}
    \union \closure{\code{base}}
    \union \closure{\code{recurse}}
    \setminus \set{\code{n}, \code{return}}
\\
\closure{\code{base}} &amp;amp;=
    \set{\code{return}}
\\
\closure{\code{recurse}} &amp;amp;=
    \set{\code{n}}
    \union \closure{\code{step1}}
\\
\closure{\code{step1}} &amp;amp;=
    \set{\code{m}}
    \union \closure{\code{fact}}
    \union \closure{\code{step2}}
    \setminus \set{\code{m}}
\\
\closure{\code{step2}} &amp;amp;=
    \set{\code{n}, \code{f}, \code{return}}
    \setminus \set{\code{f}}
\\
\closure{\code{main}} &amp;amp;=
    \closure{\code{fact}}
    \union \closure{\code{m0}}
    \setminus \set{\code{return1}}
\\
\closure{\code{m0}} &amp;amp;=
    \set{\code{f}}
    \union \closure{\code{m1}}
    \setminus \set{\code{f}}
\\
\closure{\code{m1}} &amp;amp;=
    \set{\code{return1}}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s try to solve these equations:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\closure{\code{fact}} &amp;amp;=
    \closure{\code{recurse}}
    \setminus \set{\code{n}, \code{return}}
\\
\closure{\code{base}} &amp;amp;=
    \set{\code{return}}
\\
\closure{\code{recurse}} &amp;amp;=
    \set{\code{n}}
    \union \closure{\code{step1}}
\\
\closure{\code{step1}} &amp;amp;=
    \set{\code{n}, \code{return}}
    \union \closure{\code{fact}}
    \setminus \set{\code{m}}
\\
\closure{\code{step2}} &amp;amp;=
    \set{\code{n}, \code{return}}
\\
\closure{\code{main}} &amp;amp;=
    \closure{\code{fact}}
    \setminus \set{\code{return1}}
\\
\closure{\code{m0}} &amp;amp;=
    \set{\code{return1}}
\\
\closure{\code{m1}} &amp;amp;=
    \set{\code{return1}}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The problem now is that we have a cycle around &lt;span class=&quot;math math-inline&quot;&gt;\closure{\code{fact}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\closure{\code{fact}} &amp;amp;=
    \closure{\code{recurse}}
    \setminus \set{\code{n}, \code{return}}
\\
\closure{\code{recurse}} &amp;amp;=
    \set{\code{n}}
    \union \closure{\code{step1}}
\\
\closure{\code{step1}} &amp;amp;=
    \set{\code{n}, \code{return}}
    \union \closure{\code{fact}}
    \setminus \set{\code{m}}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s inline all expressions until we recurse:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\closure{\code{fact}} &amp;amp;=
    \set{\code{n}}
    \union \par{
        \set{\code{n}, \code{return}}
        \union \closure{\code{fact}}
        \setminus \set{\code{m}}
    }
    \setminus \set{\code{n}, \code{return}}
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively, we could pick any of the others to inline. The results should be the same:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\closure{\code{recurse}} &amp;amp;=
    \set{\code{n}}
    \union \par{
        \set{\code{n}, \code{return}}
        \union \par{
            \closure{\code{recurse}}
            \setminus \set{\code{n}, \code{return}}
        }
        \setminus \set{\code{m}}
    }
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;solving-for-fact&quot;&gt;Solving for &lt;code&gt;fact&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\closure{\code{fact}} &amp;amp;=
    \set{\code{n}}
    \union \par{
        \set{\code{n}, \code{return}}
        \union \closure{\code{fact}}
        \setminus \set{\code{m}}
    }
    \setminus \set{\code{n}, \code{return}}
\\
\closure{\code{fact}} &amp;amp;=
    \par{
        \set{\code{n}}
        \setminus \set{\code{n}, \code{return}}
    }
    \union
    \par{
        \par{
            \set{\code{n}, \code{return}}
            \union \closure{\code{fact}}
            \setminus \set{\code{m}}
        }
        \setminus \set{\code{n}, \code{return}}
    }
\\
\closure{\code{fact}} &amp;amp;=
    \par{
        \set{\code{n}}
        \setminus \set{\code{n}, \code{return}}
    }
    \union
    \par{
        \par{
            \set{\code{n}, \code{return}}
            \union \closure{\code{fact}}
        }
        \setminus \set{\code{m}, \code{n}, \code{return}}
    }
\\
\closure{\code{fact}} &amp;amp;=
    \par{
        \set{\code{n}, \code{return}}
        \setminus \set{\code{m}, \code{n}, \code{return}}
    }
    \union
    \par{
        \closure{\code{fact}}
        \setminus \set{\code{m}, \code{n}, \code{return}}
    }
\\
\closure{\code{fact}} &amp;amp;=
    \closure{\code{fact}}
    \setminus \set{\code{m}, \code{n}, \code{return}}
\\
\closure{\code{fact}} &amp;amp;\in
    \mathcal{P} \par{
        \set{\code{m}, \code{n}, \code{return}}
        ^\mathrm{C}
    }
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The smallest solution is &lt;span class=&quot;math math-inline&quot;&gt;\closure{\code{fact}} = \emptyset&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We can substitute this back to solve all equations. But let&#x27;s instead look at a different recursive equation and see if we can solve it too:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;solving-for-recurse&quot;&gt;Solving for &lt;code&gt;recurse&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
\closure{\code{recurse}} &amp;amp;=
    \set{\code{n}}
    \union \par{
        \set{\code{n}, \code{return}}
        \union \par{
            \closure{\code{recurse}}
            \setminus \set{\code{n}, \code{return}}
        }
        \setminus \set{\code{m}}
    }
\\
\closure{\code{recurse}} &amp;amp;=
    \set{\code{n}}
    \union
    \par{
        \set{\code{n}, \code{return}}
        \setminus \set{\code{m}}
    }
    \union
    \par{
        \closure{\code{recurse}}
        \setminus \set{\code{m}, \code{n}, \code{return}}
    }
\\
\closure{\code{recurse}} &amp;amp;=
    \set{\code{n}, \code{return}}
    \union \par{
        \closure{\code{recurse}}
        \setminus \set{\code{m}, \code{n}, \code{return}}
    }
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The smallest solution is &lt;span class=&quot;math math-inline&quot;&gt;\closure{\code{recurse}} = \set{\code{n}, \code{return}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Special primes</title>
        <published>2019-12-13T00:00:00+00:00</published>
        <updated>2019-12-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/special-primes/"/>
        <id>https://2π.com/19/special-primes/</id>
        
        <content type="html" xml:base="https://2π.com/19/special-primes/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\mod#1{[{#1}]}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;special-primes&quot;&gt;Special primes&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Solinas Primes.&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;p = P(\cdot 2^{k})&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; a low-degree polynomial with tiny coefficients, usually &lt;span class=&quot;math math-inline&quot;&gt;{-1,0,1}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note.&lt;&#x2F;em&gt; These are also known as Generalized Mersenne Primes.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Solinas_prime&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;citeseerx.ist.psu.edu&#x2F;viewdoc&#x2F;download?doi=10.1.1.46.2133&amp;amp;rep=rep1&amp;amp;type=pdf&lt;&#x2F;p&gt;
&lt;p&gt;http:&#x2F;&#x2F;cacr.uwaterloo.ca&#x2F;techreports&#x2F;1999&#x2F;corr99-39.pdf&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Pseudo-Mersenne Primes.&lt;&#x2F;strong&gt; A subset of Solinas Primes of the form &lt;span class=&quot;math math-inline&quot;&gt;p = 2^k - c&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; a small.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;crypto.stackexchange.com&#x2F;a&#x2F;14807&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;crypto.stackexchange.com&#x2F;questions&#x2F;32222&#x2F;difference-between-pseudo-mersenne-primes-and-generalized-mersenne-primes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Proth Primes.&lt;&#x2F;strong&gt; &lt;span class=&quot;math math-inline&quot;&gt;p = c \cdot 2^{k} + 1&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;2^{k} &amp;gt; c&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; small.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.microsoft.com&#x2F;en-us&#x2F;research&#x2F;wp-content&#x2F;uploads&#x2F;2016&#x2F;02&#x2F;modmul_no_precomp.pdf&lt;&#x2F;p&gt;
&lt;h3 id=&quot;list-of-primes&quot;&gt;List of primes&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;safecurves.cr.yp.to&#x2F;field.html&lt;&#x2F;p&gt;
&lt;h1 id=&quot;montgomery-form-for-proth-primes&quot;&gt;Montgomery form for Proth primes&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We are interested in arithmatic in a prime field &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; with roots of unity &lt;span class=&quot;math math-inline&quot;&gt;\omega_n&lt;&#x2F;span&gt; for large powers of two, &lt;span class=&quot;math math-inline&quot;&gt;n = 2^k&lt;&#x2F;span&gt;. Due to math, this means that &lt;span class=&quot;math math-inline&quot;&gt;2^k \vert p -1&lt;&#x2F;span&gt; and so &lt;span class=&quot;math math-inline&quot;&gt;p = c\cdot2^k +1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Prime numbers of the form &lt;span class=&quot;math math-inline&quot;&gt;c\cdot2^k +1&lt;&#x2F;span&gt; are known as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proth_prime&quot;&gt;Proth primes&lt;&#x2F;a&gt; after the related &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proth%27s_theorem&quot;&gt;Proth&#x27;s theorem&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; &lt;em&gt;(Proth&#x27;s theorem) If &lt;span class=&quot;math math-inline&quot;&gt;p = c\cdot 2^k + 1&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; odd and &lt;span class=&quot;math math-inline&quot;&gt;2^k &amp;gt; c&lt;&#x2F;span&gt; and there exist an integer &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a^{\frac{p -1}{2}} = -1 \mod p&lt;&#x2F;span&gt;, then and only then &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; is prime.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We further specialize to the case where &lt;span class=&quot;math math-inline&quot;&gt;p &amp;lt; 2^{254}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;k = 196&lt;&#x2F;span&gt;. This means that our prime has the following form in as a 256-bit binary number:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0
\overbrace{c_{62} c_{61} \dots c_{0}}^{63}
\overbrace{0 0 0 0 0 0 0 \dots 0 0 0 0}^{195}
1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;or, represented using 64-bit words:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c
0
0
1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This special form will come in handy when we develop a Montgomery multiplication routine.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Montgomery_modular_multiplication&quot;&gt;Montgomery reduction&lt;&#x2F;a&gt; is an efficient way to compute &lt;span class=&quot;math math-inline&quot;&gt;\frac{x}{2^{256}} \mod p&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;x &amp;lt; p\cdot2^{256}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
M = -p^{-1} \mod 2^{64} = -1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;span class=&quot;math math-inline&quot;&gt;p = 1 \mod 2^{64}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;For i in 0 to 3:&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A = A + \left[-a_i \right]_{2^{64}} \cdot m \cdot (2^{64})^i&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{matrix}
a_7 &amp;amp; a_6 &amp;amp; a_5 &amp;amp; a_4 &amp;amp; a_3 &amp;amp; a_2 &amp;amp; a_1 &amp;amp; a_0 \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_0 \\
&amp;amp; &amp;amp; &amp;amp; (-a_0 m_3)_1 &amp;amp; (-a_0 m_3)_0 &amp;amp; &amp;amp; &amp;amp; \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_1&amp;#39; &amp;amp; \\
&amp;amp; &amp;amp; (-a_1&amp;#39; m_3)_1 &amp;amp; (-a_1&amp;#39; m_3)_0 &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_2&amp;#39;&amp;#39; &amp;amp; &amp;amp; \\
&amp;amp; (-a_2&amp;#39;&amp;#39; m_3)_1 &amp;amp; (-a_2&amp;#39;&amp;#39; m_3)_0 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_3&amp;#39;&amp;#39;&amp;#39; &amp;amp; &amp;amp; &amp;amp; \\
(-a_3&amp;#39;&amp;#39;&amp;#39; m_3)_1 &amp;amp; (-a_3&amp;#39;&amp;#39;&amp;#39; m_3)_0 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\
\end{matrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note, all negatives like &lt;span class=&quot;math math-inline&quot;&gt;-a_0&lt;&#x2F;span&gt; are to be taken in twos complement, so &lt;span class=&quot;math math-inline&quot;&gt;2^{64} - a_0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;a_1&amp;#39; = a_1 + 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;-a_1&amp;#39;&lt;&#x2F;span&gt;. Instead of adding one and negating, we can take the binary complement (not) of the bits.&lt;&#x2F;p&gt;
&lt;p&gt;We can ignore computing the first three limbs altogether.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;-a_1&amp;#39; = !a_1&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;-a_2&amp;#39;&amp;#39; = !a_2&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_3&amp;#39;&amp;#39;&amp;#39; = a_3 - a_0 m_3 + 1&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Above observations only hold if &lt;span class=&quot;math math-inline&quot;&gt;a_0, a_1&amp;#39;, a_2&amp;#39;&amp;#39;, a_3&amp;#39;&amp;#39;&amp;#39;&lt;&#x2F;span&gt; non-zero&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; The carry of &lt;span class=&quot;math math-inline&quot;&gt;a_0 + [- a_0]_{2^{64}}&lt;&#x2F;span&gt; is always one, except when &lt;span class=&quot;math math-inline&quot;&gt;a_0&lt;&#x2F;span&gt; is zero. What happens if we assume the carry is always one? In other words, we sometimes add an additional &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;a_0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The mechanic of setting the lower bits to zero would still work, but we would substitute &lt;span class=&quot;math math-inline&quot;&gt;2^{64} - a_0&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;- a_0&lt;&#x2F;span&gt;. This means we add an additional &lt;span class=&quot;math math-inline&quot;&gt;m_3&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;a_4&lt;&#x2F;span&gt;, only if &lt;span class=&quot;math math-inline&quot;&gt;a_0 = 0&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{matrix}
a_7 &amp;amp; a_6 &amp;amp; a_5 &amp;amp; a_4 &amp;amp; a_3 &amp;amp; a_2 &amp;amp; a_1 &amp;amp; a_0 \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_0 \\
&amp;amp; &amp;amp; &amp;amp; (-a_0 m_3)_1 &amp;amp; (-a_0 m_3)_0 &amp;amp; &amp;amp; &amp;amp; \\
&amp;amp; &amp;amp; &amp;amp; m_3 &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\
\end{matrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The same goes for the other three limbs. The net affect is also that the final result is no longer within 2x of the modulus, but 3x.&lt;&#x2F;p&gt;
&lt;p&gt;Another option is to speculatively use (or not use) the carry, and correct after.&lt;&#x2F;p&gt;
&lt;p&gt;Not using:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{matrix}
a_7 &amp;amp; a_6 &amp;amp; a_5 &amp;amp; a_4 &amp;amp; a_3 &amp;amp; a_2 &amp;amp; a_1 &amp;amp; a_0 \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_0 \\
&amp;amp; &amp;amp; &amp;amp; (-a_0 m_3)_1 &amp;amp; (-a_0 m_3)_0 &amp;amp; &amp;amp; &amp;amp; \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_1 &amp;amp; \\
&amp;amp; &amp;amp; (-a_1 m_3)_1 &amp;amp; (-a_1 m_3)_0 &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -1 &amp;amp; &amp;amp; \text{c}_1\\
&amp;amp; &amp;amp; &amp;amp; -m_3 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \text{c}_1\\
\end{matrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{matrix}
a_7 &amp;amp; a_6 &amp;amp; a_5 &amp;amp; a_4 &amp;amp; a_3 &amp;amp; a_2 &amp;amp; a_1 &amp;amp; a_0 \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_0 \\
&amp;amp; &amp;amp; &amp;amp; (-a_0 m_3)_1 &amp;amp; (-a_0 m_3)_0 &amp;amp; &amp;amp; &amp;amp; \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; -a_1 &amp;amp; \\
&amp;amp; &amp;amp; (-a_1 m_3)_1 &amp;amp; (-a_1 m_3)_0 &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\
&amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; \text{c}_1\\
&amp;amp; &amp;amp; &amp;amp; m_3 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \text{c}_1\\
\end{matrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When do carries occur?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_0&lt;&#x2F;span&gt; will carry if &lt;span class=&quot;math math-inline&quot;&gt;a_0 \ne 0&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_1&lt;&#x2F;span&gt; will carry if &lt;span class=&quot;math math-inline&quot;&gt;a_0 \ne 0 \land a_1 \ne -1&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;a_0 = 0 \land a_1 \ne 0&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;a_2&lt;&#x2F;span&gt; will carry if ...&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Composition proof</title>
        <published>2019-12-12T00:00:00+00:00</published>
        <updated>2019-12-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/composition-proof/"/>
        <id>https://2π.com/19/composition-proof/</id>
        
        <content type="html" xml:base="https://2π.com/19/composition-proof/">&lt;h1 id=&quot;composition-proof&quot;&gt;Composition proof&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Context.&lt;&#x2F;strong&gt; Are values are from a&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; &lt;em&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P\in\F_{&amp;lt; N}[X]&lt;&#x2F;span&gt; Proof the following constraint using Schwartz-Sippel and a &lt;span class=&quot;math math-inline&quot;&gt;\le N&lt;&#x2F;span&gt; low degree test:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
F(G(X)) \mod H(X) = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{P(X)^{2^{64}} - 1}{X^N - 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;Polynomials satisfying the above constraint satisfy &lt;span class=&quot;math math-inline&quot;&gt;P(\omega_N^i) = \omega_{2^{64}}^{k_i}&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;i \in [0,N)&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;&lt;span class=&quot;math math-inline&quot;&gt;\F_{&amp;lt; N}[X] \sim \F[X]&#x2F; X^N&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Assume for the moment &lt;span class=&quot;math math-inline&quot;&gt;N = 2^{64}&lt;&#x2F;span&gt;, we can generalize later&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{P(X)^N - 1}{X^N - 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This puts some constraints on the coefficients of &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = \sum_{i\in[0,N)} p_i X^i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\frac{P(X)^N - 1}{X^N - 1} &amp;amp;= \\
\frac{\left(\sum_{i\in[0,N)} p_i X^i\right)^N - 1}{X^N - 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can now expand using something like the https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Binomial_theorem, i.e. https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Multinomial_theorem.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Look into differentials.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simplifications&quot;&gt;Simplifications&lt;&#x2F;h2&gt;
&lt;p&gt;We can further restrict the problem to the case &lt;span class=&quot;math math-inline&quot;&gt;h(x) = x^n - 1&lt;&#x2F;span&gt;. This can help because we can now factor &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt; as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
h(x) = (x - ω_n^0) (x - ω_n^1) (x - ω_n^2) \cdots (x - ω_n^{n-1})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;or (thanks Yan Zhang)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
h(x) = (x - 1) (x + 1) (x^2 + 1) (x^4 + 1) \cdots (x^n + 1)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The problem could be broken solved modulo these factors and then invoke CRT.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;J. F. Ritt (1921). &quot;Prime and Composite Polynomials&quot;.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.ams.org&#x2F;journals&#x2F;tran&#x2F;1922-023-01&#x2F;S0002-9947-1922-1501189-9&#x2F;S0002-9947-1922-1501189-9.pdf&quot;&gt;link&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Raoul Blankertz (2014). &quot;A polynomial time algorithm for computing all minimal decompositions of a polynomial&quot;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20150924101735&#x2F;http:&#x2F;&#x2F;www.sigsam.org&#x2F;bulletin&#x2F;articles&#x2F;187&#x2F;Polynomial_time_decomposition_pp13-23.pdf&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;K. S. Kedlaya, C. Umans (2011). &quot;Fast polynomial factorization and modular composition&quot;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;users.cms.caltech.edu&#x2F;~umans&#x2F;papers&#x2F;KU08-final.pdf&quot;&gt;link&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Composition of cyclic proof system.</title>
        <published>2019-12-09T00:00:00+00:00</published>
        <updated>2019-12-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/composition-of-cyclic-proof-system/"/>
        <id>https://2π.com/19/composition-of-cyclic-proof-system/</id>
        
        <content type="html" xml:base="https://2π.com/19/composition-of-cyclic-proof-system/">&lt;h1 id=&quot;composition-of-cyclic-proof-system&quot;&gt;Composition of cyclic proof system.&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\Z{\mathbb{Z}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;The single most important theorem in modern proof systems is the Schwarz-Zippel lemma, so let&#x27;s introduce it now:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem.&lt;&#x2F;strong&gt; &lt;em&gt;(Schwartz–Zippel)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Proof system). Given a claim &lt;span class=&quot;math math-inline&quot;&gt;c \in \mathcal C&lt;&#x2F;span&gt; and witness &lt;span class=&quot;math math-inline&quot;&gt;w \in \mathcal W&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setup&lt;&#x2F;code&gt;: &lt;span class=&quot;math math-inline&quot;&gt;(Entropy, \lambda) \rightarrow K&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;proof&lt;&#x2F;code&gt;: &lt;span class=&quot;math math-inline&quot;&gt;(\mathcal C, \mathcal W) \rightarrow \mathcal P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;verify&lt;&#x2F;code&gt;: &lt;span class=&quot;math math-inline&quot;&gt;(\mathcal C, \mathcal W) \rightarrow \mathcal P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the remainder we assume we are talking about a specific instance of a proof, meaning the claim and witness are fixed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Algebraic expressions). &lt;span class=&quot;math math-inline&quot;&gt;\F[\{X_0, X_1, \dots\}]&lt;&#x2F;span&gt;&lt;&#x2F;em&gt; Is this a free-semiring?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Polynomial proof system). Given a field &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Parameters: &lt;span class=&quot;math math-inline&quot;&gt;\F&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\F[X]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Setup polynomials: &lt;span class=&quot;math math-inline&quot;&gt;Q_0(X), Q_1(X), \dots&lt;&#x2F;span&gt;. (&lt;strong&gt;to do&lt;&#x2F;strong&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;Witness polynomials: &lt;span class=&quot;math math-inline&quot;&gt;P_0(X), P_1(X), \dots, P_M(X)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Constraint expressions: &lt;span class=&quot;math math-inline&quot;&gt;f_0(X, P_0, P_1, \dots, P_M), f_1(\dots)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Cyclic polynomial proof system). A polynomial proof system where for each witness polynomial &lt;span class=&quot;math math-inline&quot;&gt;P_i&lt;&#x2F;span&gt; there is a primitive root of unity &lt;span class=&quot;math math-inline&quot;&gt;\omega_{N_i}&lt;&#x2F;span&gt; of order &lt;span class=&quot;math math-inline&quot;&gt;N_i = \deg P_i + 1&lt;&#x2F;span&gt;. Setup and witness polynomials are defined by a vector &lt;span class=&quot;math math-inline&quot;&gt;\vec w_i \in \F^{N_i}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;P_i&lt;&#x2F;span&gt; is the polynomial resulting from interpolation of the vector on &lt;span class=&quot;math math-inline&quot;&gt;⟨ω_{N_i}⟩&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;P_i(\omega_{N_i}^j) = w_{ij}&lt;&#x2F;span&gt;. All access to &lt;span class=&quot;math math-inline&quot;&gt;P_i&lt;&#x2F;span&gt;&#x27;s in the constraint expression is of the form &lt;span class=&quot;math math-inline&quot;&gt;P_i(\omega_{N_i}^k X)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;k \in \Z&lt;&#x2F;span&gt;. This allows us to relate witness value &lt;span class=&quot;math math-inline&quot;&gt;w_{i,j}&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;w_{i,j + k}&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In the case of starks, the witness vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec w_i&lt;&#x2F;span&gt; are all of the same length, called the &lt;em&gt;trace length&lt;&#x2F;em&gt;. This allows the interpolated values &lt;span class=&quot;math math-inline&quot;&gt;w_{ij}&lt;&#x2F;span&gt; to be layed out in an &lt;span class=&quot;math math-inline&quot;&gt;N \times M&lt;&#x2F;span&gt; matrix, called the &lt;em&gt;trace table&lt;&#x2F;em&gt;. The witness vectors are called &lt;em&gt;columns&lt;&#x2F;em&gt; or &lt;em&gt;registers&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Generallize to expressions of the form &lt;span class=&quot;math math-inline&quot;&gt;P_i(\omega^k X^e)&lt;&#x2F;span&gt; which will allow relating &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;e \cdot i + k&lt;&#x2F;span&gt;, which in turn may allow the &lt;span class=&quot;math math-inline&quot;&gt;2i&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;2i + 1&lt;&#x2F;span&gt; offsets required for Vitalik&#x27;s data availability proof.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Show how to generalize&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; *(Degree of constraints). The maximum degree of &lt;span class=&quot;math math-inline&quot;&gt;f_i&lt;&#x2F;span&gt; in the arguments &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; (so excluding the degree of &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;We can write repeating polynomial relationships between witness values.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In practice we want to keep the degree of these relationships low, typically just &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;3&lt;&#x2F;span&gt;. It is always possible to re-write higher degree constraint systems to an equivalent lower degree one by introducing new witness polynomials and new constraints.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Constraint values). Unconstraint values in the RS that can be set to anything.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Empty proof). Proof of given size where all values are unconstraint.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;transformations-and-compositions&quot;&gt;Transformations and compositions&lt;&#x2F;h2&gt;
&lt;p&gt;We will start by introducing some obvious invariants of proof systems. For starters, adding unused witness polynomials maintains the proof:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Extension). Adding more unconstraint witness polynomials.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can also change the order of the witness polynomials:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Permutation of witness polynomials). An RS proof system is invariant under a permutation of the order of the witness polynomials.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can also rotate things around&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Scaling). An RS proof system is invariant under multiplication of each constraint expression by a constant.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Rotation). An RS proof system is invariant under an affine transform &lt;span class=&quot;math math-inline&quot;&gt;X \mapsto \omega_N X^i&lt;&#x2F;span&gt; with corresponding rotation of the witness polynomials.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Rotation). An RS proof system is invariant under an affine transform &lt;span class=&quot;math math-inline&quot;&gt;X \mapsto \omega_N^k X^i&lt;&#x2F;span&gt; in constraint polynomials witness access and &lt;span class=&quot;math math-inline&quot;&gt;X \mapsto \omega_N^{-k} X&lt;&#x2F;span&gt; for the &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; argument.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Interpolation). An RS proof system is invariant under an affine transform &lt;span class=&quot;math math-inline&quot;&gt;X \mapsto X^k&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;k \vert N&lt;&#x2F;span&gt; and (&lt;strong&gt;to do&lt;&#x2F;strong&gt;).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Combined, these rotation and interpolation have the effect of mapping &lt;span class=&quot;math math-inline&quot;&gt;X=\omega_N^i&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;X=\omega_N^{e \cdot i + k}&lt;&#x2F;span&gt;; it is an affine transform of the exponent with a corresponding inverse transform in the witness.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Folding). An RS proof system with &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt; witness polynomials of degrees &lt;span class=&quot;math math-inline&quot;&gt;n_i&lt;&#x2F;span&gt; can be transformed into an RS proof system with &lt;span class=&quot;math math-inline&quot;&gt;M&#x2F;2&lt;&#x2F;span&gt; polynomials of degree &lt;span class=&quot;math math-inline&quot;&gt;2 n_i&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Generalize to roots of unity other than binary powers of two.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Generalize to roots of unity other than binary powers of two, allowing more complex foldings than halfing&#x2F;doubling.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Repeated folding). .&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Projection). Given two RS proof systems such that the second fits in the unconstraint cells of the first, they can be merged.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Horizontal composition). Two proof systems can be composed horizontally.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Vertical composition). Two proof systems can be composed vertically if all their constraints are the same.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The previous lemmas give us some leeway to make them the same.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Matched horizontal composition). Can be composed horizontally.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;special-cyclic-polynomial-proof-systems&quot;&gt;Special cyclic polynomial proof systems&lt;&#x2F;h2&gt;
&lt;p&gt;Vector equality&lt;&#x2F;p&gt;
&lt;p&gt;Set equality&lt;&#x2F;p&gt;
&lt;p&gt;Permutation check&lt;&#x2F;p&gt;
&lt;p&gt;Univariate rowcheck&lt;&#x2F;p&gt;
&lt;p&gt;Univariate sumcheck&lt;&#x2F;p&gt;
&lt;p&gt;Row check&lt;&#x2F;p&gt;
&lt;p&gt;Lincheck&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-cyclic-polynomial-proof-systems&quot;&gt;Example cyclic polynomial proof systems&lt;&#x2F;h2&gt;
&lt;p&gt;MiMC&#x2F;Poseidon&#x2F;etc.&lt;&#x2F;p&gt;
&lt;p&gt;Plonk&#x2F;RedShift&lt;&#x2F;p&gt;
&lt;p&gt;Aurora&lt;&#x2F;p&gt;
&lt;p&gt;Marlin&lt;&#x2F;p&gt;
&lt;p&gt;Fractal&lt;&#x2F;p&gt;
&lt;h2 id=&quot;overview-of-low-degree-tests&quot;&gt;Overview of low degree tests&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Degree raising). Given a polynomial &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; with degree bound &lt;span class=&quot;math math-inline&quot;&gt;\deg P ≤ k&lt;&#x2F;span&gt; and an LDE test for degree &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;k ≤ N&lt;&#x2F;span&gt;, we can test the degree-bound of the polynomial.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P&amp;#39;(X) = (\alpha + \beta \cdot X^k) \cdot P(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Degree halving).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = P&amp;#39;(X^2) + X \cdot P&amp;#39;&amp;#39;(X^2)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Degree halving doubles the number of polynomials to be LDE tested.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Combining low degree tests).&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P&amp;#39;(X) = \sum_i \alpha_i P_i(X)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using the above three lemmas, a single low-degree test can verify arbitrary degree bounds on a set of polynomials.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fri&quot;&gt;FRI&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;dark-on-rsa-or-classgroups&quot;&gt;Dark (on RSA or Classgroups)&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;kit-commitment-pairing&quot;&gt;Kit commitment (Pairing)&lt;&#x2F;h3&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>AIR Composibility</title>
        <published>2019-11-15T00:00:00+00:00</published>
        <updated>2019-11-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/air-composability/"/>
        <id>https://2π.com/19/air-composability/</id>
        
        <content type="html" xml:base="https://2π.com/19/air-composability/">&lt;h1 id=&quot;air-composibility&quot;&gt;AIR Composibility&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    trace&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;       TraceTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    constraints&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;RationalExpression&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    labels&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;      Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;String&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; RationalExpression&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; Having labels on expressions allows direct labeling of trace cells  using &lt;code&gt;Trace(i, j)&lt;&#x2F;code&gt;. But it also allows labeling derived values, for example if the constraints are written such that the &#x27;real&#x27; value is the difference of two columns, the labeled output can be &lt;code&gt;Trace(i, j) - Trace(i, k)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trace-generation&quot;&gt;Trace generation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Alternative.&lt;&#x2F;strong&gt; Instead of having the components supply the full trace table, we could also have them return a sparse table of &lt;span class=&quot;math math-inline&quot;&gt;(i, j, value)&lt;&#x2F;span&gt; tuples. The constraints would then be used to fill out the table. This may (or not) be more performant, but seems harder to implement. Perhaps instead we can provide helper functions to generate a trace table from constraints and sparse values.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;air-component-combinators&quot;&gt;Air component combinators&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; compose_horizontal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;rows &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; result.trace = [A.trace | B.trace]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; B.constraints.shift_columns(A.num_columns)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; result.constraints = union(A.constraints, B.constraints)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; names are prefixed `left_` and `right_`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; compose_vertical&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;rows &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;cols &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;constraints &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;constraints&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; result.trace = [ A.trace ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [ B.trace ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; A.constraints.repeat(2)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; result.constraints = A.constraints&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; names are prefixed `top_` and `bottom_`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; compose_interleaved&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;rows &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;cols &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; result.trace = [ A_0 ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [ B_0 ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [ A_1 ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [ B_1 ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [ ... ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; A.constraints.interleave(2);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; B.constraints.interleave(2).shift(1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; result.constraints = union(A.constraints, B.constraints)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; names are prefixed `odd_` and `even_`.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; TODO: It is possible that a pair of constraints on odd&#x2F;even&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; rows are the same and can be replaced by a single constraint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; repeated.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; fold&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;    require&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt;cols &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; result.trace = [ A_(0, 0...n) ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [ A_(0, n..2n) ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [ A_(1, 0...n) ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [ A_(1, n..2n) ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F;                [     ...      ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; A.constraints.interleave(2).shift_half(1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; result.constraints = A.constraints&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; names are unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; We can skip renaming if there are no collisions. This will have to be done on a global basis, not a per name, basis. This can lead to breakage when a subcomponent adds a new name.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-combinators&quot;&gt;Further combinators&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s useful to add a helper function creating no-op components. This allows doing things like &lt;code&gt;fold(compose_horizontal(A, empty(A.rows, 1))&lt;&#x2F;code&gt; to do a fold where &lt;code&gt;A&lt;&#x2F;code&gt; has an odd number of columns.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; empty&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;rows&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; cols&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using these, we can implement more complex operations:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; fold_padded&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; repeats&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; fit_horizontal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; B&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Same as compose_horizontal, but it will do whatever folds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; and paddings are necessary to make A.rows == B.rows.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;example&quot;&gt;Example&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; transaction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;    initial_balances&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Balances&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;    txs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Transaction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Balances&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; air&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; fit_horizontal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        compose_vertical&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;            compose_vertical&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                compose_horizontal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                    merkle_proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;old_maker_buy_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;leaf&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;old_maker_buy_leaf&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                    merkle_proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;new_maker_buy_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;leaf&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;new_maker_buy_leaf&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                compose_horizontal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                    merkle_proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;old_maker_sell_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;leaf&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;old_maker_sell_leaf&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                    merkle_proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;new_maker_sell_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;leaf&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;new_maker_sell_leaf&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;            compose_vertical&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                compose_horizontal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                    merkle_proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                    merkle_proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                compose_horizontal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                    merkle_proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                    merkle_proof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    air&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add_constraint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;air&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;old_maker_buy_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-call z-rust&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;         -&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; air&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;old_maker_sell_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        )&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; air&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;on_row&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    air&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;old_maker_buy_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;initial_balance_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    air&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;relabel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;new_maker_sell_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;final_balance_root&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; TODO: Drop all other labels. Alternatively, replace the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; set of labels in one operation.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; starkdex&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;    initial_balances&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Balances&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;    txs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Transaction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Balances&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; AirComponent&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust z-storage z-modifier&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; component&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; txs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pad_to_power_of_two&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-caps z-rust&quot;&gt;EMPTY_TRANSACTION&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;map&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;transaction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;binary_tree&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;compose_vertical&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; TODO: Add constraints tying roots together.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;impl&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; trace&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; isize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; RationalExpression&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;trait&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Component&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Claim&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;    type&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Witness&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; dimensions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self z-rust&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; set_projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt;projection&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt;usize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type z-numeric z-rust&quot;&gt; isize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; constraints&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-self z-rust&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-rust&quot;&gt; claim&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Claim&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Vec&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;RationalExpression&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-brackets z-angle z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; witness&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Claim&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust at 0x</title>
        <published>2019-11-06T00:00:00+00:00</published>
        <updated>2019-11-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/rust-at-0x/"/>
        <id>https://2π.com/19/rust-at-0x/</id>
        
        <content type="html" xml:base="https://2π.com/19/rust-at-0x/">&lt;h1 id=&quot;rust-at-0x&quot;&gt;Rust at 0x&lt;&#x2F;h1&gt;
&lt;p&gt;Our goals for the CI are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;🤖 Automate as much as possible&lt;&#x2F;li&gt;
&lt;li&gt;🧐 Provide QA metrics like coverage&lt;&#x2F;li&gt;
&lt;li&gt;🏎️ Keep PR acceptance time under 5 min.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ci-setup&quot;&gt;CI Setup&lt;&#x2F;h2&gt;
&lt;p&gt;[Insert screencap from CircleCI]&lt;&#x2F;p&gt;
&lt;h2 id=&quot;linters&quot;&gt;Linters&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;rustfmt&lt;&#x2F;code&gt;, &lt;code&gt;clippy&lt;&#x2F;code&gt;, &lt;code&gt;codechecks&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We enable lot&#x27;s of lints in &lt;code&gt;rustfmt.toml&lt;&#x2F;code&gt; and enable many clippy rules in &lt;code&gt;lints.rs&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fast-builds&quot;&gt;Fast builds&lt;&#x2F;h2&gt;
&lt;p&gt;Build containers with precompiles, &lt;code&gt;sccache&lt;&#x2F;code&gt; + cache. Parallel builds using artifacts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;checking-for-nostd&quot;&gt;Checking for &lt;code&gt;nostd&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;webassembly-builds&quot;&gt;WebAssembly builds&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;wasm-gc&lt;&#x2F;code&gt;, &lt;code&gt;twiggy&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;code-coverage&quot;&gt;Code Coverage&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;users.rust-lang.org&#x2F;t&#x2F;howto-generating-a-branch-coverage-report&#x2F;8524&lt;&#x2F;p&gt;
&lt;h2 id=&quot;to-do-tracking&quot;&gt;&#x27;To do&#x27; tracking&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;more-tools&quot;&gt;More tools&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;cargo-outdated&lt;&#x2F;code&gt;, &lt;code&gt;cargo-audit&lt;&#x2F;code&gt;, &lt;code&gt;cargo-geiger&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;list-of-hacks-and-workarrounds&quot;&gt;List of hacks and workarrounds&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We use &lt;code&gt;Cargo.toml&lt;&#x2F;code&gt;&#x27;s replace to inject a local crate named &lt;code&gt;hex-literal&lt;&#x2F;code&gt; to override the one used by &lt;code&gt;substrate-runtime&lt;&#x2F;code&gt;. The outdated version used by substrate is not compatible with &lt;code&gt;nostd&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;We need to copy &lt;code&gt;lints.rs&lt;&#x2F;code&gt; manually to each &lt;code&gt;lib.rs&lt;&#x2F;code&gt; and &lt;code&gt;main.rs&lt;&#x2F;code&gt; file. The CI &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xProject&#x2F;OpenZKP&#x2F;blob&#x2F;7f7eff19ad45a5c728399f4cb4372d13691a6534&#x2F;.circleci&#x2F;config.yml#L313&quot;&gt;checks&lt;&#x2F;a&gt; that this is done correctly. There is currently no way to share a clippy configuration in a Cargo worskpace. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;cargo&#x2F;issues&#x2F;5034&quot;&gt;Relevant issue&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;There is no structured way to reject includes of &lt;code&gt;std&lt;&#x2F;code&gt; libraries in a &lt;code&gt;nostd&lt;&#x2F;code&gt; build. If these get included things will fail far down the pipeline when linking the WASM blob, with no indication of the origin. To force the build to immediately on usage of &lt;code&gt;std&lt;&#x2F;code&gt;, we build for a target that has no standard library support. In our case we make an ARM Cortex M3 build. This build will fail.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Cargo does not support &lt;code&gt;--no-default-features&lt;&#x2F;code&gt; when building a workspace. To work arround we loop over the list of packages.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;const [T; N]&lt;&#x2F;code&gt; where &lt;code&gt;T&lt;&#x2F;code&gt; does not implement &lt;code&gt;Copy&lt;&#x2F;code&gt; can not be initialized using a repeat expression &lt;code&gt;[t; N]&lt;&#x2F;code&gt;. To work around we manually repeat &lt;code&gt;t&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Procedural macros for expressions require three additional crates to be implemented: 1) A regular library containing the macro implementations over &lt;code&gt;proc_macro2::TokenStream&lt;&#x2F;code&gt;, 2) An implementation crate containing &lt;code&gt;proc_macro::TokenStream&lt;&#x2F;code&gt; wrappers with &lt;code&gt;proc-macro = true&lt;&#x2F;code&gt; set. 3) A crate &#x2F; See the proc-macro-hack &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;proc-macro-hack&quot;&gt;docs&lt;&#x2F;a&gt;. The additional library in our case comes from the requirement that macro functions are available in a library for composition.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Cargo doc markdown does not support Latex formulas. We work arround this by including the Katex javascript library.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Cargo doc does not support the &lt;code&gt;--html-in-header&lt;&#x2F;code&gt; argument from rustdoc. We work arround this using the &lt;code&gt;RUSTDOC_ARGS&lt;&#x2F;code&gt; environment variable, but this can not be automated using cargo aliases. TODO: Does this actually work?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The no-std build for ARM Cortex M3 requires nightly, we can not automate this using cargo aliases. We workarround this by manually specifing &lt;code&gt;cargo +nigthly&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Macros live outside of the namespacing system.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Code coverage requires nightly and non-incremental build: https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;42524&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The code coverage build requires a large number of compiler flags, and some of them don&#x27;t always work. https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;rust&#x2F;issues&#x2F;63047&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The following multi-stage rube-goldberg workarround deserves special mention:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The feature flag system in cargo is intened to be strictly additive. But the absense of the &lt;code&gt;std&lt;&#x2F;code&gt; flag is a feature. Cargo will readily take unions on flags during build processes, and this leads to failures, in particular when:&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If a dev-dependency depends on some feature flag being set on a package, that feature flag will also be set for the regular build. In particular our benchmarking rig &lt;code&gt;criterion&lt;&#x2F;code&gt; sets the &lt;code&gt;std&lt;&#x2F;code&gt; flag on some of our dependencies, breaking the &lt;code&gt;nostd&lt;&#x2F;code&gt; build. To work arround this, we would like to make dev-dependencies optional, but:&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Dev-dependencies can not be optional. To work arround this, we turn all dev-dependencies into regular optional dependencies behind feature flags like &lt;code&gt;test&lt;&#x2F;code&gt; and &lt;code&gt;bench&lt;&#x2F;code&gt;. We use &lt;code&gt;required-features&lt;&#x2F;code&gt; to make sure these flags are set for test and bench builds. When running a test, we need to do &lt;code&gt;cargo test --features=test&lt;&#x2F;code&gt;. But:&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In a worskpace command, you can not provide feature flags like &lt;code&gt;--features=test&lt;&#x2F;code&gt;. The only flag available is &lt;code&gt;--all-features&lt;&#x2F;code&gt;, which is what we use. To avoid cumbersome commands, we provide aliases for build and test. (See https:&#x2F;&#x2F;github.com&#x2F;rust-lang&#x2F;cargo&#x2F;pull&#x2F;7507)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>DEEP-FRING (DEEP-FRI over Rings)</title>
        <published>2019-11-03T00:00:00+00:00</published>
        <updated>2019-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/deep-frying/"/>
        <id>https://2π.com/19/deep-frying/</id>
        
        <content type="html" xml:base="https://2π.com/19/deep-frying/">&lt;h1 id=&quot;deep-fring-deep-fri-over-rings&quot;&gt;DEEP-FRING (DEEP-FRI over Rings)&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; &lt;em&gt;Generalize FRI, Schwartz-Zippel and FFT to a commutative ring of the form &lt;span class=&quot;math math-inline&quot;&gt;R = \mathbb Z&#x2F;m \mathbb Z&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;m = 2^b ⋅ k&lt;&#x2F;span&gt; or something similar.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We want this to be able to construct a &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt; sub-ring that captures the behaviour of binary numbers without much fuzz.&lt;&#x2F;p&gt;
&lt;p&gt;We can tweak &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; to guarantee the existence of roots of unity of order &lt;span class=&quot;math math-inline&quot;&gt;2^r&lt;&#x2F;span&gt;, which will power FRI and FFT.&lt;&#x2F;p&gt;
&lt;p&gt;The ring &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Commutative_ring&quot;&gt;Commutative&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Not &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Integral_domain&quot;&gt;integral&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Finite_ring&quot;&gt;Finite&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Noetherian_ring&quot;&gt;Noetherian&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Artinian_ring&quot;&gt;Artinian&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Product_ring&quot;&gt;product ring&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Consequently, the ring of polynomials over it, &lt;span class=&quot;math math-inline&quot;&gt;R[X]&lt;&#x2F;span&gt; is&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Commutative&lt;&#x2F;li&gt;
&lt;li&gt;Not integral&lt;&#x2F;li&gt;
&lt;li&gt;Noetherian&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; We need an integral domain in order to have the common rules on degree of the polynomial: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Degree_of_a_polynomial#Behavior_under_polynomial_operations&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt;  It does seem that this only reduces the degrees of the polynomials, and potentially only with neglible probability. So much of the theory can be salvaged. (i.e. &lt;span class=&quot;math math-inline&quot;&gt;\deg (PQ) \leq (\deg P)(\deg Q)&lt;&#x2F;span&gt;).&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;roots-of-unity&quot;&gt;Roots of unity&lt;&#x2F;h2&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;schwartz-zippel&quot;&gt;Schwartz-Zippel&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;mathoverflow.net&#x2F;questions&#x2F;186074&#x2F;can-schwartz-zippel-be-formulated-for-commutative-rings-instead-of-fields&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;unique-factorization&quot;&gt;Unique factorization&lt;&#x2F;h2&gt;
&lt;p&gt;For some theorems we need Polynomials to have a unique factorization into irreducible factors (i.e. in Plonk&#x27;s multi-set check). This requires the field to be a unique factorization domain, but it isn&#x27;t. In fact, it is not even an integral ring.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Unique_factorization_domain&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_ring#Factorization_in_K[X]&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;fft-fri&quot;&gt;FFT+FRI&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;users.cs.duke.edu&#x2F;~reif&#x2F;courses&#x2F;alglectures&#x2F;reif.lectures&#x2F;ALG3.2.pdf&lt;&#x2F;p&gt;
&lt;p&gt;FFT Seems to not be an issue as long as the roots of unity exist. FRI will follow the same path.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;reed-solomon-over-rings&quot;&gt;Reed-solomon over Rings&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;hal.inria.fr&#x2F;hal-00670004v2&#x2F;document&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;commutative-rings&quot;&gt;Commutative rings&lt;&#x2F;h2&gt;
&lt;p&gt;A &lt;em&gt;commutative ring&lt;&#x2F;em&gt; is a set &lt;span class=&quot;math math-inline&quot;&gt;\mathbb R&lt;&#x2F;span&gt; with two binary operations &lt;span class=&quot;math math-inline&quot;&gt;+&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;⋅&lt;&#x2F;span&gt; and two elements &lt;span class=&quot;math math-inline&quot;&gt;0, 1 \in \mathbb R&lt;&#x2F;span&gt; s.t.:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Abelian group under addition.
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;+&lt;&#x2F;span&gt; is closed
&lt;span class=&quot;math math-inline&quot;&gt;a + b \in \mathbb R&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;+&lt;&#x2F;span&gt; is commutative
&lt;span class=&quot;math math-inline&quot;&gt;a + b = b + a&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;+&lt;&#x2F;span&gt; is associative
&lt;span class=&quot;math math-inline&quot;&gt;(a + b) + c = a + (b + c)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt; is an additive identity
&lt;span class=&quot;math math-inline&quot;&gt;a + 0 = a&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;additive inverses
&lt;span class=&quot;math math-inline&quot;&gt;a + (-a) = 0&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Monoid under multiplication
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;⋅&lt;&#x2F;span&gt; is closed
&lt;span class=&quot;math math-inline&quot;&gt;a ⋅ b \in \mathbb R&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;⋅&lt;&#x2F;span&gt; is commutative
&lt;span class=&quot;math math-inline&quot;&gt;a ⋅ b = b ⋅ a&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;⋅&lt;&#x2F;span&gt; is associative
&lt;span class=&quot;math math-inline&quot;&gt;(a ⋅ b) ⋅ c = a ⋅ (b ⋅ c)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; is a multiplicative identity
&lt;span class=&quot;math math-inline&quot;&gt;a ⋅ 1 = a&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Multiplication is distributive over addition
&lt;ul&gt;
&lt;li&gt;distributivity&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Q: Additive inverses unique?
Q: Multiplicative inverses unique?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Additive inverse). &lt;span class=&quot;math math-inline&quot;&gt;-a&lt;&#x2F;span&gt;. By the axioms these always exist.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Multiplicative inverse). &lt;span class=&quot;math math-inline&quot;&gt;a^{-1}&lt;&#x2F;span&gt;. These do not necessarily exist.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Unit). If &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; has an inverse, it is called a unit.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Zero divisor). If &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; has an element &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;ab = 0&lt;&#x2F;span&gt;, it is called a zero divisor.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Definition.&lt;&#x2F;strong&gt; &lt;em&gt;(Nilpotent). If &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; has a positive number &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;a^n = 0&lt;&#x2F;span&gt;, it is called nilpotent.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; If &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; is nilpotent then &lt;span class=&quot;math math-inline&quot;&gt;1-a&lt;&#x2F;span&gt; is a unit.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Root_of_unity_modulo_n&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Root_of_unity_modulo_n#Finding_an_n_with_a_primitive_k-th_root_of_unity_modulo_n&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Space-time constraints</title>
        <published>2019-11-03T00:00:00+00:00</published>
        <updated>2019-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/space-time-constraints/"/>
        <id>https://2π.com/19/space-time-constraints/</id>
        
        <content type="html" xml:base="https://2π.com/19/space-time-constraints/">&lt;h1 id=&quot;space-time-constraints&quot;&gt;Space-time constraints&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; Simulate a form of (random access) memory using bivariate polynomials &lt;span class=&quot;math math-inline&quot;&gt;P\in\F[X,Y]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Intuitively, we lay out the memory with time on the &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; axis and space (addresses) on the &lt;span class=&quot;math math-inline&quot;&gt;Y&lt;&#x2F;span&gt; axis.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;stack&quot;&gt;Stack&lt;&#x2F;h2&gt;
&lt;p&gt;Start with a simple stack where &lt;span class=&quot;math math-inline&quot;&gt;P(𝜔_n^i, 𝜔_m^j)&lt;&#x2F;span&gt; is the value of stack location &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt; at time &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The initial polynomial is the zero polynomial on our basis &lt;span class=&quot;math math-inline&quot;&gt;𝜔^j&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(0, Y) = Y^m - 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; It looks like we can handle the memory sparsely, both in the polyonmial form and in the merkle trees.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_{m,j}(Y) = \frac{𝜔_m^j}{m} \frac{Y^m - 1}{Y-𝜔_m^j}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;push-pop&quot;&gt;Push &amp;amp; Pop&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Constraint.&lt;&#x2F;strong&gt; &lt;em&gt;(Push). Rotate all elements to the right, add an element &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;. Has the following constraints:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X, 𝜔_m^{m-1}) &amp;amp;= 0 \\
P(𝜔_n ⋅ X, Y) &amp;amp;= P(X, 𝜔_m ⋅ Y) + x ⋅ L_0(Y)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Constraint.&lt;&#x2F;strong&gt; &lt;em&gt;(Pop). Operate the push constraint in reverse.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;random-access&quot;&gt;Random access&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Constraint.&lt;&#x2F;strong&gt; &lt;em&gt;(Compare and swap). Replace the value at &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt; from &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; to &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X, 𝜔_m^j) &amp;amp;= a \\
P(𝜔_n ⋅ X, Y) &amp;amp;= P(X, Y) + (b - a) ⋅ L_j(Y)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The problem here is that we need to encode the &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt; somehow, either in a precomputed polynomial or as a column. Since all usage of &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt; will be in the form &lt;span class=&quot;math math-inline&quot;&gt;𝜔_m^j&lt;&#x2F;span&gt; we will use that instead. the final constraint will look like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(X, Q(X)) &amp;amp;= a \\
P(𝜔_n ⋅ X, Y) &amp;amp;= P(X, Y) + (b - a) ⋅ \frac{Q(X)}{m} \frac{Y^m - 1}{Y-Q(X)}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; What if &lt;span class=&quot;math math-inline&quot;&gt;Q(X)&lt;&#x2F;span&gt; is not of the form &lt;span class=&quot;math math-inline&quot;&gt;𝜔_m^j&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;The first constraint has a degree bound of &lt;span class=&quot;math math-inline&quot;&gt;(\deg P)⋅(\deg Q) = n^2 m&lt;&#x2F;span&gt;. So far we have only handle constant constraint bounds. How do we LDE test this efficiently?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;We could add a temporary value? &lt;span class=&quot;math math-inline&quot;&gt;t = Q(X), P(X, t) = a&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In addition, to force &lt;span class=&quot;math math-inline&quot;&gt;Q(X)&lt;&#x2F;span&gt; to be a root of unity, we can add a constraint&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Q(X)^m = 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;which has degree bound &lt;span class=&quot;math math-inline&quot;&gt;m\deg Q = nm&lt;&#x2F;span&gt;. Again, how do we LDE-test this efficiently?&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;polynomial-composition&quot;&gt;Polynomial composition&lt;&#x2F;h2&gt;
&lt;p&gt;Both approaches above hit the problem that we need to low-degree-test an expression of the form &lt;span class=&quot;math math-inline&quot;&gt;P(Q(X))&lt;&#x2F;span&gt;. The straightforward approach has degree bound &lt;span class=&quot;math math-inline&quot;&gt;(\deg P)(\deg Q)&lt;&#x2F;span&gt; which is quadratic. This will kill prover performance and more than double proof size.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; &lt;em&gt;Find a way to LDE test polynomial compositions efficiently.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Specify goal more concretely.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_decomposition&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.math.mcgill.ca&#x2F;rickards&#x2F;PDFs&#x2F;amer.math.monthly.118.04.358-rickards.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cs.cornell.edu&#x2F;~kozen&#x2F;Papers&#x2F;poly.pdf&lt;&#x2F;p&gt;
&lt;p&gt;Chebyshev polynomials have the nesting property &lt;span class=&quot;math math-inline&quot;&gt;T_n(T_m(X)) = T_{mn}(X)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;dspace.mit.edu&#x2F;bitstream&#x2F;handle&#x2F;1721.1&#x2F;71792&#x2F;Kedlaya-2011-FAST%20POLYNOMIAL%20FACT.pdf?sequence=1&amp;amp;isAllowed=y
https:&#x2F;&#x2F;www.cse.iitk.ac.in&#x2F;users&#x2F;nitin&#x2F;courses&#x2F;CS681-2016-17-II&#x2F;pdfs&#x2F;slides-dwivedi.pdf
Evaluates &lt;span class=&quot;math math-inline&quot;&gt;f(g(x)) \mod h(x)&lt;&#x2F;span&gt; in less then &lt;span class=&quot;math math-inline&quot;&gt;\mathcal O(n^2)&lt;&#x2F;span&gt; time using FFTs. =&amp;gt; Read.
http:&#x2F;&#x2F;users.cms.caltech.edu&#x2F;~umans&#x2F;papers&#x2F;U07.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.cse.iitk.ac.in&#x2F;users&#x2F;nitin&#x2F;courses&#x2F;CS681-2016-17-II&#x2F;pdfs&#x2F;slides-dwivedi.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;citeseer.ist.psu.edu&#x2F;viewdoc&#x2F;download;jsessionid=611B98690C1028968AED2736F9E1E77C?doi=10.1.1.51.3154&amp;amp;rep=rep1&amp;amp;type=pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;0807.3578.pdf&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Aside: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bruun&#x27;s_FFT_algorithm&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fast extrapolation from ⟨ω⟩</title>
        <published>2019-11-02T00:00:00+00:00</published>
        <updated>2019-11-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/fast-extrapolation-from/"/>
        <id>https://2π.com/19/fast-extrapolation-from/</id>
        
        <content type="html" xml:base="https://2π.com/19/fast-extrapolation-from/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;fast-extrapolation-from-o&quot;&gt;Fast extrapolation from ⟨ω⟩&lt;&#x2F;h1&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P ∈ \F[X]&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\deg P &amp;lt; n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;ω&lt;&#x2F;span&gt; a &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;-primitive root of unity. Evaluate &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; on the subgroup generated by &lt;span class=&quot;math math-inline&quot;&gt;ω&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
a_i = P(ω^i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal.&lt;&#x2F;strong&gt; &lt;em&gt;Given only &lt;span class=&quot;math math-inline&quot;&gt;a_i&lt;&#x2F;span&gt; and arbitrary &lt;span class=&quot;math math-inline&quot;&gt;z ∈ \F&lt;&#x2F;span&gt;, efficiently evaluate &lt;span class=&quot;math math-inline&quot;&gt;P(z)&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Observe the Lagrange basis for &lt;span class=&quot;math math-inline&quot;&gt;⟨ω⟩&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i(X) = c_i \frac{X^n - 1}{X-ω^i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt; is set such that &lt;span class=&quot;math math-inline&quot;&gt;L_i(ω^j) = \delta_{ij}&lt;&#x2F;span&gt; (i.e. one when &lt;span class=&quot;math math-inline&quot;&gt;i = j&lt;&#x2F;span&gt; and zero otherwise). Using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;ZxR4-iKsRRqqcMtHYj8duA&quot;&gt;L&#x27;Hospital rule&lt;&#x2F;a&gt; we find:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\left. \frac{X^n - 1}{X-\omega^i} \right\vert_{X=\omega^i} &amp;amp;= \\
\left. \frac{n⋅X^{n-1}}{1} \right\vert_{X=\omega^i} &amp;amp;= \\
n ⋅ \omega^{i(n-1)} &amp;amp;= \\
\frac{n}{\omega^i}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and thus&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L_i(X) = \frac{\omega^i}{n} \frac{X^n - 1}{X-\omega^i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(z) &amp;amp;= 
\sum_i a_i ⋅ L_i(z) \\&amp;amp;=
\sum_i a_i ⋅ \frac{\omega^i}{n} \frac{z^n - 1}{z - \omega^i} \\&amp;amp;=
\frac{z^n - 1}{n} \sum_i \frac{a_i ⋅ \omega^i}{z - \omega^i}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{O}(1)&lt;&#x2F;span&gt; space and &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{O}(m + \log n)&lt;&#x2F;span&gt; time, where &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; is the number of non-zero entries in &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>L&#x27;Hôpital rules in finite fields</title>
        <published>2019-11-02T00:00:00+00:00</published>
        <updated>2019-11-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/lhospital-rules-in-finite-fields/"/>
        <id>https://2π.com/19/lhospital-rules-in-finite-fields/</id>
        
        <content type="html" xml:base="https://2π.com/19/lhospital-rules-in-finite-fields/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\d{\operatorname{d}\!}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;l-hopital-rules-in-finite-fields&quot;&gt;L&#x27;Hôpital rules in finite fields&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Warning.&lt;&#x2F;strong&gt; &quot;I have only proved it correct, not tried it.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P,Q ∈ \F[X]&lt;&#x2F;span&gt;. Consider the fraction&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{P(X)}{Q(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If this fraction is &lt;span class=&quot;math math-inline&quot;&gt;\dfrac 00&lt;&#x2F;span&gt; indeterminate in some value &lt;span class=&quot;math math-inline&quot;&gt;α ∈ \F&lt;&#x2F;span&gt;, we can eliminate the zeros we found:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{P(X)&#x2F;(X - α)}{Q(X)&#x2F;(X - α)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If necessary we can repeat this until the fraction is no longer indeterminate.&lt;&#x2F;p&gt;
&lt;p&gt;In real numbers, there is an alternative trick, where instead we differentiate the numbers:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\frac{\d}{\d X} P(X)}{\frac{\d}{\d X} Q(X)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;again, repeated as necessary. This trick can be applied in Finite Fields too, if we use formal derivatives.&lt;&#x2F;p&gt;
&lt;p&gt;Intuition suggest that L&#x27;Hospital&#x27;s rule should give the same result at &lt;span class=&quot;math math-inline&quot;&gt;X = α&lt;&#x2F;span&gt;. This essentially boils down to the following identity:&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P,Q ∈ \F[X]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;α ∈ \F&lt;&#x2F;span&gt;, then&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left. \frac{\frac{\d}{\d X} P(X)}{\frac{\d}{\d X} Q(X)} \right\vert_{X = α} =
\left. \frac{P(X)&#x2F;(X - α)}{Q(X)&#x2F;(X - α)} \right\vert_{X = α}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; Follows directly from below lemma.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P ∈ \F[X]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;α ∈ \F&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;P(α) = 0&lt;&#x2F;span&gt; then&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left. \frac{\d}{\d X} P(X) \right\vert_{X = α} =
\left. \frac{P(X)}{X - α} \right\vert_{X = α}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; Substitute &lt;span class=&quot;math math-inline&quot;&gt;X = U + α&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\frac{\d}{\d X} = \frac{\delta U}{\delta X}\frac{\d}{\d U} = \frac{\d}{\d U}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\left. \frac{\d}{\d U} P(U + α) \right\vert_{U = 0} &amp;amp;=
\left. \frac{P(U + α)}{U} \right\vert_{U = 0}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Write &lt;span class=&quot;math math-inline&quot;&gt;S(U) = P(U + α)&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;S(0) = 0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;S(U) = s_1 U + s_2 U^2 + ⋯&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\left. \frac{\d}{\d U} S(U) \right\vert_{U = 0} &amp;amp;=
\left. \frac{S(U)}{U} \right\vert_{U = 0}
\\
\left. \frac{\d}{\d U} \left(s_1 U + s_2 U^2 + ⋯ \right) \right\vert_{U = 0} &amp;amp;=
\left. \frac{s_1 U + s_2 U^2 + ⋯}{U} \right\vert_{U = 0}
\\
\left. \left(s_1 + 2 s_2 U + 3 s_3 U^2 ⋯ \right) \right\vert_{U = 0} &amp;amp;=
\left. \left(s_1 + s_2 U + s_3 U^2 ⋯ \right) \right\vert_{U = 0}
\\
s_1  &amp;amp;= s_1
\end{aligned}
&lt;&#x2F;span&gt;
□&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; The left-hand side expression does not depend on &lt;span class=&quot;math math-inline&quot;&gt;α&lt;&#x2F;span&gt;, so the differentiated polynomial will give the divided out values wherever &lt;span class=&quot;math math-inline&quot;&gt;P(X) = 0&lt;&#x2F;span&gt;. &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; of &lt;span class=&quot;math math-inline&quot;&gt;\deg P = n&lt;&#x2F;span&gt; has at most &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; roots and interpolates &lt;span class=&quot;math math-inline&quot;&gt;n + 1&lt;&#x2F;span&gt; points. &lt;span class=&quot;math math-inline&quot;&gt;P&amp;#39;(X)&lt;&#x2F;span&gt; has &lt;span class=&quot;math math-inline&quot;&gt;\deg P&amp;#39; = n - 1&lt;&#x2F;span&gt; and interpolates the &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; roots and their associated divided out values.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Corrolary.&lt;&#x2F;strong&gt; &lt;em&gt;The formal derivative of a polynomial is the polynomial that interpolates all the &#x27;divided out zeros&#x27;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; What if the the original polynomial contains zeros of higher multiplicity?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; What if the original polynomial contains irreducible factors of higher degree?&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;The above suggest a more general theorem:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P ∈ \F[X]&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;z ∈ \F&lt;&#x2F;span&gt;, the following holds:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left. \frac{\d}{\d X} P(X) \right\vert_{X = z} =
\left. \frac{P(X) - P(z)}{X - z} \right\vert_{X = z}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = \prod_i (X - a_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Can this be evaluated using dual numbers? See https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dual_number .&lt;&#x2F;p&gt;
&lt;p&gt;Evaluate over &lt;span class=&quot;math math-inline&quot;&gt;\F[\bar X,Ε]&#x2F;(Ε^2)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;X = \bar X + Ε&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = \prod_i (\bar X + Ε - a_i)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The result will be &lt;span class=&quot;math math-inline&quot;&gt;P(\bar X) + \left(\frac{\d}{\d \bar X} P(\bar X)\right) E&lt;&#x2F;span&gt;, i.e. the first derivative will be the coefficient of &lt;span class=&quot;math math-inline&quot;&gt;E&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Using a higher cut-off &lt;span class=&quot;math math-inline&quot;&gt;\F[\bar X,Ε]&#x2F;(Ε^n)&lt;&#x2F;span&gt;, higher order derivates can be obtained.&lt;&#x2F;p&gt;
&lt;p&gt;The division function can be modified to automatically apply L&#x27;Hospital&#x27;s rule when it faces a &lt;span class=&quot;math math-inline&quot;&gt;\frac 00&lt;&#x2F;span&gt; indeterminate. This allows an evaluation strategy that would normally fail suceed anyway when executed over the dual numbers.&lt;&#x2F;p&gt;
&lt;p&gt;Take for example the &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;-th Lagrange interpolants over &lt;span class=&quot;math math-inline&quot;&gt;⟨ω⟩&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{X^n - 1}{X - ω^i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Plonk&#x27;s Permutation check</title>
        <published>2019-10-31T00:00:00+00:00</published>
        <updated>2019-10-31T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/plonks-permutation-check/"/>
        <id>https://2π.com/19/plonks-permutation-check/</id>
        
        <content type="html" xml:base="https://2π.com/19/plonks-permutation-check/">&lt;h1 id=&quot;plonk-s-permutation-check&quot;&gt;Plonk&#x27;s Permutation check&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\F{\mathbb{F}}
\gdef\({\left (}
\gdef\){\right )}
\gdef\norm#1{\left\vert #1 \right\vert}
\gdef\set#1{\mathcal{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See the Plonk paper https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2019&#x2F;953. Here follow some meditations on chapter 5 and appendix A.&lt;&#x2F;p&gt;
&lt;p&gt;Plonk uses the fact that polynomials can be uniquely represented as a vector of coefficients and as a multiset of irreducible factors to efficiently proof that one vector is a permutation of another. This is done using applications of the Schwartz-Zippel lemma.&lt;&#x2F;p&gt;
&lt;p&gt;IMHO, the two key innovations in Plonk&#x27;s permutation check are 1) a protocol for multiset equality checking and 2) a way of encoding a permutation check as a multiset equality check over pairs.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma A.2.&lt;&#x2F;strong&gt; &lt;em&gt;(Schwartz-Zippel). Let &lt;span class=&quot;math math-inline&quot;&gt;P(\vec X) ∈ \F_p[X^n]&lt;&#x2F;span&gt; be non-zero and &lt;span class=&quot;math math-inline&quot;&gt;\vec α ∈ S ⊆ \F_p^n&lt;&#x2F;span&gt; uniform random, then&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\Pr\left[P(\vec α) = 0 \right] ≤ \frac{\deg P}{\norm S}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Corrolary.&lt;&#x2F;strong&gt; &lt;em&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;P(X) ∈ \F_p[X]&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\deg P ≪ p&lt;&#x2F;span&gt; and uniform random &lt;span class=&quot;math math-inline&quot;&gt;α ∈ \F_p&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;P(α) = 0&lt;&#x2F;span&gt; with non-neglibile probability only when &lt;span class=&quot;math math-inline&quot;&gt;P = 0&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Corrolary.&lt;&#x2F;strong&gt; &lt;em&gt;(Polynomial identity). Given &lt;span class=&quot;math math-inline&quot;&gt;P(X), Q(X) ∈ \F_p[X]&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\deg P,\deg Q ≪ p&lt;&#x2F;span&gt; and uniform random &lt;span class=&quot;math math-inline&quot;&gt;α ∈ \F_p&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;P(α) = Q(α)&lt;&#x2F;span&gt; with non-neglibile probability only when &lt;span class=&quot;math math-inline&quot;&gt;P = Q&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma A.3.&lt;&#x2F;strong&gt; &lt;em&gt;(Multiset equality) Given two multisets &lt;span class=&quot;math math-inline&quot;&gt;\set A, \set B&lt;&#x2F;span&gt; over &lt;span class=&quot;math math-inline&quot;&gt;\F_p&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;\norm{\set A}, \norm{\set  B} ≪ p&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;𝛾 ∈ \F&lt;&#x2F;span&gt; uniform random, then &lt;span class=&quot;math math-inline&quot;&gt;\set A = \set B&lt;&#x2F;span&gt; if the following holds with non-neglible probability:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\prod_{a ∈ \set A} \( a + 𝛾 \) =
\prod_{b ∈ \set B} \( b + 𝛾 \)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; Define &lt;span class=&quot;math math-inline&quot;&gt;P(X) ≝ \prod_{a ∈ A} (a + X)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q(X) ≝ \prod_{b ∈ B}(b + X)&lt;&#x2F;span&gt;. If the above holds with non-neglible probability then by the polynomial identity corrolary we have &lt;span class=&quot;math math-inline&quot;&gt;P = Q&lt;&#x2F;span&gt;. From the unique factorization of polynomials it follows that their irreducible factors are the same, which are given in their definition. From this follows &lt;span class=&quot;math math-inline&quot;&gt;\set A = \set B&lt;&#x2F;span&gt;. □&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; We do not require &lt;span class=&quot;math math-inline&quot;&gt;\norm{\set A} = \norm{\set B}&lt;&#x2F;span&gt; and the test will correctly fail when they are of unequal size.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Remark.&lt;&#x2F;strong&gt; Compared to lemma A.3 in the paper it is rephrased in terms of multisets and generalized to have multisets of unequal size. The protocol in chapter 5 is readily adjusted to become a multiset-equality protocol.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Rephrased permutation checking protocol as an instance of multiset-equality checking.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Is there utility in constructions where the irreducible factors are of higher degree?&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Lemma.&lt;&#x2F;strong&gt; &lt;em&gt;(Vector equality).&lt;&#x2F;em&gt; Given two vectors &lt;span class=&quot;math math-inline&quot;&gt;\vec a, \vec b ∈ \F_p^n&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;n ≪ p&lt;&#x2F;span&gt; and uniform random &lt;span class=&quot;math math-inline&quot;&gt;𝛽 ∈ \F_p&lt;&#x2F;span&gt;, then &lt;span class=&quot;math math-inline&quot;&gt;\vec a = \vec b&lt;&#x2F;span&gt; if the following holds with non-neglible probability:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{i ∈ [n]} a_i ⋅ 𝛽^i =
\sum_{i ∈ [n]} b_i ⋅ 𝛽^i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; Define &lt;span class=&quot;math math-inline&quot;&gt;P(X) ≝ \sum_{i ∈ [n]} a_i ⋅ X^i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q(X) ≝ \sum_{i ∈ [n]} a_i ⋅ X^i&lt;&#x2F;span&gt;. If the above holds with non-neglible probability then by the polynomial identity corrolary we have &lt;span class=&quot;math math-inline&quot;&gt;P = Q&lt;&#x2F;span&gt;. From the uniqueness of the coefficient representation of polynomials it follows that &lt;span class=&quot;math math-inline&quot;&gt;\forall_{i \in [n]} a_i = b_i&lt;&#x2F;span&gt; and therefore &lt;span class=&quot;math math-inline&quot;&gt;\vec a = \vec b&lt;&#x2F;span&gt;. □&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Remark.&lt;&#x2F;strong&gt; If &lt;span class=&quot;math math-inline&quot;&gt;\vec a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec b&lt;&#x2F;span&gt; have unequal size, the test can incorrectly pass if the final entries of the longer vector are zero, otherwise it should work correctly. The stated form requires them to be equal length. (&lt;em&gt;to do&lt;&#x2F;em&gt;: we could add a &lt;span class=&quot;math math-inline&quot;&gt;X^{n+1}&lt;&#x2F;span&gt; term to bind the length of the vector.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Note.&lt;&#x2F;strong&gt; In the permutation check we use the vector equality check with &lt;span class=&quot;math math-inline&quot;&gt;n=2&lt;&#x2F;span&gt;, i.e. pairs.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; &lt;em&gt;(Efficient composability). Show that we can do a multiset check over vectors with only two random variables.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;permutation-check&quot;&gt;Permutation check&lt;&#x2F;h3&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;\vec a, \vec b ∈ \F_p^n&lt;&#x2F;span&gt; and a permutation &lt;span class=&quot;math math-inline&quot;&gt;𝜎: [n] → [n]&lt;&#x2F;span&gt;. We want to show that &lt;span class=&quot;math math-inline&quot;&gt;b_i = a_{𝜎(i)}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;\vec c&lt;&#x2F;span&gt; with distinct values (i.e. &lt;span class=&quot;math math-inline&quot;&gt;c_i = c_j ⇔ i = j&lt;&#x2F;span&gt;). Compose the multiset and vector equality protocols to prove the following equality:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{Bmatrix}
(a_0, c_0) \\
(a_1, c_1) \\
(a_2, c_2) \\
⋮
\end{Bmatrix} = 
\begin{Bmatrix}
(b_0, c_{𝜎(0)}) \\
(b_1, c_{𝜎(1)}) \\
(b_2, c_{𝜎(2)}) \\
⋮
\end{Bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Proof.&lt;&#x2F;em&gt; Since the elements &lt;span class=&quot;math math-inline&quot;&gt;c_i&lt;&#x2F;span&gt; are unique, the pairs are unique and the multisets are just regular sets. Two sets are equal iff their elements can be brought in correspondance. Enumerate the elements as above, we are looking for correspondances between elements &lt;span class=&quot;math math-inline&quot;&gt;(a_i, c_i) ≟ (b_j, c_{𝜎(j)})&lt;&#x2F;span&gt;. The second element in the pair is equal only if &lt;span class=&quot;math math-inline&quot;&gt;i = 𝜎(j)&lt;&#x2F;span&gt;, this means a correspondance exists iff &lt;span class=&quot;math math-inline&quot;&gt;b_j = a_{𝜎(j)}&lt;&#x2F;span&gt;. □&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;Claim A.1.&lt;&#x2F;strong&gt; &lt;em&gt;If the following holds with non-negligible probability over random &lt;span class=&quot;math math-inline&quot;&gt;𝛽, 𝛾 \in \mathbb F&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
∏_i \( a_i + 𝛽 ⋅ i + 𝛾 \) =
∏_i \( b_i + 𝛽 ⋅ 𝜎\(i\) + 𝛾 \)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;then &lt;span class=&quot;math math-inline&quot;&gt;∀_{i \in [n]} b_i = a_{𝜎(i)}&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Demostrate this follows concretely from the above.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Efficient patterns of zeros of certain polynomials</title>
        <published>2019-08-10T00:00:00+00:00</published>
        <updated>2019-08-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/19/patterns-of-zeros/"/>
        <id>https://2π.com/19/patterns-of-zeros/</id>
        
        <content type="html" xml:base="https://2π.com/19/patterns-of-zeros/">&lt;h1 id=&quot;efficient-patterns-of-zeros-of-certain-polynomials&quot;&gt;Efficient patterns of zeros of certain polynomials&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;context&quot;&gt;Context&lt;&#x2F;h2&gt;
&lt;p&gt;In STARKs the computation is unrolled into a table:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;P_1(x)&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;P_2(x)&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\dots&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;P_n(x)&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\omega^0&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;a&lt;&#x2F;td&gt;&lt;td&gt;b&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\cdots&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;c&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\omega^1&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;d&lt;&#x2F;td&gt;&lt;td&gt;e&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\cdots&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;f&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\vdots&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\vdots&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\vdots&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\ddots&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\vdots&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\omega^{n-1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;g&lt;&#x2F;td&gt;&lt;td&gt;h&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\cdots&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;i&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Think of the columns as registers and the rows as sequential states in the computation.&lt;&#x2F;p&gt;
&lt;p&gt;The columns in table are interpreted as polynomials evaluated on powers of a root of unity &lt;span class=&quot;math math-inline&quot;&gt;\omega&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Constraints are now expressed as rational functions. Consider the constraint that &lt;span class=&quot;math math-inline&quot;&gt;P_2&lt;&#x2F;span&gt; is the sum of previous &lt;span class=&quot;math math-inline&quot;&gt;P_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;P_2&lt;&#x2F;span&gt; (Fibonacci constraint):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{
    P_2(\omega\cdot x) - P_1(x) - P_2(x)
}{
    (x^n - 1)&#x2F;(x - \omega^{n-1})
}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The numerator is an expression that is zero whenever the constraint holds between two rows. The denominator is zero whenever the constraint &lt;em&gt;should&lt;&#x2F;em&gt; hold. The division is exact only when the trace table is valid.&lt;&#x2F;p&gt;
&lt;p&gt;In STARKs, the verifier needs to evaluate the constraints once, given values of &lt;span class=&quot;math math-inline&quot;&gt;P_i&lt;&#x2F;span&gt;. For an efficient proof system, this the expression should be evaluable in complexity at most logarithmic in &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The above can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;O(\log n)&lt;&#x2F;span&gt; using binary exponentiation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;statement&quot;&gt;Statement&lt;&#x2F;h2&gt;
&lt;p&gt;Consider a large prime field &lt;span class=&quot;math math-inline&quot;&gt;\mathbb{F}_p&lt;&#x2F;span&gt; with a &lt;span class=&quot;math math-inline&quot;&gt;n = 2^k&lt;&#x2F;span&gt; order root of unity &lt;span class=&quot;math math-inline&quot;&gt;\omega&lt;&#x2F;span&gt;. That is, &lt;span class=&quot;math math-inline&quot;&gt;\omega^n = 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We are interested in constructing efficient polynomials which have their zeros at certain powers of this root. Efficient here means it can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;O(\log(n))&lt;&#x2F;span&gt; given arbitrary preprocessing.&lt;&#x2F;p&gt;
&lt;p&gt;Which patterns of zeros can be efficiently computed?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;positive-examples&quot;&gt;Positive examples&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;(x - ω^i)&lt;&#x2F;span&gt;  is zero at &lt;span class=&quot;math math-inline&quot;&gt;ω^i&lt;&#x2F;span&gt;. It can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;O(1)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;(x^n - 1)&lt;&#x2F;span&gt; is zeros at all powers of &lt;span class=&quot;math math-inline&quot;&gt;ω&lt;&#x2F;span&gt;. It is efficient because with repeated squaring it can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;O(log(n))&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;(x^{n&#x2F;m} - 1)&lt;&#x2F;span&gt; is zero at every &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;-th power of &lt;span class=&quot;math math-inline&quot;&gt;ω&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;combinators&quot;&gt;Combinators&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A(x) \cdot B(x)&lt;&#x2F;span&gt; is zero whenever &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; is zero. This is efficient if &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; are. Be careful that overlap changes multiplicity.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A(x) &#x2F; B(x)&lt;&#x2F;span&gt; is zero whenever &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; is zero, except when &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; is zero assuming the multiplicity of the zeros is one.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A(ω^i x)&lt;&#x2F;span&gt; has all zeros moved by &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt; places.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;open-questions&quot;&gt;Open questions&lt;&#x2F;h2&gt;
&lt;p&gt;Is there an efficient evaluation of the polynomial that is zero at &lt;span class=&quot;math math-inline&quot;&gt;\omega^0, \dots, \omega^{n&#x2F;2}&lt;&#x2F;span&gt;, i.e. only the first half of the table.&lt;&#x2F;p&gt;
&lt;p&gt;What about arbitrary ranges?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prelimiary-results&quot;&gt;Prelimiary results&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Reed-Solomon theory will explain which patterns result in sparse polynomials. The example problem will result in a dense polynomial. Takeaway: the example problem will require a clever way to evaluate a dense polynomial. We know these exist for some polynomials. (from discussion with Dimitry)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The general problem without precomputation is unsolvable. As we let &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt; grow to infinity, the number of patterns grows &lt;span class=&quot;math math-inline&quot;&gt;2^n&lt;&#x2F;span&gt;, but the number of efficient evaluation circuits grows as &lt;span class=&quot;math math-inline&quot;&gt;\log n&lt;&#x2F;span&gt;. This assumes we don&#x27;t use constants besides &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;. Takeaway: Any generic solution will require more than &lt;span class=&quot;math math-inline&quot;&gt;\log n&lt;&#x2F;span&gt; precomputation for the constants. (from discussion with Dan)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;appendix-why-is-this-field-interesting&quot;&gt;Appendix: why is this field interesting&lt;&#x2F;h2&gt;
&lt;p&gt;Arithmetic circuits are a generalization of boolean circuits. Finite fields offer richter math than booleans and some researcher believe this has opertunities for solving hard complexity theory problems.&lt;&#x2F;p&gt;
&lt;p&gt;I also believe the results in the field are not as widely known as they should be, for example, many people believe Horner&#x27;s evaluation is optimal. Given a polynomial&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x) = c_0 + c_1 x^1 + c_2 x^2 + \cdots  + c_n x^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Horner&#x27;s schema allows this to be evaluated using &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; multiplications and &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; additions:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{align}
p_0 &amp;amp;= 1 \\
p_{i+1} &amp;amp;= p_{i} \cdot x + c_{n-i} \\
P(x) &amp;amp;= p_n
\end{align}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Which takes &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; multiplications. But &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;doi.org&#x2F;10.1002&#x2F;cpa.3160250405&quot;&gt;Rabin-Winograd (1972)&lt;&#x2F;a&gt; showed that any polynomial can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;\frac{n}{2} + \log n&lt;&#x2F;span&gt; multiplications. In the following, assume &lt;span class=&quot;math math-inline&quot;&gt;n = 255&lt;&#x2F;span&gt;. The method generalizes for arbitrary degree in the paper.&lt;&#x2F;p&gt;
&lt;p&gt;We first turn &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; monic by dividing by the leading term, in the end we will multiply by it again:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
c&amp;#39;_i = \frac{c_i}{c_n}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x) = c_n (c&amp;#39;_0 + c&amp;#39;_1 \cdot x + c&amp;#39;_2 \cdot x^2 + \dots + x^n)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now we pick &lt;span class=&quot;math math-inline&quot;&gt;i = \frac{n + 1}{2} = 128&lt;&#x2F;span&gt; and split the polynomial in two:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(x) = Q(x) \cdot (x^{128} + a) + R(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; are monic with degree &lt;span class=&quot;math math-inline&quot;&gt;127&lt;&#x2F;span&gt;. The coefficients of &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; are simply &lt;span class=&quot;math math-inline&quot;&gt;c&amp;#39;_{129}, \dots, c&amp;#39;_{255}&lt;&#x2F;span&gt;. The value of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;c_{128} - 1&lt;&#x2F;span&gt;. From this we can compute the coefficients of &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt;, they are &lt;span class=&quot;math math-inline&quot;&gt;r_i = c&amp;#39;_i - c \cdot q_i&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r_{127} = 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We apply this splitting recursively untill we are left with many monic polynomials of degree 3: &lt;span class=&quot;math math-inline&quot;&gt;S(x) = s_0 + s_1 x + s_2 x^2 + x^3&lt;&#x2F;span&gt;. These are computed using:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
S(x) = (x^2 + s_1) \cdot (x + s_2) + b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;s_0 - s_1 s_2&lt;&#x2F;span&gt;. All in all, the method requires about &lt;span class=&quot;math math-inline&quot;&gt;n&#x2F;2&lt;&#x2F;span&gt; multiplications, about half of Horners method. To this we need to add the &lt;span class=&quot;math math-inline&quot;&gt;\log n&lt;&#x2F;span&gt; squarings required to get the required powers of &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;With &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt; a power of two:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = (X - \omega_N^0) (X - \omega_N^1) \cdots (X - \omega_N^{N&#x2F;2})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P(X) = (X - 1) (X - \omega_N)(X - \omega_N^2) \cdots (X + 1)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Conjecture.&lt;&#x2F;strong&gt; &lt;em&gt;In &lt;span class=&quot;math math-inline&quot;&gt;\mathbb C&lt;&#x2F;span&gt; the coefficients of &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; alternate between real multiples of &lt;span class=&quot;math math-inline&quot;&gt;\omega_4^0, \omega_4^1, \omega_4^2, \omega_4^3&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Conjecture.&lt;&#x2F;strong&gt; &lt;em&gt;Furthermore, the scalar factors are symmetric in the sens that &lt;span class=&quot;math math-inline&quot;&gt;c_i = c_{N&#x2F;2 - i}&lt;&#x2F;span&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Conjecture.&lt;&#x2F;strong&gt; &lt;em&gt;Furthermore, the scalar factors follow a bell curve.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Propose concrete formula for coefficients.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; This seems to generalize to composite &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Symmetries&lt;&#x2F;em&gt;: Take &lt;span class=&quot;math math-inline&quot;&gt;P(X)&lt;&#x2F;span&gt; to be the polynomial with zeros on &lt;span class=&quot;math math-inline&quot;&gt;\omega_N^0, \dots \omega_N^{N&#x2F;2}&lt;&#x2F;span&gt;. It should have the following symmetries based on observations of patterns of roots:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Translation by one&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
  (X - \omega_N^0) P(\omega_N X) = (X - \omega_N^{N&#x2F;2 + 1}) P(X)
  &lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and observing that &lt;span class=&quot;math math-inline&quot;&gt;\omega_N^{N&#x2F;2 + 1} = \omega_N \cdot \omega_N^{N&#x2F;2} = -\omega_N&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
  (X - 1) P(\omega_N X) = (X + \omega_N) P(X)
  &lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Complement.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
  P(X)P(-X) = (X+1)(X-1)(X^N -1)
  &lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
  P(X)P(-X) = (X^2-1)(X^N -1)
  &lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;(Conjectured)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
  P(X) = P\left(\frac{\omega_N}{X}\right)X^{N&#x2F;2}
  &lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;https:&#x2F;&#x2F;helper.ipam.ucla.edu&#x2F;publications&#x2F;ccgtut&#x2F;ccgtut_11787.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Vieta%27s_formulas&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Gauss%E2%80%93Lucas_theorem&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Geometrical_properties_of_polynomial_roots&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polynomial_decomposition&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Decomposition:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do&lt;&#x2F;strong&gt;. Try decomposition methods. Observe that &lt;span class=&quot;math math-inline&quot;&gt;X^{2^k}-1 = (X^2 -1) \circ (X^2) \circ \cdots \circ (X^2)&lt;&#x2F;span&gt;. The rhs can be evaluated in &lt;span class=&quot;math math-inline&quot;&gt;O(k)&lt;&#x2F;span&gt; operations.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20150924101735&#x2F;http:&#x2F;&#x2F;www.sigsam.org&#x2F;bulletin&#x2F;articles&#x2F;187&#x2F;Polynomial_time_decomposition_pp13-23.pdf&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;pdf&#x2F;1107.0687.pdf&lt;&#x2F;p&gt;
&lt;p&gt;Does not seem to work for small examples: https:&#x2F;&#x2F;www.wolframalpha.com&#x2F;input&#x2F;?i=Decompose%5B%28x-i%29%28x-1%29%28x%2B1%29%2C+x%5D even though &lt;span class=&quot;math math-inline&quot;&gt;X^4-1&lt;&#x2F;span&gt; works https:&#x2F;&#x2F;www.wolframalpha.com&#x2F;input&#x2F;?i=Decompose%5B%28x-i%29%28x-1%29%28x%2B1%29%28x%2Bi%29%2C+x%5D&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Interpolation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
P(z) &amp;amp;= 
\sum_i a_i ⋅ L_i(z) \\&amp;amp;=
\sum_i a_i ⋅ \frac{𝜔^i}{n} \frac{z^n - 1}{z - 𝜔^i} \\&amp;amp;=
\frac{z^n - 1}{n} \sum_i \frac{a_i ⋅ 𝜔^i}{z - 𝜔^i}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;a_i = \begin{cases} 0 &amp;amp; i \le N&#x2F;2 \\ \ne 0 &amp;amp; otherwise \end{cases}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{z^n - 1}{n} \sum_{i \in (N&#x2F;2, N)} \frac{a_i \cdot 𝜔^i}{z - 𝜔^i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This reduces the problem to computing the sum in &lt;span class=&quot;math math-inline&quot;&gt;\log N&lt;&#x2F;span&gt; time, plus we are allowed to multiply each term of the sum by a nonzero factor of our choosing. First of, let&#x27;s absorb the other factors in &lt;span class=&quot;math math-inline&quot;&gt;a_i&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
(z^n - 1) \sum_{i \in (N&#x2F;2, N)} \frac{a_i}{z - 𝜔^i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The integral related to the sum seems solvable: https:&#x2F;&#x2F;www.wolframalpha.com&#x2F;input&#x2F;?i=Integrate%5B1%2F%28a-b%5Ex%29%2C+x%5D&lt;&#x2F;p&gt;
&lt;p&gt;The series seems related to the digamma function: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Digamma_function#Evaluation_of_sums_of_rational_functions http:&#x2F;&#x2F;mathworld.wolfram.com&#x2F;q-PolygammaFunction.html&lt;&#x2F;p&gt;
&lt;p&gt;There is potentially a closed form solution, at least for complex numbers:&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;www.wolframalpha.com&#x2F;input&#x2F;?i=Sum%5B1%2F%28z-b%5Ei%29%2C+%7Bi%2C+n+%2C++2*n%7D%5D&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lambert_series&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Merkle Hashing</title>
        <published>2018-11-06T00:00:00+00:00</published>
        <updated>2018-11-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/18/merkle-hashing/"/>
        <id>https://2π.com/18/merkle-hashing/</id>
        
        <content type="html" xml:base="https://2π.com/18/merkle-hashing/">&lt;h1 id=&quot;merkle-hashing&quot;&gt;Merkle Hashing&lt;&#x2F;h1&gt;
&lt;p&gt;Dmitry Khovratovich&#x27;s talk at devcon got me thinking about efficient hashing algorithms for Merkle trees. I&#x27;m also influenced by Keccak paper arguments to reduce the intermediate rounds in the Sponge construction.&lt;&#x2F;p&gt;
&lt;p&gt;The basic idea is to only use a cryptographically secure hash function at the leaf and root nodes, and a less secure function on intermediate nodes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Unary tree&lt;&#x2F;strong&gt; Consider a degenerate Merkle tree where the branching factor is one:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathrm{Tree}\ a  = \mathrm{Leaf}\ a\ |\ \mathrm{Node}\ (\mathrm{Tree}\ a)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Tree a  = Leaf a | Node (Tree a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can construct a &#x27;tree&#x27; hashing operation like so&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hash (Node a) = sha3(innerHash a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;innerHash (Leaf a) = sha3(a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;innerHash (Node a) = innerHash(a) + 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;(assume all values in a sufficiently large field)&lt;&#x2F;p&gt;
&lt;p&gt;This scheme is essentially the same as &lt;code&gt;sha3(sha3( leaf ) + length)&lt;&#x2F;code&gt; which is secure. Yet it only requires two &lt;code&gt;sha3&lt;&#x2F;code&gt; operations instead of O(nodes).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Fixed depth binary tree.&lt;&#x2F;strong&gt; Now let&#x27;s try to generalization this to fixed depth binary trees. The tree structure becomes&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathrm{Tree}_d\ a  = \mathrm{Leaf}_0\ a\ |\ \mathrm{Node}_d\ (\mathrm{Tree}_{d-1}\ a)\ (\mathrm{Tree}_{d-1}\ a)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The suffices are there to pass the depth of the tree along. They make it easier to form a closed form expression.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hash (Node d a) = sha3(innerHash a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;innerHash (Leaf d a) = sha3(a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;innerHash (Node d a b) = prime[d] * innerHash(a) + innerHash(b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;prime = 3, 5, ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Example.&lt;&#x2F;strong&gt; Consider the case with four leaves:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a     b    c     d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; \   &#x2F;      \   &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  3a+b      3c+d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    \         &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     \       &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; 5(3a+b) + (3c+d) &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The resulting hash would be:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;sha3( 15 sha3(a) + 5 sha3(b) + 3 sha3(c) + sha3(d) )&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Security analysis&lt;&#x2F;strong&gt;. We loose some security in collision resistance because in addition to plain collisions on sha3, it is also sufficient to find certain linear relationships. This makes birthday attacks easier. I don&#x27;t think this affects pre-image resistance.&lt;&#x2F;p&gt;
&lt;p&gt;More worrying is that we loose the ability to construct Merkle proofs entirely. Let&#x27;s say I want to proof membership of &lt;code&gt;a&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a     x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; \   &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  3a+x        y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    \        &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     \      &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   5(3a+x) + y &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I would provide you the values&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a = a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x = sha3(b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;y = 3 sha3(c) + sha3(d)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You would compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;sha3( 15 sha3(a) + 5 x + y ) == rootHash&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s clear that if I can solve for &lt;code&gt;x&lt;&#x2F;code&gt; and &lt;code&gt;y&lt;&#x2F;code&gt; to make the inner expression match the (publicly known) pre-image of the root-hash.&lt;&#x2F;p&gt;
&lt;p&gt;From this example it follows that&lt;&#x2F;p&gt;
&lt;p&gt;You could argue that only the branch not taken needs to be secure, the chain to the leaf does not need the&lt;&#x2F;p&gt;
&lt;p&gt;This is related to the topic https:&#x2F;&#x2F;ethresear.ch&#x2F;t&#x2F;cheap-hash-functions-for-zksnark-merkle-tree-proofs-which-can-be-calculated-on-chain&#x2F;3176&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Order types</title>
        <published>2018-09-20T00:00:00+00:00</published>
        <updated>2018-09-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/18/order-types/"/>
        <id>https://2π.com/18/order-types/</id>
        
        <content type="html" xml:base="https://2π.com/18/order-types/">&lt;h1 id=&quot;order-types&quot;&gt;Order types&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;Market order.&lt;&#x2F;strong&gt; Order executed immediately at current price.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Limit.&lt;&#x2F;strong&gt; Order to buy or sell at a specific price or better; trade will execute once that price is met. Order remains on the book until filled or cancelled.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Limit by Time.&lt;&#x2F;strong&gt; Limit Order, with a time limit. If not filled by the specified time, cancelled.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Stop.&lt;&#x2F;strong&gt; An order to buy or sell once a VC moves past an assigned price. Once the price crosses the threshold, the stop order becomes a market order and the full trade is executed at the current price.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Stop-Limit.&lt;&#x2F;strong&gt; Order used to mitigate the risk of losses. The trader must set two prices, the stop price and the limit price.  Trader places a stop price, but instead of the stop order automatically reverting to a market order, it becomes a limit order and will only be traded if the execution price is still in the limit range.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Trailing Stop.&lt;&#x2F;strong&gt; Order will automatically track the price and trigger a sell if the price of the falls below the chosen range.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Fill or Kill.&lt;&#x2F;strong&gt; Trader sets amount and price. If the trade can be done immediately at the price (or better) and amount named then the order is filled. If not, then the order is cancelled or &#x27;killed&#x27;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Scale.&lt;&#x2F;strong&gt; Order includes several limit orders at incrementally increasing or decreasing prices; allows trader to split a larger transaction into smaller volumes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;One Cancels Other.&lt;&#x2F;strong&gt; Trader creates two orders (stop order and limit order) and links them together so that if one is met, the other automatically cancels.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hidden.&lt;&#x2F;strong&gt; Orders that do not appear on the book.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Post-Only.&lt;&#x2F;strong&gt; Order that is only added to the order book if it does not fill a pre-existing order. If there is an order currently in the order book that would be filled, the post-only order will be cancelled. Used to ensure trader does not incur &#x27;taker&#x27; fee.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Good Till Cancel.&lt;&#x2F;strong&gt; Order remains active until the order is filled or cancelled.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Immediate or Cancel.&lt;&#x2F;strong&gt; Order must be executed immediately, and any part of the order that cannot be immediately filled is cancelled.  Unlike Fill or Kill, Immediate or Cancel typically can be partially filled before being cancelled, whereas the entire order must be filled in a Fill or Kill.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Instant.&lt;&#x2F;strong&gt; Unlike a market order, which is filled at the current price, an Instant Order is used to try to execute a trade by naming the latest price on the platform. If the price has changed since the submission of the order, the trader has the option to name a new price.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Good Till Date.&lt;&#x2F;strong&gt; A buy or sell order that remains active until filled or the end of a specified date. If the order is not filled by the Good till date, it is cancelled.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Good Till End of Day.&lt;&#x2F;strong&gt; A buy or sell order that remains active until filled or the end of day that it is submitted. If the order is not filled by the end of the day, it is cancelled.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Auction-Only.&lt;&#x2F;strong&gt; At the end of the auction (usually at the end of a day), participating orders will be matched and determine the price at which the largest quantity of orders can be filled.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Indication of Interest.&lt;&#x2F;strong&gt; Typically describes a non-firm submission that includes side (buy or sell), quantity, minimum fill requirement and price limit.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Maker or Cancel.&lt;&#x2F;strong&gt; Limit order with a set price that sits on the order book, and if any quantity of the order can be filled immediately, the entire order is cancelled. Used to ensure trader does not incur &#x27;taker&#x27; fee. Similar to Post-Only.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mathemagic finale: muldiv</title>
        <published>2018-07-06T00:00:00+00:00</published>
        <updated>2018-07-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/21/muldiv/"/>
        <id>https://2π.com/21/muldiv/</id>
        
        <content type="html" xml:base="https://2π.com/21/muldiv/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{({#1})}
\gdef\floor#1{\lfloor{#1}\rfloor}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;mathemagic-finale-muldiv&quot;&gt;Mathemagic finale: muldiv&lt;&#x2F;h1&gt;
&lt;p&gt;A couple years back I wrote a series of blogs introducing some tricky mathemagic, but I never got around to tell the punchline. The goal is to compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathtt{muldiv}\p{\mathtt{a}, \mathtt{b}, \mathtt{denominator}} =
\floor{\frac{\mathtt{a} ⋅ \mathtt{b}}{\mathtt{denominator}}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;while handling overflow correctly. Our secret weapon is EVM&#x27;s &lt;code&gt;mulmod&lt;&#x2F;code&gt; instruction. This instruction does exactly what we want, except it returns the remainder not the quotient. So what&#x27;s our strategy?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute the 512-bit product &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{a} ⋅ \mathtt{b}&lt;&#x2F;span&gt; using &lt;code&gt;mulmod&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Make the division exact by subtracting the remainder using &lt;code&gt;mulmod&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Remove powers of two from the fraction to make denominator invertible &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{mod} 2^{256}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute the modular inverse of the denominator.&lt;&#x2F;li&gt;
&lt;li&gt;Multiply numerator and inverse denominator &lt;span class=&quot;math math-inline&quot;&gt;\operatorname{mod} 2^{256}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;I will not explain the implementation of each step here, for that please refer to previous posts:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;17&#x2F;chinese-remainder-theorem&quot;&gt;Chinese Remainder Theorem&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;17&#x2F;full-mul&quot;&gt;Full Multiplication&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;17&#x2F;512-bit-division&quot;&gt;512 bit division&lt;&#x2F;a&gt; (includes a number of simple tricks)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;18&#x2F;multiplitcative-inverses&quot;&gt;Multiplicative Inverses&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Implemented and optimized the strategy is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract MulDiv {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function muldiv(uint256 a, uint256 b, uint256 denominator)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    internal pure returns (uint256 result)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Handle division by zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(denominator &amp;gt; 0);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; 512-bit multiply [prod1 prod0] = a * b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Compute the product mod 2**256 and mod 2**256 - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; then use the Chinese Remainder Theorem to reconstruct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; the 512 bit result. The result is stored in two 256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; variables such that product = prod1 * 2**256 + prod0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 prod0; &#x2F;&#x2F; Least significant 256 bits of the product&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 prod1; &#x2F;&#x2F; Most significant 256 bits of the product&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            let mm := mulmod(a, b, not(0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            prod0 := mul(a, b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            prod1 := sub(sub(mm, prod0), lt(mm, prod0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Short circuit 256 by 256 division&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; This saves gas when a * b is small, at the cost of making the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; large case a bit more expensive. Depending on your use case you&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; may want to remove this short circuit and always go through the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; 512 bit path.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if (prod1 == 0) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                result := div(prod0, denominator)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            return result;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; 512 by 256 division.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Handle overflow, the result must be &amp;lt; 2**256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(prod1 &amp;lt; denominator);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Make division exact by subtracting the remainder from [prod1 prod0]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Compute remainder using mulmod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Note mulmod(_, _, 0) == 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 remainder;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            remainder := mulmod(a, b, denominator)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Subtract 256 bit number from 512 bit number&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            prod1 := sub(prod1, gt(remainder, prod0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            prod0 := sub(prod0, remainder)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Factor powers of two out of denominator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Compute largest power of two divisor of denominator.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Always &amp;gt;= 1 unless denominator is zero, then twos is zero.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 twos = -denominator &amp;amp; denominator;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Divide denominator by power of two&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            denominator := div(denominator, twos)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Divide [prod1 prod0] by the factors of two&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            prod0 := div(prod0, twos)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Shift in bits from prod1 into prod0. For this we need&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; to flip `twos` such that it is 2**256 &#x2F; twos.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; If twos is zero, then it becomes one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            twos := add(div(sub(0, twos), twos), 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        prod0 |= prod1 * twos;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Invert denominator mod 2**256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Now that denominator is an odd number, it has an inverse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; modulo 2**256 such that denominator * inv = 1 mod 2**256.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Compute the inverse by starting with a seed that is correct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; correct for four bits. That is, denominator * inv = 1 mod 2**4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; If denominator is zero the inverse starts with 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 inv = 3 * denominator ^ 2;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Now use Newton-Raphson itteration to improve the precision.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Thanks to Hensel&amp;#39;s lifting lemma, this also works in modular&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; arithmetic, doubling the correct bits in each step.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        inv *= 2 - denominator * inv; &#x2F;&#x2F; inverse mod 2**8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        inv *= 2 - denominator * inv; &#x2F;&#x2F; inverse mod 2**16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        inv *= 2 - denominator * inv; &#x2F;&#x2F; inverse mod 2**32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        inv *= 2 - denominator * inv; &#x2F;&#x2F; inverse mod 2**64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        inv *= 2 - denominator * inv; &#x2F;&#x2F; inverse mod 2**128&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        inv *= 2 - denominator * inv; &#x2F;&#x2F; inverse mod 2**256&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; If denominator is zero, inv is now 128&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Because the division is now exact we can divide by multiplying&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; with the modular inverse of denominator. This will give us the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; correct result modulo 2**256. Since the precoditions guarantee&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; that the outcome is less than 2**256, this is the final result.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; We don&amp;#39;t need to compute the high bits of the result and prod1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; is no longer required.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        result = prod0 * inv;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return result;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This routine is included in Uniswap V3 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Uniswap&#x2F;v3-core&#x2F;blob&#x2F;412d9b236a1e75a98568d49b1aeb21e3a1430544&#x2F;contracts&#x2F;libraries&#x2F;FullMath.sol#L8&quot;&gt;&lt;code&gt;FullMath.sol&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; where it is saving gas on each trade. It can also be found in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OpenZeppelin&#x2F;openzeppelin-contracts&#x2F;blob&#x2F;c1d6e39aab042a38a90f618c614a298522851f7b&#x2F;contracts&#x2F;utils&#x2F;math&#x2F;Math.sol#L50&quot;&gt;OpenZeppelin&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;search?q=%22Remco%22+%2221%2Fmuldiv%22&amp;amp;type=code&quot;&gt;various other projects&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paulrberg&#x2F;prb-math&#x2F;blob&#x2F;88d0815baef78c0699fec1ff10b34a35903e110f&#x2F;contracts&#x2F;PRBMath.sol#L379&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;paulrberg&#x2F;prb-math&#x2F;blob&#x2F;88d0815baef78c0699fec1ff10b34a35903e110f&#x2F;contracts&#x2F;PRBMath.sol#L379&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An early variant of the above was briefly considered for inclusion in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;0xProject&#x2F;0x-monorepo&#x2F;blob&#x2F;672c6f4f84981a054bcc601a7b8ae5263a2e451d&#x2F;packages&#x2F;contracts&#x2F;src&#x2F;2.0.0&#x2F;protocol&#x2F;Exchange&#x2F;libs&#x2F;LibMath.sol#L34&quot;&gt;0x protocol v2&lt;&#x2F;a&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;coinmonks&#x2F;math-in-solidity-part-3-percents-and-proportions-4db014e080b1&quot;&gt;Mikhail Vladimirov&lt;&#x2F;a&gt; independently put the pieces together and came up with the same strategy.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Optimizing transaction settlement</title>
        <published>2018-04-15T00:00:00+00:00</published>
        <updated>2018-04-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/18/optimizing-transaction-settlement/"/>
        <id>https://2π.com/18/optimizing-transaction-settlement/</id>
        
        <content type="html" xml:base="https://2π.com/18/optimizing-transaction-settlement/">&lt;h1 id=&quot;optimizing-transaction-settlement&quot;&gt;Optimizing transaction settlement&lt;&#x2F;h1&gt;
&lt;p&gt;Alice, Bob and their lexicographic friends traded extensively. All off-chain of course. They now have the following obligations to settle:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img01.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can settle this as-is, with 12 transactions. But what is the smallest number of transactions required to settle these obligations?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;(I’m going to present some intuitive tactics before getting to the optimal strategy. The impatient reader may skip ahead to ‘Solution’)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tactics&quot;&gt;Tactics&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;combine-multi-edges&quot;&gt;Combine multi-edges&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img02.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Whenever there are many transactions between two nodes, we can add them together. If transactions go in both directions, we subtract the smaller from the larger. This tactic reduces the number of transactions to at most &lt;span class=&quot;math math-inline&quot;&gt;n^2- n&lt;&#x2F;span&gt;. It also means the optimal solution can not have multi-edges, so it must be a regular directed graph.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cut-loops&quot;&gt;Cut loops&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img03.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When there is a loop, we move money in a circle. We can add and subtract an amount to all the transactions in the loop and it would have no net effect. Take the smallest transaction amount and subtract it from the transactions. At least one transaction is now zero and the loop is cut. So the optimal solution must be loop free, an acyclic directed graph.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img04.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This also holds for undirected loops. We can pick a positive orientation for the loop and add or subtract an amount to cut the loop. So the optimal solution will have to be undirectionally loop free. In other words, the optimal solution will be a directed forest.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Of course, I will now show you a sub-optimal directed forest!&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img05.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;remove-pass-through-nodes&quot;&gt;Remove pass-through nodes&lt;&#x2F;h3&gt;
&lt;p&gt;Whenever a participant passes everything through, we can remove this participant and save a transaction. The general case of this does get quite a bit more complex, but there is always a solution:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img06.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So the optimal solution will be a directed forest without pass-through nodes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;But what about this one:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img07.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the above, we switch the positions of Ben and Bob. We then adjust the transactions to make sure everyone pays and receives the same. In the process, one transaction disappears. We now have two trees in our directed forest instead of one. In a way, we did the same thing with the pass-through nodes, except we created a tree of one node. In a forest, we can not cut branches without creating new trees. So an optimal solution is a directed forest with the largest number of trees.&lt;&#x2F;p&gt;
&lt;p&gt;But how do we get there?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;compute-the-net-change-in-balances&quot;&gt;Compute the net change in balances&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img08.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The net change in balances is all we care about. As long as these remain the same, we don’t care how we get there. So let’s forget about all the transactions. We will come up with a completely new set of transactions that has the same effect. The new transactions will be optimal by construction.&lt;&#x2F;p&gt;
&lt;p&gt;Also, observe that the sum of all the balance changes is zero. This is true because no money enters or leaves the system, we are only moving it around. Let’s try a divide-and-conquer approach. We split the problem into subsets that sum to zero, solve those and then combine those solutions into a global one.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;find-groups-that-sum-to-zero&quot;&gt;Find groups that sum to zero&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img09.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Finding these groups relates to the subset sum and the partition problem. These are NP-complete problems. It is difficult to find a set that sums to zero but easy to verify that it does. For the small values presented here, dynamic programming would work in reasonable time. For the 256-bit Ethereum balances, that won’t work. Brute force is a decent strategy for a small number of participants.&lt;&#x2F;p&gt;
&lt;p&gt;Now fun fact: NP-complete problems are perfect for Blockchain! Have users compute the solutions off-chain and post it along with the transaction. Then the smart contract can easily verify their correctness and settle the transfers.&lt;&#x2F;p&gt;
&lt;p&gt;We also don’t have to be too concerned with finding all subsets. We only save a single transaction for every zero set we find. If we don’t even look and take the set of all participants, that is still only n — 1 transactions, as we will see.&lt;&#x2F;p&gt;
&lt;p&gt;In practice, I expect two major sources of zero sets. First, pass-through accounts. Second, disjoint groups that do not transfer between each other. Balance changes summing to zero by coincidence seems unlikely.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sort-balance-changes-from-large-to-small&quot;&gt;Sort balance changes from large to small&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img10.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Sort each set in two columns, negative balances on the left and positive balances on the right. Sort the columns from large to small. Notice that the sum total of both columns is the same, but negated. We need to transfer money from left to right.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;create-transactions-top-down&quot;&gt;Create transactions top down&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img11.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Start with the largest possible transaction between the top two nodes. Now exactly one of them will have its balance accounted for, it is out. Repeat the process for the remaining nodes, each time taking out one node. In the final transaction, both remaining nodes will finish, for a total of &lt;span class=&quot;math math-inline&quot;&gt;n - 1&lt;&#x2F;span&gt; transactions.&lt;&#x2F;p&gt;
&lt;p&gt;This is optimal.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Proof.&lt;&#x2F;strong&gt; We know that the set does not contain any strict subsets that sum to zero. Assume we can solve it with fewer than &lt;span class=&quot;math math-inline&quot;&gt;n - 1&lt;&#x2F;span&gt; transactions, this would create a transaction graph with &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; nodes and less than &lt;span class=&quot;math math-inline&quot;&gt;n - 1&lt;&#x2F;span&gt; edges. This transaction graph does not have enough edges to be connected and therefore has at least two disconnected components. These disconnected components individually sum to zero, which contradicts with there being no strict subsets that sum to zero. Therefore &lt;span class=&quot;math math-inline&quot;&gt;n - 1&lt;&#x2F;span&gt; transactions is optimal. ∎&lt;&#x2F;p&gt;
&lt;h3 id=&quot;global-solution&quot;&gt;Global solution&lt;&#x2F;h3&gt;
&lt;p&gt;The union of these partial solutions is also the global solution. The total number of transactions is &lt;span class=&quot;math math-inline&quot;&gt;n - m&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; is the number of zero subsets.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Proof.&lt;&#x2F;strong&gt; Assume there is a solution with fewer than &lt;span class=&quot;math math-inline&quot;&gt;n - m&lt;&#x2F;span&gt; transactions. This solution graph must have more than m components. Each component has balances summing to zero, therefore there are more than &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; zero summing subsets. Contradicts our definition of &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and therefore &lt;span class=&quot;math math-inline&quot;&gt;n - m&lt;&#x2F;span&gt; transactions is optimal. ∎&lt;&#x2F;p&gt;
&lt;h3 id=&quot;uniqueness&quot;&gt;Uniqueness&lt;&#x2F;h3&gt;
&lt;p&gt;The solution is not unique, the following is also an optimal solution for the last subset:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;18&#x2F;optimizing-transaction-settlement&#x2F;img12.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This solution is less desirable because it creates larger transactions. Larger than the net change in balance for the user. This can cause problems for accounts with transactions limits, such as ERC20 allowances.&lt;&#x2F;p&gt;
&lt;p&gt;It is also possible that there are many ways to partition the balances into m zero summing subsets.&lt;&#x2F;p&gt;
&lt;p&gt;The method presented above not only minimizes the number of transactions, it also distributes them evenly over the participants and minimizes the transaction volume. (Proof left as an exercise to the reader)&lt;&#x2F;p&gt;
&lt;p&gt;Despite a bit of searching, I could not find a similar problem in the field of graph algorithms or optimization. Literature references welcome!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Multiplicative Inverses</title>
        <published>2018-01-12T00:00:00+00:00</published>
        <updated>2018-01-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/18/multiplitcative-inverses/"/>
        <id>https://2π.com/18/multiplitcative-inverses/</id>
        
        <content type="html" xml:base="https://2π.com/18/multiplitcative-inverses/">&lt;h1 id=&quot;multiplicative-inverses&quot;&gt;Multiplicative Inverses&lt;&#x2F;h1&gt;
&lt;p&gt;In this post, I will show a trick to divide a large number using only a small multiplication by an inverse. I will show two ways of computing these inverses and how to build a small fast lookup table. In the process, we will see that a single instruction can sometimes be more expensive than many cheaper instructions!&lt;&#x2F;p&gt;
&lt;p&gt;In this post, I build a function to compute the modular multiplicative inverse for modulus &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt;. Given a number &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, I want a number &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mod{a ⋅ r}_{2^{256}} = 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note on notation: As before, I use square brackets with a subscript to denote the modulus operation.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We write the solution formally as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
r = \mod{a^{-1}}_{2^{256}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This number &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; has an interesting property: multiplication by &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; is the same as division by &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;. Let me illustrate this with an example. Take &lt;span class=&quot;math math-inline&quot;&gt;1000&lt;&#x2F;span&gt; as the modulus and let &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; be &lt;span class=&quot;math math-inline&quot;&gt;73&lt;&#x2F;span&gt;. The inverse of &lt;span class=&quot;math math-inline&quot;&gt;73&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;137&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mod{73^{-1}}_{1000} = 137
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If I want to divide &lt;span class=&quot;math math-inline&quot;&gt;876&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;73&lt;&#x2F;span&gt;, I can multiply &lt;span class=&quot;math math-inline&quot;&gt;876&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;137&lt;&#x2F;span&gt; which is &lt;span class=&quot;math math-inline&quot;&gt;120\,012&lt;&#x2F;span&gt; and take the last three digits, &lt;span class=&quot;math math-inline&quot;&gt;12&lt;&#x2F;span&gt;. Indeed &lt;span class=&quot;math math-inline&quot;&gt;876 = 12 · 73&lt;&#x2F;span&gt;. This is an interesting party trick.&lt;&#x2F;p&gt;
&lt;p&gt;The real magic happens with larger numbers. Let’s say we want to divide &lt;span class=&quot;math math-inline&quot;&gt;46\,209&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;73&lt;&#x2F;span&gt;. For this, we multiply &lt;span class=&quot;math math-inline&quot;&gt;209&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;137&lt;&#x2F;span&gt; and take the last three digits. This is &lt;span class=&quot;math math-inline&quot;&gt;633&lt;&#x2F;span&gt; and indeed &lt;span class=&quot;math math-inline&quot;&gt;46\,209 = 663 · 73&lt;&#x2F;span&gt;. But wait! We did not even use the digits &lt;span class=&quot;math math-inline&quot;&gt;46&lt;&#x2F;span&gt;! How can we divide a number without even looking at the full number? This trick works when 1) the division is exact, 2) the multiplicative inverse exists, and 3) the result fits in three digits.&lt;&#x2F;p&gt;
&lt;p&gt;Those who have read my post on 512-bit multiplication can guess where I’m going with this. We can use this to do division on 512-bit numbers with a 256-bit multiply! But before we get to that, we first need a way to compute these inverses.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-fermat-euler-carmichael-theorem&quot;&gt;The Fermat-Euler-Carmichael theorem&lt;&#x2F;h2&gt;
&lt;p&gt;This funny theorem is an elementary result in number theory. It started out as Pierre de Fermat’s little theorem (1640). Later proven and improved by Leonhard Euler (1736). Finally perfected by Robert Carmichael (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gutenberg.org&#x2F;files&#x2F;13693&#x2F;13693-pdf.pdf&quot;&gt;1914&lt;&#x2F;a&gt;). The theorem is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mod{a^n}_m = \mod{a^{\mod{n}_{λ(m)}}}_m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;λ(m)&lt;&#x2F;span&gt; is the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Carmichael_function&quot;&gt;Carmichael function&lt;&#x2F;a&gt;. This implies that for numbers modulo &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;, the exponents behave as numbers modulo &lt;span class=&quot;math math-inline&quot;&gt;λ(m)&lt;&#x2F;span&gt;. For our modulus &lt;span class=&quot;math math-inline&quot;&gt;λ(2^{256}) = 2^{254}&lt;&#x2F;span&gt;. Thus, for 256-bit integers, exponents behave as 254-bit integers. This also extends to negative numbers and we can us that to get modular inverses:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mod{a^{-1}}_{2^{256}} = \mod{a^{\mod{-1}_{2^{254}}}}_{2^{256}} = \mod{a^{2^{254}-1}}_{2^{256}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Solidity supports exponentiation, so we can directly implement this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract MulInv {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function inv256(uint256 a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        public pure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        returns (uint256 r)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r = a ** (2**254 - 1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Inversion using the Fermat-Euler-Carmichael theorem&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This compiles to a single &lt;code&gt;EXP&lt;&#x2F;code&gt; instruction with a constant exponent, which is about as short as it can get. But this function takes no less than 1614 gas! This is because the EXP operation takes 10 gas plus 50 gas for every byte in the exponent. In our case the exponent is almost all ones, so we pay the maximum price of 1600.&lt;&#x2F;p&gt;
&lt;p&gt;Why is this operation so expensive? In the virtual machines, the operation is likely implemented using exponentiation by squaring. In this case, a single EXP instruction does the same amount of work as 512 MUL instructions. At five gas each, those &lt;code&gt;MUL&lt;&#x2F;code&gt;s cost about 2560 gas. In light of this, the &lt;code&gt;EXP&lt;&#x2F;code&gt; operation is not so oddly priced. In fact, it used to be a bit cheaper but that led to problems and the price had to be raised in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;EIPs&#x2F;blob&#x2F;master&#x2F;EIPS&#x2F;eip-160.md&quot;&gt;EIP160&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Can we do better? Yes. We could use the extended Euclidean algorithm to solve &lt;span class=&quot;math math-inline&quot;&gt;r · a + 1 · m = \gcd(a, m)&lt;&#x2F;span&gt;. This is generally faster than exponentiation. But there is an even better way.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;newton-raphson-hensel-inversion&quot;&gt;Newton-Raphson-Hensel inversion&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Division_algorithm#Newton%E2%80%93Raphson_division&quot;&gt;Newton-Raphson&lt;&#x2F;a&gt; method can be used to approximate division in real numbers. Thanks to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hensel%27s_lemma&quot;&gt;Hensel’s lemma&lt;&#x2F;a&gt;, this works even better in modular arithmetic. For powers of two it is the recurrence:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
r_0 &amp;amp;= 1 \\\\
r_{i+1} &amp;amp;= \mod{r_i ⋅ (2 - a ⋅ r_i)}_{2^{2^i}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For odd numbers &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, the values of this recurrence satisfy the formula&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
r_i = \mod{a^{-1}}_{2^{2^i}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Each iteration doubles the number of correct bits. This means that we want to compute &lt;span class=&quot;math math-inline&quot;&gt;r_8&lt;&#x2F;span&gt; to get the modular inverse for a 256-bit number.&lt;&#x2F;p&gt;
&lt;p&gt;We can skip one iteration by observing that &lt;span class=&quot;math math-inline&quot;&gt;r_1 = a&lt;&#x2F;span&gt; for all odd values of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;. This leaves only seven iterations to compute.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;small-lookup-table&quot;&gt;Small lookup table&lt;&#x2F;h3&gt;
&lt;p&gt;We can skip one more iteration by creating a small lookup table for &lt;span class=&quot;math math-inline&quot;&gt;r_2&lt;&#x2F;span&gt;. The values values of &lt;span class=&quot;math math-inline&quot;&gt;r_2&lt;&#x2F;span&gt; where an inverse exists are &lt;span class=&quot;math math-inline&quot;&gt;a ∈ {1, 3, 5, …, 15}&lt;&#x2F;span&gt; with corresponding inverses &lt;span class=&quot;math math-inline&quot;&gt;[1, 11, 13, 7, 9, 3, 5, 15]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For other values of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; we use zero instead of the real values of &lt;span class=&quot;math math-inline&quot;&gt;r_2&lt;&#x2F;span&gt;. Using zeros has the advantage that it makes the final result zero when an inverse does not exist. Zero is never a valid inverse, so this is a nice flag value.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bytes16 table = 0x001000b000d0007000900030005000f;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;r= uint256(table[a % 16]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;A sixteen entry lookup table for &lt;span class=&quot;math math-inline&quot;&gt;r_2&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The instructions the Solidity compiler (v. 0.4.18) produces from this snippet are a bit disappointing. An unnecessary bounds check is inserted. A multiplication is done to typecast from &lt;code&gt;uint8&lt;&#x2F;code&gt; to &lt;code&gt;bytes1&lt;&#x2F;code&gt; which is immediately undone by a division to convert from bytes1 to &lt;code&gt;uint256&lt;&#x2F;code&gt;. Finally, the &lt;code&gt;% 16&lt;&#x2F;code&gt; is not replaced by the cheaper &lt;code&gt;&amp;amp; 15&lt;&#x2F;code&gt;. Let’s fix all this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bytes16 table = 0x001000b000d0007000900030005000f;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    r := bytes(and(15, a), table);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;A much faster lookup table for &lt;span class=&quot;math math-inline&quot;&gt;r_2&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With these optimizations, the table lookup is a net gain of a few gas. Going further is currently not worth it. For &lt;span class=&quot;math math-inline&quot;&gt;r_3&lt;&#x2F;span&gt; we would need a lookup table of 256 entries. This can theoretically be done using &lt;code&gt;CODECOPY&lt;&#x2F;code&gt; and &lt;code&gt;MLOAD&lt;&#x2F;code&gt;, but current unsupported. For &lt;span class=&quot;math math-inline&quot;&gt;r_4&lt;&#x2F;span&gt; the table would have to be 65 kilobyte which is not worth the code size.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Combining the lookup table with six iterations results in the final implementation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract MulInv {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function inv256(uint256 a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        public pure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        returns (uint256 r)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; 4 bit lookup table&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        bytes16 table = 0x001000b000d0007000900030005000f;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r := bytes(and(15, a), table);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; 6 iterations of Newton-Raphson for 4 ⋅ 2^6 = 256 bit.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r *= 2 - a * r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r *= 2 - a * r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r *= 2 - a * r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r *= 2 - a * r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r *= 2 - a * r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r *= 2 - a * r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        return r;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Multiplicative inverse modulo &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Despite having 20 times more operations, this function takes only about 154 gas. Less than 10% of the &lt;code&gt;EXP&lt;&#x2F;code&gt; based implementation!&lt;&#x2F;p&gt;
&lt;p&gt;With this inversion function, I finally have all the tools I need to solve the problem I wanted to solve. In the next post, I will work around the constraints and create a proportion function that never fails.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Update.&lt;&#x2F;strong&gt; I have since learned that &lt;span class=&quot;math math-inline&quot;&gt;r_2 =&lt;&#x2F;span&gt; &lt;code&gt;3 * a ^ 2&lt;&#x2F;code&gt; works instead of the table (Montgomery, cited in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;1303.0328&quot;&gt;Mayer 2016&lt;&#x2F;a&gt;). It is slightly cheaper and requires no assembly, but it does not return zero when the inverse does not exist.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>512 bit division</title>
        <published>2017-12-19T00:00:00+00:00</published>
        <updated>2017-12-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/17/512-bit-division/"/>
        <id>https://2π.com/17/512-bit-division/</id>
        
        <content type="html" xml:base="https://2π.com/17/512-bit-division/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{({#1})}
\gdef\floor#1{\lfloor{#1}\rfloor}
\gdef\mod#1{[{#1}]}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;512-bit-division&quot;&gt;512 bit division&lt;&#x2F;h1&gt;
&lt;p&gt;In the previous posts, I introduced the &lt;a href=&quot;..&#x2F;chinese-remainder-theorem&quot;&gt;Chinese Remainder Theorem&lt;&#x2F;a&gt; and used it to build a &lt;a href=&quot;..&#x2F;full-mul&quot;&gt;full multiplication function&lt;&#x2F;a&gt;. In this post, I will introduce five small tricks and use them to build a simple division algorithm.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;find-the-largest-power-of-two-divisor-of-a-given-number&quot;&gt;Find the Largest Power of Two Divisor of a Given Number&lt;&#x2F;h2&gt;
&lt;p&gt;Given a number &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;. Find the largest power of two, &lt;span class=&quot;math math-inline&quot;&gt;r = 2^n&lt;&#x2F;span&gt;, that divides a given number. Equivalently, find a number &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\frac ar&lt;&#x2F;span&gt; is an exact division and its quotient is an odd number.&lt;&#x2F;p&gt;
&lt;p&gt;The answer is -a &amp;amp; a. It is hard to explain mathematically because it combines arithmetic with bitwise operations. But an example in binary makes it intuitively clear:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\dots\mathtt{00000110101101000} &amp;amp;&amp;amp; a \\
\dots\mathtt{11111001010011000} &amp;amp;&amp;amp; -a \\
\dots\mathtt{00000000000001000} &amp;amp;&amp;amp; a\ \&amp;amp; -a \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The key insight is that negation flips all high bits of a number up to but not including the least significant one. A simple &lt;em&gt;and&lt;&#x2F;em&gt; then removes all the flipped bits and we are left with only the least significant one.&lt;&#x2F;p&gt;
&lt;p&gt;For completeness, I’ll present it in Solidity as well:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Div512 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function twoDivisor(uint256 a) internal pure returns (uint256 r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r = -a &amp;amp; a;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Compute the largest power of two dividing a number&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For zero there is no divisor, and the function returns zero. For odd numbers, it returns one. This makes sense as it is the largest power of two (&lt;span class=&quot;math math-inline&quot;&gt;1 = 2^0&lt;&#x2F;span&gt;) that divides the number.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;divide-by-a-given-number&quot;&gt;Divide &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt; by a Given Number&lt;&#x2F;h2&gt;
&lt;p&gt;The number &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt; is fundamental to working with the Ethereum virtual machine, so it’s useful to do some tricks with it. It can not be expressed directly, but we can express fractions of it. For a given number &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, we can compute &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt; divided by &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;. For this I found a trick involving negated numbers:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\floor{\frac{2^{256}}{a}} = \floor{\frac{2^{256} - a}{a} + 1} = \floor{\frac{\mod{-a}_{2^{256}}}{a}} + 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Implemented in Solidity and optimized, this becomes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Div512 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function div256(uint256 a) internal pure returns (uint256 r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(a &amp;gt; 1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r := add(div(sub(0, a), a), 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Divide &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt; by a given number&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For the answer to be defined and fit in a single word, a needs to be larger than one. The assembly is to avoid a redundant zero check on division.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compute-modulo-a-given-number&quot;&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt; Modulo a Given Number&lt;&#x2F;h2&gt;
&lt;p&gt;Like the previous, we can also compute the remainder of 2^{256} divided by a instead of the quotient. The same trick with negation works:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mod{2^{256}}_a = \mod{2^{256} - a}_a = \mod{\mod{-a}_{2^{256}}}_a
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Again, in Solidity:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Div512 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function mod256(uint256 a) internal pure returns (uint256 r) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        require(a != 0);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r := mod(sub(0, a), a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Remainder of &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt; divided by a given number&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The answer always exists for non-zero a and is strictly less than &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;. The assembly is to avoid a redundant zero check.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;add-subtract-two-512-bit-numbers&quot;&gt;Add &#x2F; Subtract Two 512-bit Numbers&lt;&#x2F;h2&gt;
&lt;p&gt;The multiplication algorithm from before produces 512-bit numbers. To add two such numbers we can use an expression like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Div512 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function add512(uint256 a0, uint256 a1, uint256 b0, uint256 b1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    internal pure returns (uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r0 = a0 + b0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r1 = a1 + b1 + (r0 &amp;lt; a0 ? 1 : 0);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Simple 512-bit addition&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The second line has an extra term that checks for carry and adds it. It takes about 65 gas. The Solidity compiler (v. 0.4.18) does not produce optimal code here. The ternary expression turns in to a branch. We can avoid this. Observe the yellow paper definition of the LT, the less-than instruction:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathtt{lt}(a, b) = \begin{cases} 1 &amp;amp; a &amp;lt; b \\ 0 &amp;amp; \text{otherwise} \end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This function already returns zero or one exactly as we want it. We can thus add it directly. Casting a boolean to a number is not allowed in Solidity, so we need to switch to assembler again:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Div512 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function add512(uint256 a0, uint256 a1, uint256 b0, uint256 b1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    internal pure returns (uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r0 := add(a0, b0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r1 := add(add(a1, b1), lt(r0, a0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Add two 512 bit numbers&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This function takes only 10 gas (when measured by comparing to a function returning zero). Similarly for subtraction:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Div512 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function sub512(uint256 a0, uint256 a1, uint256 b0, uint256 b1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    internal pure returns (uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r0 := sub(a0, b0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r1 := sub(sub(a1, b1), lt(a0, b0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Subtract 512-bit numbers&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dividing-a-512-bit-number-by-a-256-bit-number&quot;&gt;Dividing a 512-bit Number by a 256-bit Number&lt;&#x2F;h2&gt;
&lt;p&gt;To show the usefulness of the above functions, I’ll make a simple division algorithm. We want to build a 512-by-256-bit division function, that is, we want to compute x such that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = \floor{\frac{a_1 ⋅ 2^{256} + a_0}{b}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;a_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;a_1&lt;&#x2F;span&gt; are the lower and higher half of the 512-bit number and &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; is the 256-bit number. The result, &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;, will also be 512-bit. So it is also split into its low and high bits &lt;span class=&quot;math math-inline&quot;&gt;x_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;x_1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To solve it, first, we observe the following. With the &lt;code&gt;div256&lt;&#x2F;code&gt; and &lt;code&gt;mod256&lt;&#x2F;code&gt; functions we can compute two numbers &lt;code&gt;q = div256(b)&lt;&#x2F;code&gt; and &lt;code&gt;r = mod256(b)&lt;&#x2F;code&gt;. These then satisfy:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
2^{256} = q ⋅ b + r
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we substitute this identity in the fraction, we can split out a term:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\floor{\frac{a_1 ⋅ \p{q ⋅ c + r} + a_0}{c}} = \floor{\frac{a_1 ⋅ r + x_0}{c}} + a_1 ⋅ q
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Because &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; is smaller than &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt;, the new numerator is smaller than the one we had before — we made some progress. We can keep repeating this process. Each time splitting of a term and computing the new numerator. Eventually, we reach a point where the new &lt;span class=&quot;math math-inline&quot;&gt;x_1&lt;&#x2F;span&gt; is zero. When that happens we do a regular division of &lt;span class=&quot;math math-inline&quot;&gt;x_0&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt;. The final result is the sum of all the &lt;span class=&quot;math math-inline&quot;&gt;x_1 · q&lt;&#x2F;span&gt; terms and the final division.  This creates an elegant algorithm:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Div512 {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function div512(uint256 a0, uint256 a1, uint256 b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    internal pure returns (uint256 x0, uint256 x1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 q = div256(b);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 r = mod256(b);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        while (a1 != 0) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (t0, t1) = mul512(a1, q);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (x0, x1) = add512(x0, x1, t0, t1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (t0, t1) = mul512(a1, r);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (a0, a1) = add512(t0, t1, a0, 0);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (x0, x1) = add512(r0, r1, a0 &#x2F; b, 0);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;512-by-256-division for &lt;span class=&quot;math math-inline&quot;&gt;b &amp;gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;How many iterations does the loop take? In the worst case is &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; is as large as possible because then we ‘scale back’ &lt;span class=&quot;math math-inline&quot;&gt;x_1&lt;&#x2F;span&gt; by the smallest amount. The largest &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; can get is &lt;span class=&quot;math math-inline&quot;&gt;2^{255} - 1&lt;&#x2F;span&gt;, when &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; equals &lt;span class=&quot;math math-inline&quot;&gt;2^{255} + 1&lt;&#x2F;span&gt;. This means &lt;span class=&quot;math math-inline&quot;&gt;x_1&lt;&#x2F;span&gt; is at least halved every iteration. Since &lt;span class=&quot;math math-inline&quot;&gt;x_1&lt;&#x2F;span&gt; is 256-bit, it takes at most 256 iterations.&lt;&#x2F;p&gt;
&lt;p&gt;As presented, it requires &lt;span class=&quot;math math-inline&quot;&gt;b &amp;gt; 1&lt;&#x2F;span&gt;. A special case for &lt;span class=&quot;math math-inline&quot;&gt;b = 1&lt;&#x2F;span&gt; is easily added, just return the input &lt;span class=&quot;math math-inline&quot;&gt;(a_0, a_1)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I did a bit of searching, but could not find this approach to division in the literature; a division algorithm where the radix is rewritten in terms of the denominator. Please tell me if you know one.&lt;&#x2F;p&gt;
&lt;p&gt;With these five new tools, we are developing a nice toolbox. We can already tackle some interesting problems. The division algorithm shown here is not optimized because there are better approaches. The really good ones require one more tool, modular inverses, which I will present in the next post.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Full Multiplication</title>
        <published>2017-12-15T00:00:00+00:00</published>
        <updated>2017-12-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/17/full-mul/"/>
        <id>https://2π.com/17/full-mul/</id>
        
        <content type="html" xml:base="https://2π.com/17/full-mul/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\floor#1{\lfloor{#1}\rfloor}
\gdef\mod#1{[{#1}]}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;full-multiplication&quot;&gt;Full Multiplication&lt;&#x2F;h1&gt;
&lt;p&gt;A lot of smart contracts use the &lt;code&gt;SafeMath&lt;&#x2F;code&gt; library. It prevents contracts from having incorrect results, but it does so by failing transactions instead of making them correct. Let’s instead try to do the math correctly. In this series, I will derive some advanced techniques. Today, I’ll make a better &lt;code&gt;safeMul&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you multiply two numbers, the result will be a number twice the size. In Ethereum, when you multiply two numbers, the result can be up to 512 bits. But Ethereum only gives you the lower half; it simply ignores the rest. This is a common practice in mathematics called &lt;em&gt;modular arithmetic&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;However, ignoring numbers is not an acceptable practice in accounting. Care needs to be taken to avoid it or someone will lose something valuable. A popular library called &lt;code&gt;SafeMath&lt;&#x2F;code&gt; detects when it happens and then fails the transaction. But what if you do not want your transaction to fail?&lt;&#x2F;p&gt;
&lt;p&gt;What if you want to multiply any numbers and have the complete result?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Spoiler alert:&lt;&#x2F;strong&gt; this is snippet of Solidity code will do that for you:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract FullMul {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function mul512(uint256 a, uint256 b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    public pure returns(uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            let mm := mulmod(a, b, not(0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r0 := mul(a, b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r1 := sub(sub(mm, r0), lt(mm, r0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Optimized full 512 bit multiplication in Solidity.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But before we get into that, let’s define the problem precisely: We have two unsigned numbers &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;, both 256 bits in length and we want their product, a 512-bit number &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = a ⋅ b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since this number is too large to be represented directly in code, we split it up into the least significant and most significant 256 bits, &lt;span class=&quot;math math-inline&quot;&gt;r_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r_1&lt;&#x2F;span&gt; respectively:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
r_0 &amp;amp;= \mod{x}_{2^{256}} &amp;amp;
r_1 &amp;amp;= \floor{\frac{x}{2^{256}}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where the square brackets with subscript represent the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Modulo_operation&quot;&gt;modulo operation&lt;&#x2F;a&gt; and the lower-half brackets on the right represent the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Floor_and_ceiling_functions&quot;&gt;floor operation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;schoolbook-algorithm&quot;&gt;Schoolbook algorithm&lt;&#x2F;h2&gt;
&lt;p&gt;The classical way of solving this problem is by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Multiplication_algorithm#Long_multiplication&quot;&gt;long multiplication&lt;&#x2F;a&gt;, the method we all learned in school. You split your large number into decimals, multiply the digits, and then add the intermediate results. This method also works in binary and other bases. Let me quickly show you how you would use it here:&lt;&#x2F;p&gt;
&lt;p&gt;Since we have 256 bit multiply build in, we can multiply any two 128 bit numbers and get the full result. So if we split our large number into groups of 128 bits we can compute all their products. Take &lt;span class=&quot;math math-inline&quot;&gt;a_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;a_1&lt;&#x2F;span&gt; to respectively mean the least significant and most significant 128 bits of &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, similarly for &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a_0 &amp;amp;= \mod{a}\_{2^{128}} &amp;amp;
a_1 &amp;amp;= \floor{\frac{a}{2^{128}}} \\\\
b_0 &amp;amp;= \mod{b}\_{2^{128}} &amp;amp;
b_1 &amp;amp;= \floor{\frac{b}{2^{128}}} \\\\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now the original numbers a and b can be written as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a &amp;amp;= a_1 ⋅2^{128} + a_0 \\\\
b &amp;amp;= b_1 ⋅2^{128} + b_0 \\\\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we substitute this in product equation it becomes:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = a_1 ⋅ b_1 ⋅2^{256} + (a_0 ⋅ b_1 + a_1 ⋅ b_0) ⋅ 2^{128} + a_0 ⋅ b_0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ignoring the constants, we now have four multiplications instead of one. But all four of them involve numbers less than &lt;span class=&quot;math math-inline&quot;&gt;2^{128}&lt;&#x2F;span&gt; that can be computed directly. The result is still too large, so we still need two numbers &lt;span class=&quot;math math-inline&quot;&gt;r_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r_1&lt;&#x2F;span&gt; to represent it. I will skip the steps of how to get &lt;span class=&quot;math math-inline&quot;&gt;r_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r_1&lt;&#x2F;span&gt; from this expression. It is straightforward, but annoying because of the shifts and carries. The final result is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract FullMul {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    uint256 constant H = 2**128;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function mul512(uint256 a, uint256 b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    public pure returns(uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Split in groups of 128 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 a0 = a % H;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 a1 = a &#x2F; H;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 b0 = b % H;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 b1 = b &#x2F; H;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Compute 256 bit intermediate products&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 i00 = a0 * b0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 i01 = a0 * b1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 i10 = a1 * b0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 i11 = a1 * b1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Split results in (shifted) groups of 128 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 i010 = i01 * H; &#x2F;&#x2F; Shifted up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 i011 = i01 &#x2F; H;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 i100 = i10 * H; &#x2F;&#x2F; Shifted up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 i101 = i10 &#x2F; H;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Add all intermediate terms, taking care of overflow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r0 = i00;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r1 = i11 + i011 + i101;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r0 += i010;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if (r0 &amp;lt; i010) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r1 += 1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r0 += i100;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if (r0 &amp;lt; i100) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r1 += 1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Schoolbook algorithm for 512 bit multiplication.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(Note that Solidity, as of 0.4.18, actually fails to compile the above example because the compiler can not handle that many local variables. This is easily solved by inlining some expressions, but since it reduces readability I opted not to do that for this example.)&lt;&#x2F;p&gt;
&lt;p&gt;The two multiplications for &lt;code&gt;i01&lt;&#x2F;code&gt; and &lt;code&gt;i10&lt;&#x2F;code&gt; can be replaced by one using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Karatsuba_algorithm&quot;&gt;Karatsuba algorithm&lt;&#x2F;a&gt;, at the expense of a few more additions. Since additions are 3 gas and multiplications only 5, this is not worth it. But if you want to do larger multiplications (say 4096 bit) it is worth looking into these methods.&lt;&#x2F;p&gt;
&lt;p&gt;We have now solved the problem using two modulo operations, four divisions, six additions, two conditional branches, and no less than six multiplications. The entire function takes a bit over 300 gas. This is not bad, but the gas cost is almost two orders of magnitude larger than the 5 gas for a regular multiplication, or 90 for a standard &lt;code&gt;safeMul&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We can do a lot better.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chinese-remainder&quot;&gt;Chinese Remainder&lt;&#x2F;h2&gt;
&lt;p&gt;So here’s the trick: We use the rather obscure &lt;code&gt;mulmod&lt;&#x2F;code&gt; instruction and the Chinese Remainder Theorem. In short, the theorem states thati f we know a number modulo &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;2^{256} - 1&lt;&#x2F;span&gt;, we can compute its 512-bit representation cheaply. The function to do this, &lt;code&gt;chineseRemainder&lt;&#x2F;code&gt;, is described in a &lt;a href=&quot;..&#x2F;chinese-remainder-theorem&quot;&gt;previous post&lt;&#x2F;a&gt;. To use it here, we first need to compute our product in the two moduli:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_0 &amp;amp;= \mod{a ⋅ b}\_{2^{256}} &amp;amp;
x_1 &amp;amp;= \mod{a ⋅ b}\_{2^{256} -1 }
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first one, &lt;span class=&quot;math math-inline&quot;&gt;x_0&lt;&#x2F;span&gt; is just a regular multiply, as it already truncates to 256 bits. The second one, &lt;span class=&quot;math math-inline&quot;&gt;x_1&lt;&#x2F;span&gt;, can be computed directly using a single &lt;code&gt;mulmod&lt;&#x2F;code&gt; operation. This is a rather unknown opcode that computes:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathtt{mulmod}(a, b, c) = \mod{a ⋅ b}_{c}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Put this together, and we have our new mul512 function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract FullMul {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    uint256 constant M1 = 2**256 - 1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function mul512(uint256 a, uint256 b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    public pure returns(uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 x0 = a * b;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        uint256 x1 = mulmod(a, b, M1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (r0, r1) = chineseRemainder(x0, x1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;512-bit multiplication.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Solidity compiler, as of version 0.4.18, does not produce very optimal code here. The &lt;code&gt;chineseRemainder&lt;&#x2F;code&gt; function is so tiny it is not worth the call-overhead, so it should be inlined, but the compiler doesn’t do this. The compiler does recognize that &lt;code&gt;M1&lt;&#x2F;code&gt; can be expressed efficiently as &lt;code&gt;not(0)&lt;&#x2F;code&gt;. Manually inlining results in an efficient multiplication function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract FullMul {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    uint256 constant M1 = 2**256 - 1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function mul512(uint256 a, uint256 b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    public pure returns(uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            let mm := mulmod(a, b, not(0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r0 := mul(a, b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r1 := sub(sub(mm, r0), lt(mm, r0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Optimized full 512 bit multiplication in Solidity.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is our &lt;code&gt;chineseRemainder&lt;&#x2F;code&gt; function (two &lt;code&gt;sub&lt;&#x2F;code&gt;s and one &lt;code&gt;lt&lt;&#x2F;code&gt;) with a &lt;code&gt;mul&lt;&#x2F;code&gt; and &lt;code&gt;mulmod&lt;&#x2F;code&gt; added. We use assembly to avoid an unnecessary branch. The total gas cost is about 60 gas, compared to 5 for a normal multiply and 90 for a standard &lt;code&gt;safeMul&lt;&#x2F;code&gt;. In fact, it is slightly cheaper to use &lt;code&gt;mul512&lt;&#x2F;code&gt; and check that &lt;code&gt;r1&lt;&#x2F;code&gt; is zero than it is to use &lt;code&gt;safeMul&lt;&#x2F;code&gt;!
Conclusion&lt;&#x2F;p&gt;
&lt;p&gt;It is possible to do full precision never-overflowing multiplication in the EVM for less gas than a regular &lt;code&gt;safeMul&lt;&#x2F;code&gt;. This is a good starting point for smart contracts do not want to reject transaction just because an intermediate value overflows.&lt;&#x2F;p&gt;
&lt;p&gt;In the next post, I will introduce a number of simple utility functions for dealing with large numbers. This builds up to a very popular function that nobody has yet implement correctly for all cases. Stay tuned!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Chinese Remainder Theorem</title>
        <published>2017-12-09T00:00:00+00:00</published>
        <updated>2017-12-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/17/chinese-remainder-theorem/"/>
        <id>https://2π.com/17/chinese-remainder-theorem/</id>
        
        <content type="html" xml:base="https://2π.com/17/chinese-remainder-theorem/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\p#1{({#1})}
\gdef\floor#1{\lfloor{#1}\rfloor}
\gdef\ceil#1{\lceil{#1}\rceil}
\gdef\mod#1{[{#1}]}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;chinese-remainder-theorem&quot;&gt;Chinese Remainder Theorem&lt;&#x2F;h1&gt;
&lt;p&gt;A lot of smart contracts use the &lt;code&gt;SafeMath&lt;&#x2F;code&gt; library. It prevents contracts from having incorrect results, but it does so by failing transactions instead of making them correct. Let’s instead try to do the math correct. In this series I will derive some advanced techniques. The Chinese Remainder Theorem is important in these, so I will introduce it first.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract ChineseRemainder {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function chineseRemainder(uint256 x0, uint256 x1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    public pure returns (uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r0 := x0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r1 := sub(sub(x1, x0), lt(x1, x0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Special Chinese Remainder reconstruction in Solidity&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sufficiently advanced mathematics is indistinguishable from magic.&lt;&#x2F;p&gt;
&lt;p&gt;— Arthur C. Clarke’s 3rd law (edited)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning.&lt;&#x2F;strong&gt; This is a very mathematical post. Follow up posts will build on the results derived here, but will not be that math heavy.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Notation.&lt;&#x2F;strong&gt; I use square brackets with a subscript for the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Modulo_operation&quot;&gt;modulo operation&lt;&#x2F;a&gt;. I do this mostly because the conventional notation is cumbersome for nested expressions. The notation is inspired by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Floor_and_ceiling_functions#Notation&quot;&gt;Iverson’s notation&lt;&#x2F;a&gt; for the floor and ceiling functions, &lt;span class=&quot;math math-inline&quot;&gt;\floor{a}&lt;&#x2F;span&gt;, and &lt;span class=&quot;math math-inline&quot;&gt;\ceil{b}&lt;&#x2F;span&gt; respectively. In typeset math, the floor, ceil and mod-&lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; operations look like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\floor{a} &amp;amp;&amp;amp; \ceil{b} &amp;amp;&amp;amp; \mod{c}_m
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;chinese-remainder-theorem-1&quot;&gt;Chinese Remainder Theorem&lt;&#x2F;h2&gt;
&lt;p&gt;Given two &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Coprime_integers&quot;&gt;coprime&lt;&#x2F;a&gt; numbers &lt;span class=&quot;math math-inline&quot;&gt;m_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m_1&lt;&#x2F;span&gt;, any number &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; less than &lt;span class=&quot;math math-inline&quot;&gt;m_0 · m_1&lt;&#x2F;span&gt; can be uniquely written as a pair &lt;span class=&quot;math math-inline&quot;&gt;(x_0, x_1)&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_0 &amp;amp;= \mod{x}_{m_0} &amp;amp; x_1 &amp;amp;= \mod{x}_{m_1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this pair, the original number can be reconstructed as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = \mod{x_0 ⋅ \mod{m_1^{-1}}_{m_0} ⋅ m_1 + x_1 ⋅ \mod{m_0^{-1}}_{m_1} ⋅ m_0}_{m_0 ⋅ m_1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is known as the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chinese_remainder_theorem&quot;&gt;Chinese Remainder Theorem&lt;&#x2F;a&gt;. In fact, it is a special case with only two moduli, the full theorem can have any number of ms as basis. For completeness, here is the full theorem as I expressed it &lt;a href=&quot;&#x2F;09&#x2F;11&#x2F;fast-base-extension-in-residue-number-systems&quot;&gt;almost a decade ago&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
M &amp;amp;= \prod_{[1,n]}^i m_i &amp;amp; \mod{x}_M &amp;amp;= \mod{\sum_{[1,n]}^i \frac{M}{m_i} ⋅ \mod{x ⋅ \frac{m_i}{M} }_{m_i} }_M
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;The general Chinese Remainder Theorem.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-special-modular-basis&quot;&gt;A special modular basis&lt;&#x2F;h2&gt;
&lt;p&gt;The trick I discovered is to use this theorem with a basis &lt;span class=&quot;math math-inline&quot;&gt;m_0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m_1&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;m_1 = m_0 - 1&lt;&#x2F;span&gt; and thus &lt;span class=&quot;math math-inline&quot;&gt;m_0 = m_1 + 1&lt;&#x2F;span&gt;. This allows for very easy computation, for example they have nice inverses (you can convince yourself of their correctness by computing &lt;span class=&quot;math math-inline&quot;&gt;m_1 · m_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m_0 · 1&lt;&#x2F;span&gt;, expanding the result, and taking the modulus.):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mod{m_1^{-1}}_{m_0} &amp;amp;= m_1 &amp;amp;
\mod{m_0^{-1}}_{m_1} &amp;amp;= 1
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This simplifies the before mentioned reconstruction formula to:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = \mod{x_0 ⋅ m_1^2 + x_1 ⋅ m_0}_{m_0 ⋅ m_1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we substitute &lt;span class=&quot;math math-inline&quot;&gt;m_1 = m_0 - 1&lt;&#x2F;span&gt; and do a bit of algebra it reduces to:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = \mod{x_0 + \p{x_1 - x_0} ⋅ m_0}_{m_0^2 - m_0}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The modulo operation now has a large modulus compared to the number inside the brackets. The only time it can ‘wrap around’ is when &lt;span class=&quot;math math-inline&quot;&gt;x_1 &amp;lt; x_0&lt;&#x2F;span&gt; and then only once. When this happens, we need to add an single extra modulus term, &lt;span class=&quot;math math-inline&quot;&gt;m_0^2 - m_0&lt;&#x2F;span&gt;, to get a positive result again. To get rid of the modulo operation, we introduce a variable &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; that is &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; when we need to add the modulus and zero otherwise:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = x_0 + \p{x_1 - x_0} ⋅ m_0 + c ⋅\p{m_0^2 - m_0}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is the reconstruction formula for any basis where &lt;span class=&quot;math math-inline&quot;&gt;m_1 = m_0 - 1&lt;&#x2F;span&gt;. From here on, I use the specific basis &lt;span class=&quot;math math-inline&quot;&gt;m_0 = 2^{256}&lt;&#x2F;span&gt; and thus &lt;span class=&quot;math math-inline&quot;&gt;m_1 = 2^{256} - 1&lt;&#x2F;span&gt;. This is, in a way, the largest and best basis possible in the EVM. It also turns out to lead to even more simplification in the next step.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;output&quot;&gt;Output&lt;&#x2F;h3&gt;
&lt;p&gt;We now have the full number x in theory, but this number is to big to represent directly in code. To represent it, we want to split it in the least significant and most significant bits of x. I will call these r_0 and r_1 respectively. In a 256 bit machine like the EVM they are defined as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
r_0 &amp;amp;= \mod{x}_{2^{256}} &amp;amp; r_1 &amp;amp;= \floor{\frac{x}{2^{256}}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we substitute the reconstruction formula from above, fill in the modular basis and realize that there is an implicit modulo &lt;span class=&quot;math math-inline&quot;&gt;m_0&lt;&#x2F;span&gt;, almost everything cancels out. (do verify if you are not convinced):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
r_0 &amp;amp;= x_0 &amp;amp; r_1 &amp;amp;= x_1 - x_0 - c
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As mentioned earlier, &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; is one if &lt;span class=&quot;math math-inline&quot;&gt;x_1 &amp;lt; x_0&lt;&#x2F;span&gt; and zero otherwise. That is all there is to it; trivially simple!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;So, to summarize, if we know a number modulo &lt;span class=&quot;math math-inline&quot;&gt;2^{256}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;2^{256} - 1&lt;&#x2F;span&gt;, we can convert that to a 512 bit number with the above two equations. This works iff the number is less than &lt;span class=&quot;math math-inline&quot;&gt;2^{256} · (2^{256} - 1)&lt;&#x2F;span&gt;. In solidity the reconstruction algorithm is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract ChineseRemainder {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function chineseRemainder(uint256 x0, uint256 x1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    public pure returns (uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r0 = x0;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        r1 = x1 - x0 - (x1 &amp;lt; x0 ? 1 : 0);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Solidity compiler, as of version 0.4.18, does not produce very optimal code here. It introduces a conditional jump that is entirely avoidable. It can be hand-optimized as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract ChineseRemainder {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function chineseRemainder(uint256 x0, uint256 x1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    public pure returns (uint256 r0, uint256 r1) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assembly {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r0 := x0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            r1 := sub(sub(x1, x0), lt(x1, x0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Two subtractions and one comparisons. This is practically for free in terms of gas!&lt;&#x2F;p&gt;
&lt;p&gt;In the next post, I will use this theorem to build a full 512 bit multiplication in Solidity. It will take just two more instructions, can you guess which?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Blockchain is more than FinTech</title>
        <published>2017-05-04T00:00:00+00:00</published>
        <updated>2017-05-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/17/more-than-fintech/more-than-fintech/"/>
        <id>https://2π.com/17/more-than-fintech/more-than-fintech/</id>
        
        <summary type="html">&lt;h1 id=&quot;blockchain-is-more-than-fintech&quot;&gt;Blockchain is more than FinTech&lt;&#x2F;h1&gt;
&lt;p&gt;Blockchain and FinTech often go hand in hand. And for good reason! But there is more to blockchain than financial innovation. Let’s look at the non-FinTech opportunities on chain.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Basic Contracts: Owned &amp; Terminable</title>
        <published>2017-04-21T00:00:00+00:00</published>
        <updated>2017-04-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/17/basic-contracts/basic-contracts/"/>
        <id>https://2π.com/17/basic-contracts/basic-contracts/</id>
        
        <content type="html" xml:base="https://2π.com/17/basic-contracts/basic-contracts/">&lt;h1 id=&quot;basic-contracts-owned-terminable&quot;&gt;Basic Contracts: Owned &amp;amp; Terminable&lt;&#x2F;h1&gt;
&lt;p&gt;I like to keep smart contracts small and simple to help understanding and reviews. A couple contracts I have developed are useful for everyone. I’ll share them in this and later posts.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;17&#x2F;basic-contracts&#x2F;basic-contracts&#x2F;dog.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;On the blockchain, nobody knows you’re a dog.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;owned&quot;&gt;Owned&lt;&#x2F;h2&gt;
&lt;p&gt;Probably the most used contract is &lt;code&gt;Owned&lt;&#x2F;code&gt;, also know as &lt;code&gt;Ownable&lt;&#x2F;code&gt;. It’s role is to keep track of a special role called &lt;code&gt;owner&lt;&#x2F;code&gt;. The ownership game is played like this: Whoever created the contract is its first owner. Whoever is the current owner, can decide who becomes the new owner. That’s it. By itself, ownership doesn’t mean anything. It’s up to the smart contract developer to embellish this role with privileges. We will see later, when we allow the owner to terminate the contract. The basic contract looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Owned {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    address public owner;    function Owned() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        owner = msg.sender;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }    modifier onlyOwner() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(msg.sender == owner);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }    function transferOwnership(address newOwner) external onlyOwner {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if (newOwner != address(0)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            owner = newOwner;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It does the job. But there’s a couple of things we can do to make it better. Let’s start with the &lt;code&gt;newOwner != address(0)&lt;&#x2F;code&gt; check. The goal here is to prevent the contract from being transfered to an incorrect address. But we are only checking for zero, and not the near infinite amount of other invalid addresses. Instead, we can use the approve-accept paradigm:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Owned {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    address private ownerCandidate;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        modifier onlyOwnerCandidate() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(msg.sender == ownerCandidate);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }    function transferOwnership(address candidate) external onlyOwner {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ownerCandidate = candidate;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }    function acceptOwnership() external onlyOwnerCandidate {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        owner = ownerCandidate;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now the new owner needs to accept the ownership before she receives it. If we accidentally transfered ownership to an invalid address, there is no way this address can accept the ownership. When this happens, we retain ownership and can redo the transfer. Problem solved!&lt;&#x2F;p&gt;
&lt;p&gt;We can do one better: If we accidentally send it to a wrong but existing address, and this address accepts ownership before we realize this and redo our transfer, then our contract still ends up in wrong hands! To solve this we necessarily need some additional authentication mechanism for the new owner. We can use a one time key:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Owned {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    address private ownerCandidate;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    bytes32 private ownerCandidateKeyHash;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    modifier onlyOwnerCandidate(bytes32 key) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(msg.sender == ownerCandidate);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        assert(sha3(key) == ownerCandidateKeyHash);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        _;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }    function transferOwnership(address candidate, bytes32 keyHash)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        public&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        onlyOwner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ownerCandidate = candidate;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ownerCandidateKeyHash = keyHash;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }    function acceptOwnership(bytes32 key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        external&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        onlyOwnerCandidate(key)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        owner = ownerCandidate;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, to transfer ownership you generate a random 256 bit key and hash it using &lt;code&gt;web3.sha3&lt;&#x2F;code&gt;. Then we call &lt;code&gt;transferOwnership&lt;&#x2F;code&gt; with the new owner’s address and the hash of the key. We contact the new owner (through any available secure channel), and hand her the key. The new owner calls acceptOwnership providing the key. The contract verifies the key, and if correct, accepts the new owner.&lt;&#x2F;p&gt;
&lt;p&gt;Note: It is important to use a unique key that has not been used before anywhere. Once used, the key is permanently and publicly visible on the blockchain. This is why I used 256 bit random keys. If I were to use a password, someone could brute-force it.&lt;&#x2F;p&gt;
&lt;p&gt;Do we really need this security device? If we accidentally make a typo in the new owners address, the chances of this addresses accepting ownership are pretty low. With probability bordering on certainty, the typo-address won’t exist and won’t do anything. But let’s assume we are transferring the ownership of a very valuable contract, and evil people are on the prey. In that scenario, this technique introduces an additional authentication factor.&lt;&#x2F;p&gt;
&lt;p&gt;Which one of the two solutions is best depends on your security&#x2F;usability trade-off. The later adds an additional authentication factor, but it also requires communicating a key over a secure channel, which is huge penalty in the usability field.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;terminable&quot;&gt;Terminable&lt;&#x2F;h2&gt;
&lt;p&gt;Contract &lt;code&gt;Owned&lt;&#x2F;code&gt; often goes hand in with contract &lt;code&gt;Terminable&lt;&#x2F;code&gt;, also known as &lt;code&gt;Mortal&lt;&#x2F;code&gt;. This contract adds a function only owner can trigger, the function to permanently terminate the contract. Any Ether owned by the contract get send to the owner. It looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Terminable is Owned {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function terminate() external onlyOwner {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        selfdestruct(owner);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This terminates the contract and sends any Ether held by the contract back to the owner. Easy-peasy. But! Ether is no longer the only currency in Ethereum. There are many tokens out there, and smart contracts can own tokens too. If you use the above &lt;code&gt;terminate&lt;&#x2F;code&gt; function on a contract that has tokens, those tokens are permanently lost!&lt;&#x2F;p&gt;
&lt;p&gt;Tokens, as a reminder, tend to have the following interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract IERC20Basic {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function balanceOf(address who) constant public returns (uint);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function transfer(address to, uint value) public returns (bool ok);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    event Transfer(address from, address to, uint value);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can use these functions to send the tokens to owner on &lt;code&gt;terminate&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;contract Terminable is Owned {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    function terminate(IERC20Basic[] tokens) external onlyOwner {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Transfer tokens to owner&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        for(uint i = 0; i &amp;lt; tokens.length; i++) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            uint256 balance = tokens[i].balanceOf(this);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            tokens[i].transfer(owner, balance);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &#x2F;&#x2F; Transfer Ether to owner and terminate contract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        selfdestruct(owner);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, we need to be really careful here! The innocent looking &lt;code&gt;tokens[i].balanceOf(…)&lt;&#x2F;code&gt; and &lt;code&gt;tokens[i].transfer(…)&lt;&#x2F;code&gt; are function calls to external contracts. This means they can fail or do nasty things like re-entering your contract!&lt;&#x2F;p&gt;
&lt;p&gt;Let’s consider failure first. Solidity bubbles the failures up the call stack, so when one of the calls fails, it will fail the entire terminate operation. This default behavior is not bad, we can inspect which token contract made us fail, exclude the misbehaving token and try again. You will not recover that token. This is fine; who wants to own a broken&#x2F;malicious token anyway?&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;terminate&lt;&#x2F;code&gt; call can also fail when it runs out of gas. This puts an upper limit to the number of tokens types that can be recovered: at some point we reach the block gas limit. If your contract is going to own many different kinds of tokens, (for example an exchange) you need to come up with something better.&lt;&#x2F;p&gt;
&lt;p&gt;This leaves reentrancy. It is not a problem for our &lt;code&gt;Terminable&lt;&#x2F;code&gt; contract: &lt;code&gt;onlyOwner&lt;&#x2F;code&gt; prevents other contracts from calling the function. But this contract is not meant to be used on its own. When you inherit from &lt;code&gt;Terminable&lt;&#x2F;code&gt; and add external functions, remember that they can be indirectly called from the terminate function!&lt;&#x2F;p&gt;
&lt;p&gt;In general, don’t try to reclaim tokens you don’t trust. (This is a special case of the general lemma: don’t interact with contracts you don’t trust)&lt;&#x2F;p&gt;
&lt;p&gt;Cool! How do I use this?&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;Terminable&lt;&#x2F;code&gt; contract is contributed to the Zeppelin project under the name &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OpenZeppelin&#x2F;zeppelin-solidity&#x2F;blob&#x2F;master&#x2F;contracts&#x2F;lifecycle&#x2F;TokenDestructible.sol&quot;&gt;&lt;code&gt;TokenDestructable&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;. For the &lt;code&gt;Ownable&lt;&#x2F;code&gt; there already exists a similar contract called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OpenZeppelin&#x2F;zeppelin-solidity&#x2F;blob&#x2F;master&#x2F;contracts&#x2F;ownership&#x2F;Claimable.sol&quot;&gt;&lt;code&gt;Claimable&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Entropy Coding</title>
        <published>2016-02-03T00:00:00+00:00</published>
        <updated>2016-02-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/16/entropycoding/"/>
        <id>https://2π.com/16/entropycoding/</id>
        
        <content type="html" xml:base="https://2π.com/16/entropycoding/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{#1 #2 #3}
\gdef\p#1{({#1})}
\gdef\floor#1{\lfloor{#1}\rfloor}
\gdef\ceil#1{\lceil{#1}\rceil}
\gdef\mod#1{[{#1}]}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;entropy-coding&quot;&gt;Entropy Coding&lt;&#x2F;h1&gt;
&lt;p&gt;In these lab notes I derive an arithmetic coder that is optimally efficient using 64 bit registers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;range-multiplication&quot;&gt;Range multiplication&lt;&#x2F;h2&gt;
&lt;p&gt;Given two sub-intervals of &lt;span class=&quot;math math-inline&quot;&gt;\delim[{0, 1})&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
B &amp;amp;= \delim[{b₀, b₁}) \\
S &amp;amp;= \delim[{s₀, s₁})
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and we want to compute the product of &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; into &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
S · B = \delim[{bₒ + s₀ (b₁ - b₀), bₒ + s₁(b₁ - b₀)})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;64-bit-intervals&quot;&gt;64 bit intervals&lt;&#x2F;h2&gt;
&lt;p&gt;We want to represent non-empty subintervals of &lt;span class=&quot;math math-inline&quot;&gt;\delim[{0,1})&lt;&#x2F;span&gt; with 64 bit integers, &lt;span class=&quot;math math-inline&quot;&gt;𝔹^{64}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\b{\mathtt{b}}
\gdef\r{\mathtt{r}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;\p{\b,\r} ∈ \p{𝔹^{64}}^2&lt;&#x2F;span&gt; with the following map:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\b,\r} ↦ \delim[{\frac{\b}{2^{64}}, \frac{\b + \r + 1}{2^{64}}})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Some examples of this map:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\p{0,0} &amp;amp;↦ \delim[{0, 2^{-64}}) \\
\p{0,2^{64}-1} &amp;amp;↦ \delim[{0, 1}) \\
\p{2^{64}-1, 0} &amp;amp;↦ \delim[{1 - 2^{-64}, 1}) \\
\p{2^{64}-1, 2^{64}-1} &amp;amp;↦ \delim[{1 - 2^{-64}, 2 - 2^{-64}}) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where the last example is invalid. For validity we require&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\b + \r + 1 ≤ 2^{64}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A reverse map can be created as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{l, h}) ↦ \p{\ceil{l · 2^{64}}, \floor{h · 2^{64}} - \ceil{l · 2^{64}} - 1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In order for &lt;span class=&quot;math math-inline&quot;&gt;\b&lt;&#x2F;span&gt; to be in &lt;span class=&quot;math math-inline&quot;&gt;𝔹^{64}&lt;&#x2F;span&gt; we require &lt;span class=&quot;math math-inline&quot;&gt;0 ≤ \ceil{l · 2^{64}} &amp;lt; 2^{64}&lt;&#x2F;span&gt;. We already have &lt;span class=&quot;math math-inline&quot;&gt;0 ≤ l &amp;lt; 1&lt;&#x2F;span&gt;. To satisfy the upper bound we additionally require:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
l ≤ 1 - 2^{-64}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In order for &lt;span class=&quot;math math-inline&quot;&gt;\r&lt;&#x2F;span&gt; to be in &lt;span class=&quot;math math-inline&quot;&gt;𝔹^{64}&lt;&#x2F;span&gt; we require &lt;span class=&quot;math math-inline&quot;&gt;0 ≤ \floor{h · 2^{64}} - \ceil{l · 2^{64}} - 1 &amp;lt; 2^{64}&lt;&#x2F;span&gt;. The upper bound is already satisfied. To satisfy the lower bound we require:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
0 &amp;amp;≤ \floor{h · 2^{64}} - \ceil{l · 2^{64}} - 1 \\
&amp;amp;&amp;lt; \p{h - l} · 2^{64} - 1 - 1 \\
l + 2^{-63} &amp;amp;&amp;lt; h
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;span class=&quot;math math-inline&quot;&gt;h ≤ 1&lt;&#x2F;span&gt; this also implies the stronger bound &lt;span class=&quot;math math-inline&quot;&gt;l &amp;lt; 1 - 2^{-63}&lt;&#x2F;span&gt; on &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;. For the reverse map to work we need &lt;span class=&quot;math math-inline&quot;&gt;l + 2^{-63} &amp;lt; h ≤ 1&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Going full circle results in:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{l, h}) ↦ \p{\b,\r} ↦ \delim[{\frac{\ceil{l · 2^{64}}}{2^{64}}, \frac{\floor{h · 2^{64}}}{2^{64}}})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It can be easily shown that the later interval is always a subinterval of the former. It is also easily seen that this operation is idempotent.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;64-bit-interval-multiply&quot;&gt;64 bit interval multiply&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\p{\b_B,\r_B} &amp;amp;↦ \delim[{\frac{\b_B}{2^{64}}, \frac{\b_B + \r_B + 1}{2^{64}}}) \\
\p{\b_S,\r_S} &amp;amp;↦ \delim[{\frac{\b_S}{2^{64}}, \frac{\b_S + \r_S + 1}{2^{64}}})
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
  \frac{\b_B}{2^{64}} + \frac{\b_S}{2^{64}} \p{\frac{\b_B + \r_B + 1}{2^{64}} - \frac{\b_B}{2^{64}}},
  \frac{\b_B}{2^{64}} + \frac{\b_S + \r_S + 1}{2^{64}} \p{\frac{\b_B + \r_B + 1}{2^{64}} - \frac{\b_B}{2^{64}}}
})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{
  \frac{\b_B}{2^{64}} + \frac{\b_S\p{\r_B + 1}}{2^{128}},
  \frac{\b_B}{2^{64}} + \frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{128}}
})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first bound in &lt;span class=&quot;math math-inline&quot;&gt;l + 2^{-63} &amp;lt; h ≤ 1&lt;&#x2F;span&gt; gives:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\frac{\b_B}{2^{64}} + \frac{\b_S\p{\r_B + 1}}{2^{128}} + 2^{-63} &amp;amp;&amp;lt; 
\frac{\b_B}{2^{64}} + \frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{128}} \\
\b_S\p{\r_B + 1} + 2^{64} &amp;amp;&amp;lt; 
\p{\b_S + \r_S + 1}\p{\r_B + 1}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The second bound in &lt;span class=&quot;math math-inline&quot;&gt;l + 2^{-63} &amp;lt; h ≤ 1&lt;&#x2F;span&gt; gives:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\frac{\b_B}{2^{64}} + \frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{128}} &amp;amp; ≤ 1 \\
\b_B · 2^{64} + \p{\b_S + \r_S + 1}\p{\r_B + 1} &amp;amp; ≤ 2^{128}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mapping this back to &lt;span class=&quot;math math-inline&quot;&gt;\p{𝔹^{64}}²&lt;&#x2F;span&gt; using the reverse map:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\b_B&amp;#39; &amp;amp;= \ceil{l · 2^{64}} \\
 &amp;amp;= \ceil{\p{ \frac{\b_B}{2^{64}} + \frac{\b_S\p{\r_B + 1}}{2^{128}} }·2^{64}} \\
 &amp;amp;= \b_B + \ceil{\frac{\b_S\p{\r_B + 1}}{2^{64}} } \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since we have &lt;span class=&quot;math math-inline&quot;&gt;\b_S &amp;lt; 2^{64}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\r_B + 1 ≤ 2^{64}&lt;&#x2F;span&gt; we can implement this using a 64 bit multiply with 128 bit result, and an 128 bit and 64 bit add as &lt;span class=&quot;math math-inline&quot;&gt;\b_S · \r_B + \b_S&lt;&#x2F;span&gt;, or in code:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;uint64 h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;tie&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b_S&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r_B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;tie&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; add128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b_S&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint64 t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;l &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;b_B &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where the final term implements the ceiling operator.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\r_B&amp;#39; &amp;amp;= \floor{h · 2^{64}} - \ceil{l · 2^{64}} - 1 \\
&amp;amp;= \floor{\p{\frac{\b_B}{2^{64}} + \frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{128}}}· 2^{64}} - \b_B + \ceil{\frac{\b_S\p{\r_B + 1}}{2^{64}}} - 1 \\
&amp;amp;= \floor{\frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{64}}} - \ceil{\frac{\b_S\p{\r_B + 1}}{2^{64}}} - 1 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To obtain a valid result we need &lt;span class=&quot;math math-inline&quot;&gt;0 ≤ \r_B&amp;#39; &amp;lt; 2^{64}&lt;&#x2F;span&gt;. The lower bound goes like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
0 &amp;amp;≤ \floor{\frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{64}}} - \ceil{\frac{\b_S\p{\r_B + 1}}{2^{64}}} - 1 \\
0 &amp;amp;≤ \frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{64}} - \frac{\b_S\p{\r_B + 1}}{2^{64}} - 1 \\
1 &amp;amp;&amp;lt; \frac{\p{\r_S + 1}\p{\r_B + 1}}{2^{64}} \\
2^{64} &amp;amp;≤ \p{\r_S + 1}\p{\r_B + 1} \\
\r_S &amp;amp;≥ \frac{2^{64}}{\r_B + 1} - 1 \\
\r_S &amp;amp;≥ 1
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where in the last step I have used &lt;span class=&quot;math math-inline&quot;&gt;\r_B ≥ 2⁶³&lt;&#x2F;span&gt;, which will be enforced later, in normalization. The upper bound &lt;span class=&quot;math math-inline&quot;&gt;\r_B&amp;#39; &amp;lt; 2^{64}&lt;&#x2F;span&gt; goes like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
2^{64} &amp;amp;&amp;gt; \floor{\frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{64}}} - \ceil{\frac{\b_S\p{\r_B + 1}}{2^{64}}} - 1 \\
2^{64} &amp;amp;&amp;gt; \frac{\p{\b_S + \r_S + 1}\p{\r_B + 1}}{2^{64}} - \ceil{\frac{\b_S\p{\r_B + 1}}{2^{64}}} - 1 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The second term we already have as &lt;code&gt;t&lt;&#x2F;code&gt;. For the first term we need another tricky multiply. In this case we have &lt;span class=&quot;math math-inline&quot;&gt;\b_S + \r_S + 1 ≤ 2^{64}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\r_B + 1 ≤ 2^{64}&lt;&#x2F;span&gt;, so the intermediate result can actually be &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt;. The &lt;span class=&quot;math math-inline&quot;&gt;-1&lt;&#x2F;span&gt; will make sure the final result will be in &lt;span class=&quot;math math-inline&quot;&gt;𝔹^{64}&lt;&#x2F;span&gt;. We must be careful, but modular arithmetic will handle the overflow fine. Let&#x27;s rewrite the multiplication in values &lt;span class=&quot;math math-inline&quot;&gt;&amp;lt;2^{64}&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\p{\b_S + \r_S}·\r_B + \p{\b_S + \r_S} + \r_B + 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now we can calculate the final interval:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;tie&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b_S &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r_S&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r_B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;tie&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; add128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b_S &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r_S&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;tie&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; add128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r_B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;tie&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; add128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;r_B &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;normalization&quot;&gt;Normalization&lt;&#x2F;h2&gt;
&lt;p&gt;Given an interval &lt;span class=&quot;math math-inline&quot;&gt;\delim[{l,h})&lt;&#x2F;span&gt; we want to extract the prefix bits that won&#x27;t
change anymore. To determine which bits won&#x27;t change it is useful to look at &lt;span class=&quot;math math-inline&quot;&gt;h-l&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
l &amp;amp;= \mathtt{0.0001101101000111111110110010001001}… \\
h &amp;amp;= \mathtt{0.0001101101001000000011000010000111}… \\
h - l &amp;amp;= \mathtt{0.}
\underbrace{\mathtt{000000000000}}_{\mathrm{settled}}
\underbrace{\mathtt{0000000}}_{\mathrm{outstanding}}
\underbrace{\mathtt{100001111111110}…}_{\mathrm{active}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The settled bits can be written directly to the output. The outstanding bits can still change because of a carry, but are otherwise settled. To normalize this interval we output the first 12 bits, note that there are 7 bits outstanding, and rescale the interval by &lt;span class=&quot;math math-inline&quot;&gt;2^{12+7}&lt;&#x2F;span&gt;. There is one edge case we can consider:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
h - l &amp;amp;= \mathtt{0.0000000000000000000100000000000000}… \\
&amp;amp;= \mathtt{0.00000000000000000000}
   \underbrace{\mathtt{11111111111111}…}_{\mathrm{active}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Writing the number in two different but equal ways can result in a different number of leading zeros. We take the one that results in the largest number of leading zeros. So in general we want to rescale by &lt;span class=&quot;math math-inline&quot;&gt;2^n&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; given by:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
n = \floor{-\log_2 \p{h - l}} - 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The interval is normalized if &lt;span class=&quot;math math-inline&quot;&gt;n=0&lt;&#x2F;span&gt; and thus iff &lt;span class=&quot;math math-inline&quot;&gt;\frac 12 &amp;lt; h - l&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
l&amp;#39; = l·2^n &amp;amp;= \mathtt{1101101000111111.110110010001001}… \\
h&amp;#39; = h·2^n &amp;amp;= \mathtt{1101101001000000.011000010000111}… \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here we can be in one of two situations, either the integral parts are the same, or &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt;&#x27;s is one larger that &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;&#x27;s.
In this case &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt;&#x27;s is in fact one larger. We can subtract the integral part of &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
l&amp;#39;&amp;#39; = l&amp;#39;-\floor{l&amp;#39;} &amp;amp;= \mathtt{0.110110010001001}… \\
h&amp;#39;&amp;#39; = h&amp;#39;-\floor{l&amp;#39;} &amp;amp;= \mathtt{1.011000010000111}… \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We have now scaled our &lt;span class=&quot;math math-inline&quot;&gt;\delim[{l,h})&lt;&#x2F;span&gt; interval to a subinterval of &lt;span class=&quot;math math-inline&quot;&gt;\delim[{0,2})&lt;&#x2F;span&gt;, but we also have&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
0 &amp;amp;≤ l &amp;lt; 1 \\
\frac{1}{2} &amp;amp;&amp;lt; h-l ≤ 1
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In summary, an interval is normalized when it is a subinterval of &lt;span class=&quot;math math-inline&quot;&gt;\delim[{0,2})&lt;&#x2F;span&gt; and the above inequalities hold.&lt;&#x2F;p&gt;
&lt;p&gt;After normalization we end up in one of two cases:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\delim[{h,l}) ⊆ \delim[{0,1})&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\delim[{h,l}) ⊈ \delim[{0,1})&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Our situation is as above, there are no bits outstanding.
This is when we have a carry outstanding and &lt;span class=&quot;math math-inline&quot;&gt;h &amp;gt; 1&lt;&#x2F;span&gt;.
After further narrowing of the interval we will eventually end up in the first case and flush the carry buffer, or we will end up in a third case:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;\delim[{h,l}) ⊆ \delim[{1,2})&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In this third case we should add the carry and subtract &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt; from both &lt;span class=&quot;math math-inline&quot;&gt;h&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt;. We are then effectively back in the first case.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;64-bit-normalization&quot;&gt;64 bit normalization&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\delim[{\frac{\b}{2^{64}}, \frac{\b + \r + 1}{2^{64}}})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For this to be normalized in &lt;span class=&quot;math math-inline&quot;&gt;\delim[{0, 2})&lt;&#x2F;span&gt; we must have&lt;&#x2F;p&gt;
&lt;p&gt;And the normalization condition &lt;span class=&quot;math math-inline&quot;&gt;½ &amp;lt; h-l ≤ 1&lt;&#x2F;span&gt; reduces to &lt;span class=&quot;math math-inline&quot;&gt;2⁶³ ≤ \r &amp;lt; 2^{64}&lt;&#x2F;span&gt;. This essentially means that &lt;span class=&quot;math math-inline&quot;&gt;\r ∊ 𝔹^{64}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\r&lt;&#x2F;span&gt; must have the most significant bit set.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
n &amp;amp;= \floor{-\log_2 \p{\frac{\r + 1}{2^{64}}}} - 1 \\
&amp;amp;= 63 - \ceil{\log_2 \p{\r + 1}} \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The ceiling and the &lt;span class=&quot;math math-inline&quot;&gt;+1&lt;&#x2F;span&gt; cancel, except when &lt;span class=&quot;math math-inline&quot;&gt;\r=0&lt;&#x2F;span&gt;. What remains is essentially a count leading zeroes operation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; count_leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
l&amp;#39;&amp;#39; &amp;amp;= l·2^n - \floor{l·2^n} = \mod{\frac{\b}{2^{64-n}}}_1  \\
h&amp;#39;&amp;#39; &amp;amp;= h·2^n - \floor{l·2^n} = \frac{\b + \r + 1}{2^{64-n}} - \floor{\frac{\b}{2^{64-n}}}\\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\mod{x}_1 = x - \floor{x}&lt;&#x2F;span&gt; is the fractional part operator.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\b&amp;#39;&amp;#39; &amp;amp;= \ceil{l&amp;#39;&amp;#39; · 2^{64}} \\
&amp;amp;= \ceil{\mod{\frac{\b}{2^{64-n}}}_1 · 2^{64}} \\
&amp;amp;= \ceil{\mod{\frac{\b}{2^{64-n}}_1 · 2^{64}}_{2^{64}}} \\
&amp;amp;= \mod{\b · 2^n}_{2^{64}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\mod{x}_{2^{64}} = x \;\mathrm{mod}\; 2^{64}&lt;&#x2F;span&gt; is the modular operator. Since &lt;span class=&quot;math math-inline&quot;&gt;\b · 2^n&lt;&#x2F;span&gt; is strictly integer, the ceiling has no effect and the operation reduces to a simple right shift:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\r&amp;#39;&amp;#39; &amp;amp;= \floor{h&amp;#39;&amp;#39; · 2^{64}} - \ceil{l&amp;#39;&amp;#39; · 2^{64}} - 1 \\
&amp;amp;= \floor{h&amp;#39;&amp;#39; · 2^{64}} - \b&amp;#39;&amp;#39; - 1 \\
&amp;amp;= \floor{\p{\frac{\b + \r + 1}{2^{64-n}} - \floor{\frac{\b}{2^{64-n}}}} · 2^{64}} - \b&amp;#39;&amp;#39; - 1 \\
&amp;amp;= \floor{\p{\b + \r + 1}·2^n - \floor{\frac{\b}{2^{64-n}}}· 2^{64} } - \b&amp;#39;&amp;#39; - 1 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
&amp;amp;= \floor{\p{\frac{\b·2^n}{2^{64}} - \floor{\frac{\b·2^n}{2^{64}}}}· 2^{64} + \p{\r + 1}·2^n} - \b&amp;#39;&amp;#39; - 1 \\
&amp;amp;= \floor{\mod{\b·2^n}_{2^{64}} + \p{\r + 1}·2^n} - \b&amp;#39;&amp;#39; - 1 \\
&amp;amp;= \floor{\b&amp;#39;&amp;#39; + \p{\r + 1}·2^n} - \b&amp;#39;&amp;#39; - 1 \\
&amp;amp;= \r·2^n + 2^n - 1 \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is essentially shifting &lt;span class=&quot;math math-inline&quot;&gt;\r&lt;&#x2F;span&gt; to the right &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; places while shifting in ones. We don&#x27;t need to worry about overflow here because &lt;span class=&quot;math math-inline&quot;&gt;\r&lt;&#x2F;span&gt; is strictly less than &lt;span class=&quot;math math-inline&quot;&gt;2^{64-n}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;UL&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;appendix-128-bit-arithmetic&quot;&gt;Appendix: 128 Bit arithmetic&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;pair&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul128_emu&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-type&quot;&gt;	using uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;	const uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;ffffffff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;	const uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;ffffffff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;	const uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w3 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;ffffffff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;ffffffff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;	const uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;	const uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; w3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; make_pair&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;pair&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; add128&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	l &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;l &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; make_pair&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; l&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Perfect ending for entropy coding</title>
        <published>2016-02-03T00:00:00+00:00</published>
        <updated>2016-02-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/16/entropycodingend/"/>
        <id>https://2π.com/16/entropycodingend/</id>
        
        <content type="html" xml:base="https://2π.com/16/entropycodingend/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\delim#1#2#3{#1 #2 #3}
\gdef\set#1{\mathcal{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;perfect-ending-for-entropy-coding&quot;&gt;Perfect ending for entropy coding&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;finitely-odd-numbers&quot;&gt;Finitely odd numbers&lt;&#x2F;h2&gt;
&lt;p&gt;Here we use the ideas of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www3.sympatico.ca&#x2F;mt0000&#x2F;biacode&#x2F;biacode.html&quot;&gt;Matt Timmermans&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;bijective.dogma.net&#x2F;&quot;&gt;David A. Scott&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the above, we derived a method for generating an infinite stream of bits representing a real number that encodes our symbols. If the stream of symbols is finite, we want to end the stream of bits. We do this by picking a so called &lt;em&gt;finitely odd number&lt;&#x2F;em&gt;, these numbers:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
&amp;amp;\mathtt{0.00000000000000}… \\
&amp;amp;\mathtt{0.10000000000000}… \\
&amp;amp;\mathtt{0.01000000000000}… \\
&amp;amp;\mathtt{0.11000000000000}… \\
&amp;amp;\mathtt{0.00100000000000}… \\
&amp;amp;\mathtt{0.01100000000000}… \\
&amp;amp;\mathtt{0.10100000000000}… \\
&amp;amp;\mathtt{0.11100000000000}… \\
&amp;amp;\mathtt{0.00010000000000}… \\
&amp;amp;\phantom{\mathtt{0.000100}}⋮
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that they are not sorted as ordinary real numbers, they are rather sorted in a form of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Shortlex_order&quot;&gt;shortlex order&lt;&#x2F;a&gt;. This is important to us because we want to encode the stream of symbols as the shortest possible bit string.&lt;&#x2F;p&gt;
&lt;p&gt;We store the first available finitely odd number that uniquely encodes the sequence of symbols. This means the number we pick must be in the final interval. But this number will also be in the final interval of all the prefixes of our current symbol sequence. To solve this problem we do the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;On start we set the current ending to &lt;span class=&quot;math math-inline&quot;&gt;e = \mathtt{0.0000}…&lt;&#x2F;span&gt; and reserve &lt;span class=&quot;math math-inline&quot;&gt;E = ∅&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Every time we encode a symbol we:
&lt;ul&gt;
&lt;li&gt;Reserve the previous ending: Set &lt;span class=&quot;math math-inline&quot;&gt;E&amp;#39; = E ∪ \set{e}&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Set &lt;span class=&quot;math math-inline&quot;&gt;e&amp;#39;&lt;&#x2F;span&gt; to the first number in &lt;span class=&quot;math math-inline&quot;&gt;\delim[{h, l})&lt;&#x2F;span&gt; and not in &lt;span class=&quot;math math-inline&quot;&gt;E&amp;#39;&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;On end we write &lt;span class=&quot;math math-inline&quot;&gt;e&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ending-a-bit-streams&quot;&gt;Ending a bit streams&lt;&#x2F;h2&gt;
&lt;p&gt;At any point in encoding, the written bit stream can be sorted in four states:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
…\mathtt{0}⁻ &amp;amp; \\
…\mathtt{0}⁺ &amp;amp; \\
…\mathtt{1}⁻ &amp;amp; \\
…\mathtt{1}⁺ &amp;amp; \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;⁺&lt;&#x2F;span&gt; denotes that we can add a carry and &lt;span class=&quot;math math-inline&quot;&gt;⁻&lt;&#x2F;span&gt; means we can not. The empty bit stream, the initial state, can be considered part of &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;To do.&lt;&#x2F;strong&gt; Insert state diagram.&lt;&#x2F;p&gt;
&lt;p&gt;Besides any potential bits to output, we can also decide to trigger the carry or not. To denote endings we leave off the infinite tail of zeros and prefix a &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt; if we want to trigger the carry and &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt; if we don&#x27;t. The ordered sequence of valid endings for each state are:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.011}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.011}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.101}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.101}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.111}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.111}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.0001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.0001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The situation for &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁻&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻&lt;&#x2F;span&gt; are identical. The sequence for &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺&lt;&#x2F;span&gt; only differs in the first entry. With the exception of the first two items in &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺&lt;&#x2F;span&gt;, these sequences are simply the finitely odd numbers, directly or shifted to the left once.&lt;&#x2F;p&gt;
&lt;p&gt;The endings also need to fall in the range &lt;span class=&quot;math math-inline&quot;&gt;\delim[{h, l})&lt;&#x2F;span&gt;, further trimming the set of possibilities.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;updating-and-pruning-the-reserved-set&quot;&gt;Updating and pruning the reserved set&lt;&#x2F;h2&gt;
&lt;p&gt;The set &lt;span class=&quot;math math-inline&quot;&gt;E&lt;&#x2F;span&gt; can currently only grow, and does so with one entry for every symbol. As we start outputting bits and carries we need to update the set. Assume the set only contains valid entries, then for each of the ten possible transitions we do the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Writing a carry, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺ → \mathtt{1}⁻&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a carry, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺ → \mathtt{0}⁻&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a zero, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁻ → \mathtt{0}⁺&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.011}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.101}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.111}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.0001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a zero, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺ → \mathtt{0}⁺&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a zero, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻ → \mathtt{0}⁺&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.011}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.101}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.111}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.0001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a zero, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺ → \mathtt{0}⁺&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a one, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁻ → \mathtt{1}⁻&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.011}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.101}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.111}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.0001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a one, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺ → \mathtt{1}⁺&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a one, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻ → \mathtt{1}⁻&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁻&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.011}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.101}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.111}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.0001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writing a one, &lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺ → \mathtt{1}⁺&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;→&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1}⁺&lt;&#x2F;span&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.01}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.1}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{1.11}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathtt{0.001}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;\;\;⋮&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We observe that the transitions preserve the order!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>White Paper on Coblue&#x27;s Key Management</title>
        <published>2015-08-27T00:00:00+00:00</published>
        <updated>2015-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/15/coblue-key-management/"/>
        <id>https://2π.com/15/coblue-key-management/</id>
        
        <content type="html" xml:base="https://2π.com/15/coblue-key-management/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\⊕{\bigoplus}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;white-paper-on-coblue-s-key-management&quot;&gt;White Paper on Coblue&#x27;s Key Management&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;executive-summary&quot;&gt;Executive Summary&lt;&#x2F;h2&gt;
&lt;p&gt;Coblue allows people to work together using secure resilient systems. We assume that every user, device or connection can fail or can become malicious. This includes Coblue itself. We expect malicious actors to have the resources of powerful nation-states. Our software runs on a wide range of hardware, from smartphones to servers. Our software handles various modes of connectivity, if connected at all. These assumptions are harsh, but true for modern information systems. It requires a different approach to system design.&lt;&#x2F;p&gt;
&lt;p&gt;This paper presents Coblue’s approach to secure resilient systems. We demonstrate our approach to be more secure, less complex, faster and more efficient than alternatives. Resilient systems need redundancy and are therefore necessarily networked systems. Networked systems are hindered by eight often overlooked factors. Resilient systems require resilient networks, and the most resilient networks are distributed networks.&lt;&#x2F;p&gt;
&lt;p&gt;Distributed systems cannot guarantee consistency, availability and partition tolerance at the same time. Instead, the Coblue solution offers strong eventual consistency. In order to ensure eventual consistency that cannot be tampered with, we use several techniques.&lt;&#x2F;p&gt;
&lt;p&gt;Our cipher suite is based upon &lt;em&gt;Keccak-f₁₆₀₀&lt;&#x2F;em&gt; for all symmetric cryptography and &lt;em&gt;Ed448&lt;&#x2F;em&gt; for all asymmetric cryptography, and we have focused on simplicity for our implementation. The advantage of the algorithms we use is the invulnerability against the side-channel attacks AES implementations suffer from. The key strengths of our implementation of the algorithms are beyond the upper bounds of all evaluation models, and hence it is very likely that breaking the used cryptography remains infeasible. On top of that, our cipher suite offers more security through a number of extra features, not offered by any other cipher suite.&lt;&#x2F;p&gt;
&lt;p&gt;Coblue’s Toolbox consists of cryptographic techniques, Defensive Programming and Secure Memory. Defensive Programming hardening techniques offer extra defence in case a user’s device is under attack. Secure Memory protects application running in untrusted environments. A range of low-level cryptographic primitives ensure secure protocols and secure systems. Our advanced cryptography allows us to fight denial-of-service attacks, enables having key escrow without a trusted third party, and enable secure authentication of users over insecure channels.&lt;&#x2F;p&gt;
&lt;p&gt;Coblue’s networking stack constructs resilient end-to-end secure channels in hostile environments while keeping the communication overhead to only ten bytes per packet. The networking stack can establish secure connections as soon as simple web-browsing is possible or while active in a local area network. The decentral network that is being formed is peer-to-peer and requires no central coordination, unless applications specifically demand so.&lt;&#x2F;p&gt;
&lt;p&gt;Input&#x2F;output routines and storage are a process’ interface to the world, which makes it where the strongest defences need to be. Since this code is so critical to get correct, we decided to generate our I&#x2F;O procedures from formal specifications. We specify structures in a domain specific formal language, and our tooling generates most of the data handling code from the formal specification, including all binary encoding&#x2F;decoding code.&lt;&#x2F;p&gt;
&lt;p&gt;Our cipher suite and toolbox are most recently employed for key management in a concrete application: Storro. Storro is a tool to securely share and collaborate on data on a project basis. Five different user roles are specified: &lt;em&gt;outsider&lt;&#x2F;em&gt; (i.e. not part of a project), &lt;em&gt;facilitator&lt;&#x2F;em&gt;, &lt;em&gt;observer&lt;&#x2F;em&gt;, &lt;em&gt;participant&lt;&#x2F;em&gt; and &lt;em&gt;administrator&lt;&#x2F;em&gt;. A license for a project is necessary for interacting, and a license needs to be renewed periodically to ensure it has not yet expired. Our Distributed Content Addressed Store stores all information related to every project for which the user is at least a facilitator of a project. Version management safeguards the exchange and integrity of the project’s version history. Version management creates a strong eventually consistent latest version. The user management ensures that new users can be added to and removed from a project, while at the same time ensuring that roles cannot be escalated.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;paper-overview&quot;&gt;Paper overview&lt;&#x2F;h2&gt;
&lt;p&gt;In the first chapter we will introduce our basic cipher suite. We then explain our algorithm and key strength choices. The chapter concludes by comparing our transport security protocol with existing offerings. The second chapter showcases the Coblue toolbox. It explains the various techniques used to create secure resilient systems. It starts with a description of the non-cryptographic defences necessary for running secure applications on commodity hardware. It explains secure key generation and basic cryptographic primitives. The next section covers advanced techniques that facilitate decentralized systems. This is followed by our works-everywhere network communication stack. Finally we describe our approach to secure input&#x2F;output and storage. The last chapter contains a case study of a complex real world application currently in production.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resilient-systems&quot;&gt;Resilient systems&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;The network is reliable&lt;&#x2F;li&gt;
&lt;li&gt;Latency is zero&lt;&#x2F;li&gt;
&lt;li&gt;Bandwidth is infinite&lt;&#x2F;li&gt;
&lt;li&gt;The network is secure&lt;&#x2F;li&gt;
&lt;li&gt;Topology doesn&#x27;t change&lt;&#x2F;li&gt;
&lt;li&gt;There is one administrator&lt;&#x2F;li&gt;
&lt;li&gt;Transport cost is zero&lt;&#x2F;li&gt;
&lt;li&gt;The network is homogeneous&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;— The &quot;8 Fallacies of Networking&quot;. Peter Deutsch (Sun Microsystems Labs, 1991)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Resilient systems are necessarily distributed computer systems. Resilient systems cannot have a single point of failure. So a central server is not allowed. Servers can be used, but they need to have sufficient redundancy for the application. The servers would then themselves form a distributed computer system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Theorem&lt;&#x2F;strong&gt;: &lt;em&gt;CAP Theorem&lt;&#x2F;em&gt;. No distributed computer systems can give all three of the following desirable guarantees:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Consistency: All devices see the same data at the same time.&lt;&#x2F;li&gt;
&lt;li&gt;Availability: Every request receives a response about whether it succeeded or failed.&lt;&#x2F;li&gt;
&lt;li&gt;Partition tolerance: The system continues to operate despite arbitrary partitioning due to network failures.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Network failure is unavoidable, so the choice is between consistency and availability. Consensus based protocols like Paxos sacrifice availability. When the network splits in two, only the larger part can continue to operate. If the network splits in more parts, none of them may function. In other words: the systems become unavailable. Most practical implementations use (non-Byzantine) Paxos. Paxos relies on the integrity of devices: devices can fail, but they cannot become malicious.&lt;&#x2F;p&gt;
&lt;p&gt;Coblue cannot afford to assume devices won’t become malicious. We also cannot afford
the system becoming unavailable. Thus, we need to sacrifice consistency.&lt;&#x2F;p&gt;
&lt;p&gt;We provide &lt;em&gt;strong eventual consistency&lt;&#x2F;em&gt; instead: the network propagates state changes as updates. Eventually all devices receive all updates. Two devices that have received the same unordered set of updates will be in the same state. Two devices that have reached the same state are said to have &lt;em&gt;converged&lt;&#x2F;em&gt;. The system will always be available on every device for read and write access. In practice, connected devices should always be converged. The only exception is the brief period while an update propagates through the network. Disconnected devices should converge soon after the connection re-establishes. We build strong eventually consistent systems using conflict-free replicated data types. We prefer the state-based variant, convergent replicated data types. This variant makes the weakest assumptions and offers the strongest guarantees. We further extend these with cryptographic guarantees to get to Byzantine fault tolerance.&lt;&#x2F;p&gt;
&lt;p&gt;Security guarantees in distributed systems can be classified in four categories:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Perfect guarantees: These guarantees are mathematically proven. No amount of computing power can break these guarantees. This also includes quantum computers. An example is Shamir&#x27;s secret sharing scheme: Insufficient shares reveal nothing about the secret.&lt;&#x2F;li&gt;
&lt;li&gt;Cryptographic guarantees: Breaking this security guarantee requires breaking a code. It requires solving a mathematical problem considered out of reach for the foreseeable future. Elliptic curve cryptography is an example. The public key is a derived from the private key. The reverse requires solving the elliptic curve discrete logarithm problem.&lt;&#x2F;li&gt;
&lt;li&gt;Protocol guarantees: Breaking these guarantees requires illegal behaviour to be accepted by other peers. Write permissions are an example: A write operation signed by an unauthorized user will not be accepted by the other peers in the network.&lt;&#x2F;li&gt;
&lt;li&gt;Weak guarantees: Breaking these guarantees requires illegal behaviour. Enforcing requires cooperation. An altered malicious device might not cooperate. Revocation of read permission is an example: A malicious devices can make a copy of all data accessed while having read access. It will then keep the illegal copy after read access is revoked.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Sources&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;L. Peter Deutsch (1991). &lt;em&gt;&quot;The &#x27;8 Fallacies of Networking&#x27;&quot;&lt;&#x2F;em&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blogs.oracle.com&#x2F;jag&#x2F;resource&#x2F;Fallacies.html&quot;&gt;https:&#x2F;&#x2F;blogs.oracle.com&#x2F;jag&#x2F;resource&#x2F;Fallacies.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Dr. Eric A. Brewer (2000). &lt;em&gt;&quot;Towards Robust Distributed Systems&quot;&lt;&#x2F;em&gt;. Keynote presentation. Symposium on Principles of Distributed Computing (PoDC). &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cs.berkeley.edu&#x2F;~brewer&#x2F;cs262b-2004&#x2F;PODC-keynote.pdf&quot;&gt;http:&#x2F;&#x2F;www.cs.berkeley.edu&#x2F;~brewer&#x2F;cs262b-2004&#x2F;PODC-keynote.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Werner Vogels (2009). &lt;em&gt;&quot;Eventually consistent&quot;&lt;&#x2F;em&gt;. Communications of the ACM 52: 40. doi:10.1145&#x2F;1435417.1435432. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dx.doi.org&#x2F;10.1145%2F1466443.1466448&quot;&gt;https:&#x2F;&#x2F;dx.doi.org&#x2F;10.1145%2F1466443.1466448&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Marc Shapiro, Nuno Preguiça, Carlos Baquero, Marek Zawirski (2011), &lt;em&gt;&quot;Conflict-Free Replicated Data Types&quot;&lt;&#x2F;em&gt;. Lecture Notes in Computer Science 6976 (Proc 13th International Symposium, SSS 2011), Grenoble, France: Springer Berlin Heidelberg, pp. 386–400, doi:10.1007&#x2F;978-3-642-24550-3_29, ISBN 978-3-642-24549-7 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hal.inria.fr&#x2F;file&#x2F;index&#x2F;docid&#x2F;617341&#x2F;filename&#x2F;RR-7687.pdf&quot;&gt;https:&#x2F;&#x2F;hal.inria.fr&#x2F;file&#x2F;index&#x2F;docid&#x2F;617341&#x2F;filename&#x2F;RR-7687.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;cipher-suite&quot;&gt;Cipher Suite&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;“Cryptography is not broken, it is circumvented”
— Adi Shamir (Weizmann Institute, co-inventor RSA and differential cryptanalysis)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Simplicity is an important goal in our cryptography. Cryptography developed in the past two decades has no significant known weaknesses (as the Snowden revelations support). Instead, weaknesses in the implementation break security. The complexity of standards such as SSL&#x2F;TLS facilitates this. We have carefully evaluated and selected one suite of algorithms and key lengths. Since the algorithms are known in advance, no negotiation is necessary. Should it be required to change algorithms, a new system will be deployed. Data can be migrated from the old system to the new system.&lt;&#x2F;p&gt;
&lt;p&gt;The essential cryptographic algorithms we use are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Keccak-f₁₆₀₀&lt;&#x2F;em&gt; for all symmetric cryptography&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Ed448&lt;&#x2F;em&gt; for all asymmetric cryptography&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The algorithms have no known weaknesses. They have relatively simple specifications without unexplained constants. A concise specification is included in the appendix. The algorithms all run in constant time and have fixed memory access patterns. This makes them immune to a variety of side-channel attacks. The implementation is simple, readable and high-performance, both in software and in hardware: we use well-known public domain implementations. The implementations have 270 and 1046 lines of code and we audited the implementations. Wrapping classes expose only high-level functionality and enforce &#x27;sane&#x27; usage. All together the end-to-end network encryption amounts to 2,909 lines of code. In comparison: the OpenSSL TLS implementation has 437,157 lines of code. The low code complexity makes the implementations less error prune and easier to audit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-not-aes-gcm&quot;&gt;Why not AES-GCM&lt;&#x2F;h3&gt;
&lt;p&gt;We use authenticated encryption with associated data. Daemen and Rijmen created AES almost two decades ago. Back then encryption and authentication where considered separate operations. The cryptographic community has since found this to be error-prone. Authenticated encryption integrates both in one operation. McGrew and Viega retrofitted AES with the GCM construction to give it authenticated encryption. Currently AES-GCM is a popular algorithm. In fact, modern desktop processors have AES-NI instructions to enhance its performance. But, it has problems:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;AES-GCM has the following problems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;In the case of nonce reuse both integrity and confidentiality properties are violated. If the same nonce is used twice, an adversary can create forged ciphertexts easily.&lt;&#x2F;li&gt;
&lt;li&gt;When short tags are used, it is rather easy to produce message forgeries. For instance, if the tag is 32 bits, then after 2¹⁶ forgery attempts and 2¹⁶ encryptions of chosen plaintexts (also of length 2¹⁶), a forged ciphertext can be produced. Creation of forgeries can be instantaneous when enough forgeries have been found.&lt;&#x2F;li&gt;
&lt;li&gt;GCM security proof has a flaw. It has been repaired recently, but the new security bounds are far worse for nonces not 12 bytes long;&lt;&#x2F;li&gt;
&lt;li&gt;GCM implementations are vulnerable to timing attacks if they do not use special AES instructions. The vulnerability remains even if the AES itself is implemented in constant-time. Constant-time implementations of GCM exist, but they are rather slow.&lt;&#x2F;li&gt;
&lt;li&gt;GCM restricts the message length to 68 GBytes, which might be undesirable in the future. The total amount of data allowed to encrypt on a single key is limited by 2⁶⁴ blocks, but this number decreases if long nonces are allowed.&lt;&#x2F;li&gt;
&lt;li&gt;Reasonably fast implementations of GCM require specific lookup tables, which do not fit into fast memory (L1 cache or similar) on some architectures.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;— Dmitry Khovratovich (University of Luxembourg, Microsoft Research)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;AES, like GCM, is also vulnerable to side-channel attacks. In 2005, Osvik, Shamir and Tromer demonstrated a cache-timing attack. They obtained an AES key after only 800 encryptions, totaling 65 milliseconds. In 2010 Bangerter, Gullasch and Krenn extended this. They recovered AES keys without the need for either cipher text or plaintext. Their approach works on real-life implementations such as OpenSSL. The cryptographic community is looking for a successor with the CAESAR competition. The committee has of over 20 leading cryptographic experts, including the original creators of AES.&lt;&#x2F;p&gt;
&lt;p&gt;Keyak is Keccak-f₁₆₀₀ employed as an authenticated encryption algorithm. Keccak-f₁₆₀₀ has received extensive analysis as the winner of the SHA-3 competition. The use as an authenticated encryption algorithm has a mathematical proof of safety. Keyak is a prominent contender in the CAESAR competition. It has received extensive review by the cryptographic community itself.&lt;&#x2F;p&gt;
&lt;p&gt;Like Keccak and our other algorithms, Keyak has no sensitive branches or lookups. This makes it resilient to the side-channel attacks. Described above are side-channel attacks for AES. The authentication tags do not have the weaknesses of GCM described above. The algorithm and implementation are also less complex. This prevents errors and facilitates audits. Moreover, all symmetric algorithms share the same core, the Keccak-f₁₆₀₀ function.&lt;&#x2F;p&gt;
&lt;p&gt;Besides increased security and reduced complexity, Keyak also offer increased throughput. Performance is in clock cycles per byte of data, lower is faster:&lt;&#x2F;p&gt;
&lt;p&gt;Architecture        AES-GCM   Keyak&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;x86-64 with AES-NI        4       9
x86-64                   11       9
ARM Cortex A8            51      16
FPGA                      1    0.08&lt;&#x2F;p&gt;
&lt;p&gt;On smartphones and embedded systems Keyak outperforms AES-GCM. It is on these systems that performance is the most critical because of the scarcity of resources on these devices. On x86-64 systems the cryptography overhead is usually negligible. There the trade-off is best made in favour of security.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;: The AES-GCM FPGA implementation takes 3781 ALUTs (on Cyclone-IV). A crypto-processor would also require a hashing algorithm. Adding SHA-256 takes another 2416 ALUTs (on Cyclone-III), making the total 6197. The Keccak-f₁₆₀₀ implementation takes 4574 ALUTs (on Artix-7). It provides hashing, authenticated encryption and other symmetric cryptography.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Sources&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Dag Arne Osvik; Adi Shamir; Eran Tromer (2005). &lt;em&gt;&quot;Cache Attacks and Countermeasures: the Case of AES&quot;&lt;&#x2F;em&gt;. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.wisdom.weizmann.ac.il&#x2F;~tromer&#x2F;papers&#x2F;cache.pdf&quot;&gt;http:&#x2F;&#x2F;www.wisdom.weizmann.ac.il&#x2F;~tromer&#x2F;papers&#x2F;cache.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Endre Bangerter; David Gullasch &amp;amp; Stephan Krenn (2010). &lt;em&gt;&quot;Cache Games – Bringing Access-Based Cache Attacks on AES to Practice&quot;&lt;&#x2F;em&gt; &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eprint.iacr.org&#x2F;2010&#x2F;594.pdf&quot;&gt;http:&#x2F;&#x2F;eprint.iacr.org&#x2F;2010&#x2F;594.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Babbage et al (2014). &lt;em&gt;&quot;Competition for Authenticated Encryption: Security, Applicability, and Robustness&quot;&lt;&#x2F;em&gt; CAESAR &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;competitions.cr.yp.to&#x2F;caesar-committee.html&quot;&gt;http:&#x2F;&#x2F;competitions.cr.yp.to&#x2F;caesar-committee.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Ted Krovetz, Phillip Rogaway  (2011). &lt;em&gt;&quot;The Software Performance of Authenticated-Encryption Modes&quot;&lt;&#x2F;em&gt;. Fast Software Encryption, Lecture Notes in Computer Science Volume 6733, 2011, pp 306-327  &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;web.cs.ucdavis.edu&#x2F;~rogaway&#x2F;papers&#x2F;ae.pdf&quot;&gt;http:&#x2F;&#x2F;web.cs.ucdavis.edu&#x2F;~rogaway&#x2F;papers&#x2F;ae.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;CAST Inc. (2014). &lt;em&gt;&quot;Altera GCM-AES Authenticated Encryption &#x2F; Decryption Megafunction&quot;&lt;&#x2F;em&gt;. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cast-inc.com&#x2F;ip-cores&#x2F;encryption&#x2F;aes-gcm&#x2F;cast_aes-gcm-a.pdf&quot;&gt;http:&#x2F;&#x2F;www.cast-inc.com&#x2F;ip-cores&#x2F;encryption&#x2F;aes-gcm&#x2F;cast_aes-gcm-a.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;ECRYPT (2014). &lt;em&gt;&quot;eBACS: ECRYPT Benchmarking of Cryptographic Systems&quot;&lt;&#x2F;em&gt;. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;bench.cr.yp.to&#x2F;results-hash.html&quot;&gt;http:&#x2F;&#x2F;bench.cr.yp.to&#x2F;results-hash.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;CAST Inc. (2014). &lt;em&gt;&quot;Altera SHA-256 Secure Hash Function Megafunction&quot;&lt;&#x2F;em&gt; &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cast-inc.com&#x2F;ip-cores&#x2F;encryption&#x2F;sha-256&#x2F;cast_sha256-a.pdf&quot;&gt;http:&#x2F;&#x2F;www.cast-inc.com&#x2F;ip-cores&#x2F;encryption&#x2F;sha-256&#x2F;cast_sha256-a.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Markku-Juhani O. Saarinen (2014). &lt;em&gt;&quot;Simple AEAD Hardware Interface (SÆHI) in a SoC: Implementing an On-Chip Keyak&#x2F;WhirlBob Coprocessor&quot;&lt;&#x2F;em&gt;. TrustED 2014, 03 November 2014, Scottsdale AZ US. ACM. DOI: 10.1145&#x2F;2666141.2666144 &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;575.pdf&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;575.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;key-strength&quot;&gt;Key strength&lt;&#x2F;h3&gt;
&lt;p&gt;Our implementations have key strengths with fixed values. This lowers complexity and prevents accidental or malicious changes to key strengths. We made a trade-off between realistic multi-decade security, algorithm availability, complexity and performance. We chose the following keys strengths:&lt;&#x2F;p&gt;
&lt;p&gt;Operation                algorithm  strength&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Hash                     Keccak     512 bits capacity
Symmetric encryption     Keyak      256 bits key
Diffie-Hellman           Ed448      448 bits key
Digital signatures       Ed448      448 bits key&lt;&#x2F;p&gt;
&lt;p&gt;Key strength evaluation models express the strength of cryptographic keys in terms of years it can secure information. These take double or triple Moore&#x27;s laws into consideration. This accounts for combined advances in algorithms processors. Using common evaluation standards we get:&lt;&#x2F;p&gt;
&lt;p&gt;Method              hash     symmetric  elliptic curve&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Lenstra        year 2282     year 2282       year 2233
IETF                   —     year 2245       year 2209
ECRYPT II    &amp;gt; year 2041   &amp;gt; year 2041     &amp;gt; year 2041
NIST        ≫ year 2030  ≫ year 2030    ≫ year 2030
ANSSI        &amp;gt; year 2030   &amp;gt; year 2030     &amp;gt; year 2030
BSI          &amp;gt; year 2021   &amp;gt; year 2021     &amp;gt; year 2021
NSA           top secret    top secret      top secret&lt;&#x2F;p&gt;
&lt;p&gt;Our key strengths are beyond the upper bounds of the evaluation models. Thus breaking the cryptography is infeasible for the foreseeable future, with a wide security margin. Remaining risks are mathematical breakthroughs and powerful quantum computers. Save for a very unlikely radical breakthrough, mathematical breakthroughs and advances in quantum computing slowly eat away the security margin. When the margin is insufficient the cryptography will be upgraded. During such an upgrade a parallel upgraded system will be deployed and data migrated to the new system.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Sources&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Dmitry Khovratovich (2014). &lt;em&gt;&quot;Discussion: AES-GCM Disadvantage&quot;&lt;&#x2F;em&gt;. On StackExchange Cryptography. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crypto.stackexchange.com&#x2F;questions&#x2F;18420&#x2F;aes-gcm-disadvantage&quot;&gt;https:&#x2F;&#x2F;crypto.stackexchange.com&#x2F;questions&#x2F;18420&#x2F;aes-gcm-disadvantage&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Arjen K. Lenstra (2004). &lt;em&gt;&quot;Key Lengths&quot;&lt;&#x2F;em&gt;. The Handbook of Information Security, 06&#x2F;2004. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;infoscience.epfl.ch&#x2F;record&#x2F;164539&#x2F;files&#x2F;NPDF-32.pdf&quot;&gt;http:&#x2F;&#x2F;infoscience.epfl.ch&#x2F;record&#x2F;164539&#x2F;files&#x2F;NPDF-32.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;&quot;Yearly Report on Algorithms and Keysizes&quot;&lt;&#x2F;em&gt; (2012), D.SPA.20 Rev. 1.0, ICT-2007-216676 European Network of Excellence in Cryptology (ECRYPT II), 09&#x2F;2012. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ecrypt.eu.org&#x2F;ecrypt2&#x2F;documents&#x2F;D.SPA.20.pdf&quot;&gt;http:&#x2F;&#x2F;www.ecrypt.eu.org&#x2F;ecrypt2&#x2F;documents&#x2F;D.SPA.20.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;NIST (2012). &lt;em&gt;&quot;Recommendation for Key Management&quot;&lt;&#x2F;em&gt;, Special Publication 800-57 Part 1 Rev. 3, National Institute of Standards and Technology (NIST), 07&#x2F;2012. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;groups&#x2F;ST&#x2F;toolkit&#x2F;key_management.html&quot;&gt;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;groups&#x2F;ST&#x2F;toolkit&#x2F;key_management.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;ANSSI (2014). &lt;em&gt;&quot;Mécanismes cryptographiques - Règles et recommandations&quot;&lt;&#x2F;em&gt;, Rev. 2.03, Agence Nationale de la Sécurité des Systèmes d&#x27;Information (ANSSI) , 02&#x2F;2014.
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ssi.gouv.fr&#x2F;uploads&#x2F;2015&#x2F;01&#x2F;RGS_v-2-0_B1.pdf&quot;&gt;http:&#x2F;&#x2F;www.ssi.gouv.fr&#x2F;uploads&#x2F;2015&#x2F;01&#x2F;RGS_v-2-0_B1.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;NSA (2014). &lt;em&gt;&quot;Fact Sheet Suite B Cryptography&quot;&lt;&#x2F;em&gt;, National Security Agency (NSA), 09&#x2F;2014.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.nsa.gov&#x2F;ia&#x2F;programs&#x2F;suiteb_cryptography&#x2F;index.shtml&quot;&gt;https:&#x2F;&#x2F;www.nsa.gov&#x2F;ia&#x2F;programs&#x2F;suiteb_cryptography&#x2F;index.shtml&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;IETF (2004). &lt;em&gt;&quot;Determining Strengths for Public Keys Used for Exchanging Symmetric Keys&quot;&lt;&#x2F;em&gt;, Internet Engineering Task Force (IETF). RFC 3766, H. Orman and P. Hoffman, 04&#x2F;2004.
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc3766.txt&quot;&gt;http:&#x2F;&#x2F;www.ietf.org&#x2F;rfc&#x2F;rfc3766.txt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;BSI (2014). &lt;em&gt;&quot;Algorithms for Qualified Electronic Signatures&quot;&lt;&#x2F;em&gt;, BNetzA, Budesamt für Sicherheit in der Informationstechnik (BSI), 01&#x2F;2014 updated with BSI Draft, 10&#x2F;2014. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bundesnetzagentur.de&#x2F;SharedDocs&#x2F;Downloads&#x2F;DE&#x2F;Sachgebiete&#x2F;QES&#x2F;Veroeffentlichungen&#x2F;Algorithmen&#x2F;2014Algorithmenkatalog.pdf?__blob=publicationFile&amp;amp;v=1&quot;&gt;http:&#x2F;&#x2F;www.bundesnetzagentur.de&#x2F;SharedDocs&#x2F;Downloads&#x2F;DE&#x2F;Sachgebiete&#x2F;QES&#x2F;Veroeffentlichungen&#x2F;Algorithmen&#x2F;2014Algorithmenkatalog.pdf?__blob=publicationFile&amp;amp;v=1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;comparison-of-transport-security-protocols&quot;&gt;Comparison of transport security protocols&lt;&#x2F;h3&gt;
&lt;p&gt;End-to-end encryption is a key component in our peer-to-peer network. It allows us to establish reliable secure communication over untrusted networks. There are more approaches to securing communication over the internet. We evaluated TLS, SSH, IPSec and CurveCP using OpenSSL-1.0.1f, OpenSSH-6.7p1, StrongSwan-5.3.2 and NaCL-20110221 respectively. Both TLS and SSH have a client-server model that is not appropriate for peer-to-peer networks. None of the protocols support our full cipher suite. For evaluation we substituted AES-GCM-256, SHA256 and P384. None of the existing approaches satisfy our strict requirements, as this table will elaborate:&lt;&#x2F;p&gt;
&lt;p&gt;Feature                     Ours      TLS       SSH    IPSec  CurveCP&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Complexity (lines of code) 2,909  437,157    96,378  309,796   34,786
Handshake round trips          1        2        15        3        1
Handshake overhead (bytes)   240     2403      4485    &amp;gt; 650      872
Packet overhead (bytes)       10   29—203        33       36   64—672
Confidentiality              yes     yes¹      yes¹     yes¹      yes
Integrity                    yes     yes¹      yes¹     yes¹      yes
Authenticity                 yes  optional     yes¹     yes¹      yes
Forward secrecy              yes  optional  partial optional      yes
Safe curve                   yes       no        no       no      yes
Deniability                  yes       no        no       no       no
Identity hiding              yes       no        no       no       no
Marker free                  yes       no        no       no       no&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note ¹&lt;&#x2F;em&gt;: Users can disable it in configuration. This allows for mistakes in practice. TLS and SSH support many different algorithms, some of which are not secure. This &quot;flexibility&quot; increases code complexity and adds risk and overhead.&lt;&#x2F;p&gt;
&lt;p&gt;More aspects are important than just the standard confidentiality, integrity and authenticity guarantees. Safe curves are a set of additional mathematical requirements established by elliptic curve experts. Forward secrecy guarantees previous conversations remain confidential, even if keys get compromised. Deniability means that neither party has proof that the conversation took place. Identity hiding means an eavesdropper cannot see the identities being authenticated. Marker free protocols are indistinguishable from random noise.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;coblue-s-toolbox&quot;&gt;Coblue&#x27;s Toolbox&lt;&#x2F;h2&gt;
&lt;p&gt;The cipher suite described above implements a range of cryptographic primitives. In addition to the basic cryptography we use unique techniques that offer extra defences. We call this our toolbox. Our toolbox description starts with two non-cryptographic methods. These methods construct lines of defence for processes running on possibly compromised devices. The non-cryptographic defences are:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Defensive programming&lt;&#x2F;strong&gt;: Our applications employ an array of hardening techniques to give the user a line of defence even if his&#x2F;her device is under attack.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Executables have anti reverse engineering techniques.&lt;&#x2F;li&gt;
&lt;li&gt;Executables are statically linked.&lt;&#x2F;li&gt;
&lt;li&gt;Executables are self-contained.&lt;&#x2F;li&gt;
&lt;li&gt;Executables interact directly with the operating system.&lt;&#x2F;li&gt;
&lt;li&gt;Processes maintain their own entropy pool fed from multiple sources.&lt;&#x2F;li&gt;
&lt;li&gt;Sensitive information is locked down in inaccessible memory.&lt;&#x2F;li&gt;
&lt;li&gt;No branches or lookups based on sensitive information.&lt;&#x2F;li&gt;
&lt;li&gt;Input processors are generated from formal specification.&lt;&#x2F;li&gt;
&lt;li&gt;Design simplifications to prevent implementation errors.&lt;&#x2F;li&gt;
&lt;li&gt;Statically typed APIs that prevent mis-use of components.&lt;&#x2F;li&gt;
&lt;li&gt;Static code analysis tools.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Secure Memory&lt;&#x2F;strong&gt;: Our applications run in untrusted environments. Malicious (kernel) processes can try to extract information from our applications process. A perfect solution is only possible with trusted hardware, but there are defences. We use the following methods to store sensitive information:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Compartmentalizing sensitive information.&lt;&#x2F;li&gt;
&lt;li&gt;Locking to physical RAM (this prevents writing to disk on swap or hibernate).&lt;&#x2F;li&gt;
&lt;li&gt;Disabling page write access during reads.&lt;&#x2F;li&gt;
&lt;li&gt;Disabling all page access between operations.&lt;&#x2F;li&gt;
&lt;li&gt;Canaries detect opportunistic write access.&lt;&#x2F;li&gt;
&lt;li&gt;Guard pages block opportunistic read access.&lt;&#x2F;li&gt;
&lt;li&gt;Flush caches before and after operations (this frustrates cache-timing attacks).&lt;&#x2F;li&gt;
&lt;li&gt;Fixed time comparison operators.&lt;&#x2F;li&gt;
&lt;li&gt;In-memory encryption with multi-factor keys.&lt;&#x2F;li&gt;
&lt;li&gt;A statically typed API that separates sensitive data from other data.&lt;&#x2F;li&gt;
&lt;li&gt;Trusted hardware, if the application requires it.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;cryptographic-primitives&quot;&gt;Cryptographic primitives&lt;&#x2F;h3&gt;
&lt;p&gt;We have a full suite of well-established, cryptographic primitives. These are essential for designing secure protocols and systems. They are based on the two algorithms presented in the Cipher Suite chapter. In accordance with defensive programming, the interfaces are carefully designed to prevent mis-use.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Pseudo Random&lt;&#x2F;strong&gt;: Our cryptographically secure pseudo random generator is Keccak in SpongePRG mode. The state-recovery complexity is 2¹²⁸ assuming 2²⁰ known blocks. The differentiability complexity is 2⁷⁴ blocks. The block size is 180 bytes. &lt;em&gt;Secure memory&lt;&#x2F;em&gt; is used for the internal state.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Random&lt;&#x2F;strong&gt;: Every application instance maintains it&#x27;s own entropy pool. The pool implements Ferguson &amp;amp; Schneier&#x27;s Fortuna algorithm as improved by Dodis et al. The random generator contains an accumulator pool, a generator pool and 32 staging pools. Fortuna protects against manipulation of entropy sources. Even after a full compromise, it  guarantees a return to correct operation. Our implementation makes heavy use of &lt;em&gt;secure memory&lt;&#x2F;em&gt;. No two pools are ever unlocked at the same time. Entropy passes between pools through a short-lived segment of &lt;em&gt;secure memory&lt;&#x2F;em&gt;. The pools and generators use our &lt;em&gt;pseudo random&lt;&#x2F;em&gt; generator.&lt;&#x2F;p&gt;
&lt;p&gt;On application start up the pools are initialized with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;operating system supplied cryptography grade entropy&lt;&#x2F;li&gt;
&lt;li&gt;processor&#x27;s hardware based random number generator (RDRAND or RDSEED)&lt;&#x2F;li&gt;
&lt;li&gt;entropy stored before&lt;&#x2F;li&gt;
&lt;li&gt;screenshot of the current desktop (if supported)&lt;&#x2F;li&gt;
&lt;li&gt;processor&#x27;s tick counter (RDTSC)&lt;&#x2F;li&gt;
&lt;li&gt;process id&lt;&#x2F;li&gt;
&lt;li&gt;stack base address&lt;&#x2F;li&gt;
&lt;li&gt;heap base address&lt;&#x2F;li&gt;
&lt;li&gt;current time in milliseconds&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While running the entropy pools are replenished using:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;all the sources above&lt;&#x2F;li&gt;
&lt;li&gt;application IO-event timing (disk, network, user, OS, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;mouse coordinates, key presses, screen touches (if available)&lt;&#x2F;li&gt;
&lt;li&gt;processor internal state (adapted HAVEGE)&lt;&#x2F;li&gt;
&lt;li&gt;several processor tick measurements through collection&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Hash&lt;&#x2F;strong&gt;: The Keccak hash function is used. Keccak has a large 1600 bit interal state, of which a part is reserved as capacity. The capacity is not directly exposed to input and output. The function requires keying of every usage with a 256 bit domain separating key. Keys relevant to this document are listed in the appendix. The default configuration is a hash of 256 bit output length and 512 bit capacity. It provides 128 bit collision resistance, 256 bit (second) pre-image resistance and 256 bit resistance against any attack. Keccak is immune to length extension and padding attacks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Message Authentication&lt;&#x2F;strong&gt;: Our &lt;em&gt;hash&lt;&#x2F;em&gt; functions are already keyed and meet the requirements for message authentication. For authentication applications we generate &lt;em&gt;random&lt;&#x2F;em&gt; keys instead of fixed domain separating keys.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Key Derivation&lt;&#x2F;strong&gt;: The SCrypt key derivation algorithm is used. Older key derivation methods only need processing time. Attackers use parallel computation to brute-forces these methods. Depending on budget, they use GPUs, FPGAs or ASICs. SCrypt needs both memory &lt;em&gt;and&lt;&#x2F;em&gt; processing time. This makes it expensive to brute-force in parallel. In practice, the bottleneck is processor to memory &lt;em&gt;bandwidth&lt;&#x2F;em&gt;. This resource does not follow Moore&#x27;s law.
Keys derive from passphrases using a &lt;em&gt;random&lt;&#x2F;em&gt; 256 bit salt, 12 rounds of Keccak, &lt;span class=&quot;math math-inline&quot;&gt;2^{28} + \mathrm{random}(2^{24})&lt;&#x2F;span&gt; memory cost and &lt;span class=&quot;math math-inline&quot;&gt;2^{24} + \mathrm{random}(2^{20})&lt;&#x2F;span&gt; processor cost. This takes 256 MB of RAM and about 1.5 sec of CPU on a modern processor. Every byte is shuffled twice on average. Our implementation uses Keccak instead of PBKDF2-SHA256 + SalsaMix20&#x2F;8. This simplifies the amount of crypto-code to audit.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Symmetric Key&lt;&#x2F;strong&gt;: Keyak mode with 256 bit keys is used. We always use authenticated encryption. Nonces are 128 &lt;em&gt;random&lt;&#x2F;em&gt; bits. Tags are 128 bit. This adds (only) 32 bytes to the message.&lt;&#x2F;p&gt;
&lt;p&gt;We use the same algorithm in bidirectional streams, for example in network communication. Both directions have a 256 bit key and a 128 bit nonces. A packet’s nonce is the 64 bit sequence number combined with the initial nonce. The nonce is not transmitted. Packet tags are 64 bits. This adds 8 bytes to each packet. We follow the &lt;em&gt;NIST SP 800-38D C&lt;&#x2F;em&gt; recommendation for 64 bit tags. The recommendation limits packet size to 512 kilobytes and key usage to 2²⁶ packets. We expire keys after 2²⁶ packets or 24 hours, whichever comes first.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Signatures&lt;&#x2F;strong&gt;: The Edwards-curve Digital Signature Algorithm Ed448 is used. Nonces are deterministic and invulnerable to repeated-nonce weaknesses. The keyed &lt;em&gt;hash&lt;&#x2F;em&gt; function separates the signature domains. Public and private keys are both 448 bit in size. Signature size is 112 bytes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Shared Secrets&lt;&#x2F;strong&gt;: The Elliptic Curve Diffie-Hellman protocol Ed448 creates shared secrets. The private and public keys are 448 bit. Shared secret entropy is 446 bits. We expand&#x2F;contract secret entropy to the final secret size using a domain specific &lt;em&gt;hash&lt;&#x2F;em&gt;. Public&#x2F;private key size is 56 bytes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;advanced-cryptography&quot;&gt;Advanced cryptography&lt;&#x2F;h3&gt;
&lt;p&gt;This section will describe methods beyond basic cryptography. It allows us to fight denial-of-service attack, have key escrow without a trusted third party and authenticate users over insecure channels.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Secure Files&lt;&#x2F;strong&gt;: Files have read&#x2F;write access to arbitrary parts and are resizeable. It is infeasible to encrypt and decrypt the entire file for each access. Files are split in four kilobyte blocks. The blocks are &lt;em&gt;symmetrically&lt;&#x2F;em&gt; encrypted using a 256 bit file master key. The 64 bit block number and 64 &lt;em&gt;random&lt;&#x2F;em&gt; bits form the nonce. Tags are 128 bit. A Merkle tree interleaved between content blocks stores the tags. This increases the file size by 0.5%. The tree&#x27;s root guarantees the integrity of the entire file.&lt;&#x2F;p&gt;
&lt;p&gt;The Merkle tree makes our implementation authenticated and tamper-proof. Conventional disk encryption (TrueCrypt, BitLocker, FileVault, etc.) do not have integrity checks. In those systems, an attacker can tamper with the content. An attacker can revert changes to a specific part of a file. This is not possible in our implementation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Convergent Encryption&lt;&#x2F;strong&gt;: Based on &lt;em&gt;symmetric&lt;&#x2F;em&gt; encryption with 256 bit encryption keys the algorithm keys a &lt;em&gt;hash&lt;&#x2F;em&gt; with a 256 bit convergence key. It then derives the encryption key by hashing the plaintext. Tag size is 128 bit and there is no nonce. Nonces are not necessary since the generated keys are single-use. Adding a &lt;em&gt;random&lt;&#x2F;em&gt; nonce would remove the convergence property.&lt;&#x2F;p&gt;
&lt;p&gt;Convergent encryption identifies repeated information in a multi-agent system without revealing the information itself. Identical plaintexts result in identical ciphertexts. Yet every message has its own key which is necessary to decrypt. There are important security properties: everyone with access can see if two ciphertexts match. Possessors of the convergence key can create new ciphertexts. They can therefore also brute-force the content of existing ciphertexts. A possessor of a ciphertext and its encryption key can decrypt the message.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Proof of Work&lt;&#x2F;strong&gt;:  Coelho&#x27;s Hokkaido challenge-response protocol is the basis of our proof of work protocol. Like SCrypt in our &lt;em&gt;key derivation&lt;&#x2F;em&gt;, Hokkaido is a memory-bound algorithm. A &lt;em&gt;pseudo random&lt;&#x2F;em&gt; generator generates Hokkaido&#x27;s permutation and branch tables. Its seed is a 128 bit &lt;em&gt;random&lt;&#x2F;em&gt; bitstring. The &lt;em&gt;message authentication code&lt;&#x2F;em&gt; key is 256 &lt;em&gt;random&lt;&#x2F;em&gt; bits. The challenge issuer is regenerated every hour. Challenges have configurable difficulty and time limit for solving.&lt;&#x2F;p&gt;
&lt;p&gt;The challenge contains several problem instances. It has a timestamp and a 256 bit &lt;em&gt;message authentication code&lt;&#x2F;em&gt;. The challenge is less than 100 bytes in size. The response has the solutions and a copy of the challenge. The response is less than 132 bytes.&lt;&#x2F;p&gt;
&lt;p&gt;The algorithm requires 16 megabytes of memory. Generating and verifying challenges takes 168 steps, solving challenges requires 2²⁴ steps. Challenges expire if not solved in configured time. The issuer maintains no state for outstanding challenges.&lt;&#x2F;p&gt;
&lt;p&gt;The proof of work protocol fights off denial-of-services attacks. Attacks normally work if the attacker uses few of his own resources to consume a lot of the victim&#x27;s. Our solution reverses this proportion. Proof of work forces the attacker to consume memory and processor resources. The server only consumes a tiny amount of processor time generating challenges. The server load and request size tunes the size of the issued workload. In non-attack situation there is no overhead. The burden on honest clients scales with the sophistication of the attack.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Erasure Code&lt;&#x2F;strong&gt;: We use a Reed-Solomon code over &lt;span class=&quot;math math-inline&quot;&gt;GF(2^{16})&lt;&#x2F;span&gt;. The code supports &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-out-of-&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; schemes up to 2¹⁶ shares. (But performance is cubic in &lt;span class=&quot;math math-inline&quot;&gt;n - k&lt;&#x2F;span&gt;). Any &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; sized subset can generate more shares, this way lost shares can be recovered.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Secret Sharing&lt;&#x2F;strong&gt;: We use Shamir&#x27;s Secret Sharing Scheme over &lt;span class=&quot;math math-inline&quot;&gt;GF(2^{16})&lt;&#x2F;span&gt;. This supports &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-out-of-&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; schemes of up to 2¹⁶ shares (with cubic complexity in &lt;span class=&quot;math math-inline&quot;&gt;n-k&lt;&#x2F;span&gt;). Payloads larger than 256 bytes are &lt;em&gt;symmetrically&lt;&#x2F;em&gt; encrypted using a &lt;em&gt;random&lt;&#x2F;em&gt; key. The &lt;em&gt;secret sharing&lt;&#x2F;em&gt; scheme then shares the key; the &lt;em&gt;erasure code&lt;&#x2F;em&gt; shares the payload. Any &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; sized subset can generate more shares.&lt;&#x2F;p&gt;
&lt;p&gt;The secret sharing protocol allows escrow of sensitive information. A group of five users can decide that any majority of three should be able to recover lost keys. The key generator distributes shares to the group using a 3-out-of-5 scheme.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Zero-Knowledge Password Proof&lt;&#x2F;strong&gt;: We use the Socialist Millionaire Protocol implemented in Ed448.&lt;&#x2F;p&gt;
&lt;p&gt;The proof protocol allows two users to interrogate each other. Questions like &quot;Where did we first meet?&quot; or &quot;What is the agreed upon password?&quot; help to authenticate. Both parties will known if they gave the same answer or not. Yet the protocol prevents a potential man-in-the-middle from learning anything. The other party participates in every guess. So an attacker is unable to brute-force the answers. This way two users sharing a common secret can authenticate, even over insecure channels.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Steganography&lt;&#x2F;strong&gt;: Our steganography formats a message as a valid bitmap image file. The encoder zero-pads the data to fit an approximately square image. It then adds a valid bitmap header. The overhead is 58 bytes plus padding&lt;&#x2F;p&gt;
&lt;p&gt;Our steganography is trivial and will not fool any targeted attack. Our applications use it to establish encrypted communication channels that appear unencrypted. Sometimes proxies, firewalls and other men-in-the-middle block encrypted connections. With steganography we can  still build end-to-end encryption connections.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Pronouncable Entropy&lt;&#x2F;strong&gt;: We try to avoid presenting key material to the user where possible. For humans, cryptographic keys are hard to compare and  remember. &lt;em&gt;Pronouncable entropy&lt;&#x2F;em&gt; mimics human language to present cryptographic information in a memorable form. It stores up to 100 bits of entropy in a phrase as &quot;michmeckrojef in beony&quot;. Compare this with 100 bits in base64: &lt;code&gt;bHlN va&#x2F;T sfEf z5C9 dw==&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Passphrase Entropy Estimation&lt;&#x2F;strong&gt;: We try to avoid the use of passphrases where possible. When users do set a passphrase, the quality of their passphrases is estimated. An &lt;em&gt;n&lt;&#x2F;em&gt;-gram model estimates the predictability of the password, expressed in bits of entropy. We trained the model with ten million passwords and equally many names and titles. It models the brute-force complexity of an attacker with this information.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;network-communication&quot;&gt;Network communication&lt;&#x2F;h3&gt;
&lt;p&gt;Coblue&#x27;s networking stack constructs resilient end-to-end secure channels in hostile environments. The communication overhead is minimal (only ten bytes per packet). The stack establishes secure connections wherever simple web-browsing is possible. They are also possible in an offline local area network. The network is peer-to-peer and requires no central coordination. Applications can create centralized services if needed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Socket&lt;&#x2F;strong&gt;: The connection is agnostic over the transport protocol used. We support bidirectional transports as bad as 10% success rate and 10 second latency. Transports are not required to deliver in order.&lt;&#x2F;p&gt;
&lt;p&gt;In a peer-to-peer network there is no distinction between clients and servers. Yet, every communication has an initiating side and a listening side. To the network, listening is the same as being a server. Direct connections between two peers behind NAT routers and firewalls are not always possible. We establish connections using three methods. First, we try different transports. Second, we use NAT and proxy traversal. Finally, we route the traffic over any accessible routing peer. If necessary, we disguise encrypted traffic as normal HTTP traffic.&lt;&#x2F;p&gt;
&lt;p&gt;Currently implemented transports are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Standard TCP&#x2F;IP.&lt;&#x2F;li&gt;
&lt;li&gt;Standard UDP&#x2F;IP. We distinguish transport channels by host&#x2F;port. The transport is unreliable, but the &lt;em&gt;connection&lt;&#x2F;em&gt; takes care of this.&lt;&#x2F;li&gt;
&lt;li&gt;Plain HTTP or HTTPS. We ignore certificates since the &lt;em&gt;connection&lt;&#x2F;em&gt; guarantees security. A peer accepts incoming HTTP connections if enabled in configuration. It can run its own webserver or export a FastCGI interface. We disguise traffic as normal web traffic. Packets are &lt;em&gt;steganographically&lt;&#x2F;em&gt; hidden in images and sent and received over POST requests. The URL is &lt;em&gt;randomized&lt;&#x2F;em&gt; to prevent caching. The server delays responses until a packet is available (or timed out). The client makes sure there is always an outstanding request. This creates a low latency bi-directional connection that can traverse firewalls and proxy servers.&lt;&#x2F;li&gt;
&lt;li&gt;Routed connections. If a direct connection is impossible, an indirect connections is set up. The peer uses peer discovery to find publicly accessible routing peers it can connect to. It then advertises its reachability through these peers. The routing peers will forward traffic. Note that this happens below the &lt;em&gt;connection&lt;&#x2F;em&gt; layer. The router cannot inspect the connection and is not a man-in-the-middle. The worst it can do is bandwidth throttling or denying the connection, like any internet router can do.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The transports and listening ports are all optional and configurable. The least to connect is an outgoing HTTP connection. Proxy servers are no problem. This corresponds with what users consider &#x27;an internet connection&#x27;. In case no internet connection is available, local area peer-to-peer connections are still available. When multiple transports are available between two peers they select the best one. The peers try the different transports using an exponential back-off algorithm.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Connection&lt;&#x2F;strong&gt;: A connection takes a &lt;em&gt;socket&lt;&#x2F;em&gt; and uses cryptography to turn it into a secure connection. The connection is reliable, end-to-end encrypted and authenticated. Authentication is between the peer public keys. When a &lt;em&gt;socket&lt;&#x2F;em&gt; establishes a transport both peers engage in a triple Diffie-Hellman handshake. For an initiator with authentication key &lt;span class=&quot;math math-inline&quot;&gt;(i, I)&lt;&#x2F;span&gt; and responder with authentication key &lt;span class=&quot;math math-inline&quot;&gt;(r, R)&lt;&#x2F;span&gt; this goes as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The initiator generates an ephemeral key pair &lt;span class=&quot;math math-inline&quot;&gt;(a, A)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The initiator sends the public key &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt; to the responder.&lt;&#x2F;li&gt;
&lt;li&gt;The responder generates an ephemeral key pair &lt;span class=&quot;math math-inline&quot;&gt;(b, B)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The responder computes the shared secret key &lt;span class=&quot;math math-inline&quot;&gt;K₁ = b A&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The responder computes the shared secret key &lt;span class=&quot;math math-inline&quot;&gt;K₂ = K₁ ‖ r A&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The responder sends &lt;span class=&quot;math math-inline&quot;&gt;B ‖ \text{Encrypt}[K₁](R) ‖ \text{Encrypt}[K₂](\text{message})&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The initiator computes the shared secret key &lt;span class=&quot;math math-inline&quot;&gt;K₁ = a B&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The initiator computes the shared secret key &lt;span class=&quot;math math-inline&quot;&gt;K₂ = K₁ ‖ a R&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The initiator computes the shared secret key &lt;span class=&quot;math math-inline&quot;&gt;K₃ = K₂ ‖ i B&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The initiator sends &lt;span class=&quot;math math-inline&quot;&gt;\text{Encrypt}[K₂](I) ‖ \text{Encrypt}[K₃](\text{message})&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The responder computes the shared secret key &lt;span class=&quot;math math-inline&quot;&gt;K₃ = K₂ ‖ b I&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Both set up a bidirectional stream using &lt;span class=&quot;math math-inline&quot;&gt;K₃ ‖ A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;K₃ ‖ B&lt;&#x2F;span&gt; as keys.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In step six, the responder has not yet authenticated the initiator. The message can therefore only contain information it would share with anyone. In practice we leave this message empty and only send the tag. In step twelve the keys and nonces of the bidirectional stream are derived from &lt;span class=&quot;math math-inline&quot;&gt;K₃&lt;&#x2F;span&gt;. In the direction from initiator to responder &lt;span class=&quot;math math-inline&quot;&gt;K₃ ‖ A&lt;&#x2F;span&gt; is used and in the reverse direction &lt;span class=&quot;math math-inline&quot;&gt;K₃ ‖ B&lt;&#x2F;span&gt; is used. Each packet contains the lower 16 bits of the package sequence number. The receiver uses a 1024 packet window for out-of-order packets. Together with the tag, the total communication overhead is 10 bytes per packet. Connections have a heartbeat to sense if the connection is still alive.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Peer Info&lt;&#x2F;strong&gt;: Peers can announce themselves using a peer info object. The &lt;em&gt;object&lt;&#x2F;em&gt; contains the peer public key, the addresses the peer is reachable on, a timestamp and a &lt;em&gt;signature&lt;&#x2F;em&gt;. The signature authenticates the peer info to the peer public key. The peer private keys are stored in a key vault. The peer key pairs are not security critical. Should an application depend on it, tamper resistant hardware can store the key for enhanced security.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Peer Discovery&lt;&#x2F;strong&gt;: The peer-to-peer network self-assembles by discovering other peers. This comes down to collecting &lt;em&gt;peer infos&lt;&#x2F;em&gt;. The implemented optional methods are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bundling: The software includes &lt;em&gt;peer info&lt;&#x2F;em&gt; objects.&lt;&#x2F;li&gt;
&lt;li&gt;UDP Broadcasting: the peer probes the local area network.&lt;&#x2F;li&gt;
&lt;li&gt;Peer exchange: connected peers exchange known &lt;em&gt;peer info&lt;&#x2F;em&gt; objects.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Services&lt;&#x2F;strong&gt;: Application level services have their API specified in a formal language. A &lt;em&gt;hash&lt;&#x2F;em&gt; of the formal specification identifies the services. The network stack handles service discovery, serialization and message passing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;storage&quot;&gt;Storage&lt;&#x2F;h3&gt;
&lt;p&gt;Input&#x2F;output routines and storage are a process&#x27; interface to the world. This is also where the strongest defences need to be. Since this code is so critical to get correct, we decided not to write it at all. Instead we generate our I&#x2F;O procedures from formal specifications.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Objects&lt;&#x2F;strong&gt;: We specify information containing structures in a domain specific formal language. Tooling generates most of the data handling code from the formal specification. This includes all binary encoding&#x2F;decoding code.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Bix&lt;&#x2F;strong&gt;: We serialize &lt;em&gt;objects&lt;&#x2F;em&gt; using a bix, our binary format. The format is a dense and high-performance serialization. It is like Google Protocol Buffers or Apache Thrift. Our format is unique in three ways:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It can encode cyclical data structures.&lt;&#x2F;li&gt;
&lt;li&gt;It is one-to-one. An object always has one unique valid encoding.&lt;&#x2F;li&gt;
&lt;li&gt;Encoded objects include a 128 bit &lt;em&gt;hash&lt;&#x2F;em&gt; of the formal specification for versioning.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Content Addressed Store&lt;&#x2F;strong&gt;: A key-value store where the key is a 256 bit &lt;em&gt;hash&lt;&#x2F;em&gt; of the serialized value. This allows the calling side to confirm the correct behaviour of the store. The store is a primitive in Byzantine systems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;case-study-storro-key-management&quot;&gt;Case Study: Storro Key Management&lt;&#x2F;h2&gt;
&lt;p&gt;Storro allows users to collaborate on projects. It creates an encrypted drive on the users’ devices. The drive contains a folder for each project the user has joined. Changes made to the folder distribute to the project&#x27;s other users. Every device independently validates correct operation. Storro resolves any conflicting changes without user interaction. A revision history logs all changes. All historical versions are retrievable. The integrity is cryptographically guaranteed.&lt;&#x2F;p&gt;
&lt;p&gt;A user can be in one of five different roles in a project. In monotonically increasing order of privilege they are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Outsider&lt;&#x2F;em&gt;: The user is not in any way part of the project.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Facilitator&lt;&#x2F;em&gt;: The user provides backup and hosting. Other than that, there is
no read access. The user is not able to learn anything about the
contents of the project: not even a list of files.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Observer&lt;&#x2F;em&gt;: The user has full read-only access to the project. The user is a
passive observer and not able to make any changes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Participant&lt;&#x2F;em&gt;: The user participates in the project. The user has full write
access to the project folder. He&#x2F;she is able to create, change and remove all
files and folders.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Administrator&lt;&#x2F;em&gt;: The user administrates the project. Like a participant, he&#x2F;she
has read&#x2F;write access. Administrators can also change the project metadata.
This includes adding or removing users and changing their roles. (With one
exception: the last administrator cannot remove him&#x2F;her self.)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Storro enforces non-mutable privileges by controlling access to read-keys. It forces mutating privileges by having every participant confirm the correctness of the mutation. Storro limits storage of encrypted information to a set of allowed devices.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;license-management&quot;&gt;License Management&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LicenseCertificate:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	user: User public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	device: Device public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	kind: enum of Server Desktop Laptop Smartphone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	validity: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature: Signature by a license authority&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LicenseService:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	refreshLicense: ∅ → LicenseCertificate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A device maintains an up-to-date &lt;code&gt;LicenseCertificate&lt;&#x2F;code&gt; object. It periodically requests a new &lt;code&gt;LicenseCertificate&lt;&#x2F;code&gt; object from a license authority. The license authority&#x27;s signature validates the license. Storro has a fixed set of license authorities, compiled into the executable. Initial authentication uses the socialist millionaire protocol on the license key. Later authentications can also use user&#x2F;device keys.&lt;&#x2F;p&gt;
&lt;p&gt;The full version of the licensing protocol exchanges more details about the licensee. Storro only shares these details between the licensee and the license authority. The authority can hand out &lt;code&gt;LicenseCertificate&lt;&#x2F;code&gt; objects with longer or shorter validity. The validity forces peers to come online and refresh the license. The validity is a trade-off between offline functionality and revoking licenses.&lt;&#x2F;p&gt;
&lt;p&gt;Storro peers will request a valid &lt;code&gt;LicenseCertificate&lt;&#x2F;code&gt; object before they interact. An expired license will lock a user&#x2F;device out of the network. The user can continue to work locally. A renewed license reconnects the user. Storro then integrates the local and remote changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;distributed-content-addressed-store&quot;&gt;Distributed Content Addressed Store&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;StoreCertificate:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	projectUuid: Uuid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	users: set of public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	admins: set of public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	timestamp: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature: signature by an admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;StoreService:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	exchangeCertificate: set of StoreCertificate → set of StoreCertificate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	get: (Uuid, Hash) → (Uuid, Value)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	put: (Uuid, Value) → ∅&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	sync: Binary → Binary&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Storro stores all the projects&#x27; state in a content addressed stores. The stores synchronize between all users that are at least facilitator in the project. Facilitators cannot decrypt anything in the store. The facilitators know who to synchronize with and who administrates the project. Storro maintains an up to date &lt;code&gt;StoreCertificate&lt;&#x2F;code&gt; object for every project. This object contains the list of devices that can access it. It also contains a list of administrators that can update the &lt;code&gt;StoreCertificate&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Exchange Certificate&lt;&#x2F;strong&gt;: When two Storro peers connect, they check which projects the other peer has access to. They then exchange the latest &lt;code&gt;StoreCertificate&lt;&#x2F;code&gt;s for those projects. For every certificate received, the peer verifies and updates. Only &lt;code&gt;StoreCertificate&lt;&#x2F;code&gt;s signed by administrators are accepted. The timestamp guarantees that the latest certificates eventually reach every peer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Get, Put and Sync&lt;&#x2F;strong&gt;: The store has the conventional &lt;code&gt;get&lt;&#x2F;code&gt; and &lt;code&gt;put&lt;&#x2F;code&gt; calls. Get retrieves a value based on its hash. The requester verifies correct behaviour by verifying the hash of the returned value. The &lt;code&gt;sync&lt;&#x2F;code&gt; call uses an efficient protocol to discover missing hashes between two stores. The &lt;code&gt;put&lt;&#x2F;code&gt; call is for completeness. Every store can validate its own integrity by checking the hashes. Observers can decrypt the contents and perform full integrity checks and garbage collection.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;version-management&quot;&gt;Version Management&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VersionCertificate:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	projectUuid: Uuid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	readKey: set of encrypted keys to Version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	timestamp: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature: signature by an observer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VersionService:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	exchangeVersions: set of VersionCertificate → set of VersionCertificate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;readKey&lt;&#x2F;code&gt; contains the keys to read the latest &lt;code&gt;Version&lt;&#x2F;code&gt; object. The certificate writer encrypts them for each user with at least observer role. Storro stores the &lt;code&gt;Version&lt;&#x2F;code&gt; object and the following related objects convergently encrypted in the content addressed store:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Version:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	metadata: key to Metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	previous: set of key to Version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	root: key to Directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature: user signature&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Directory:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	entries: set of (key to File or Director)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;File:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	contents: key to binary&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The next chapter will describe the &lt;code&gt;Metadata&lt;&#x2F;code&gt; object. The specification leaves out details such as modification times and compression. Observers can create a new version and the corresponding certificate. This new version merges updates from every other version the device is aware of. Devices with observer role have one unique latest version. Facilitators have insufficient permission to create their own versions. Facilitators will store and pass along the latest versions of other users.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;Version&lt;&#x2F;code&gt; objects satisfy invariants. They are a state-based conflict-free replicated data type with strong eventual consistency. The state is monotonically increasing. This is explicitly constructed by the &lt;code&gt;previous&lt;&#x2F;code&gt; hashes. These create a causal lattice of &lt;code&gt;Version&lt;&#x2F;code&gt; objects:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The versions form a directed acyclic graph through their &lt;code&gt;previous&lt;&#x2F;code&gt; fields, the &lt;em&gt;version graph&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The version graph has a least element, the &lt;em&gt;initial version&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The hash of the initial version is the projects&#x27; &lt;em&gt;universally unique identifier&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The version graph has a greatest element, the &lt;em&gt;latest version&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Converged replicas have the same latest version.&lt;&#x2F;li&gt;
&lt;li&gt;Converged replicas have identical states.&lt;&#x2F;li&gt;
&lt;li&gt;Non-initial versions have either one parent, the &lt;em&gt;commits&lt;&#x2F;em&gt;, or more, the &lt;em&gt;merges&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The initial version has one user with the administrator role, the &lt;em&gt;founder&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The initial version is signed by the founder.&lt;&#x2F;li&gt;
&lt;li&gt;Commits differ from their previous commit in either the &lt;code&gt;metadata&lt;&#x2F;code&gt; or &lt;code&gt;root&lt;&#x2F;code&gt; field, not both. These are called &lt;em&gt;meta-commits&lt;&#x2F;em&gt; and &lt;em&gt;root-commits&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Root-commits are signed by a user that has a participant or administrator role in the previous version.&lt;&#x2F;li&gt;
&lt;li&gt;The previous versions in a merge are commits.&lt;&#x2F;li&gt;
&lt;li&gt;The previous versions in a merge are pair-wise unreachable.&lt;&#x2F;li&gt;
&lt;li&gt;Merges are a known deterministic function of their previous versions.&lt;&#x2F;li&gt;
&lt;li&gt;No two elements in a &lt;code&gt;Directory.entries&lt;&#x2F;code&gt; have the same &lt;code&gt;name&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Create Project&lt;&#x2F;strong&gt;: The founder creates an initial version that satisfies all invariants. The founder can work in the project on his device and can invite other users&#x2F;devices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Exchange Versions&lt;&#x2F;strong&gt;: Two devices start with the content addressed store synchronization. Next they exchange &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt;s for the latest versions of the project. Storro peers restrict this to versions the other device is also member of. Peers validate the certificate on receipt. Facilitators can stop here. Observers proceed to construct the &lt;code&gt;Version&lt;&#x2F;code&gt; object and verify the invariants. Peers ignore invalid data. Peers integrate new data and update their &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Add Commit&lt;&#x2F;strong&gt;: The device registers local changes to the projects’ directories. Storro peers store these changes as a commit in the &lt;code&gt;Version&lt;&#x2F;code&gt; history. They update their &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt; and distribute it to other devices. Devices validate the new &lt;code&gt;Version&lt;&#x2F;code&gt; on receipt. Storro rejects illegal &lt;code&gt;Version&lt;&#x2F;code&gt;s. Illegal changes will not propagate the network beyond the malicious device(s).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;user-management&quot;&gt;User Management&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Invitation:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	projectUuid:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name: String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	readKey: key to Version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	voucher: private key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	expiry: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Storro devices store the following three types of information in the content addressed store using convergent encryption:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Metadata:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	description: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	users: set of Credentials&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	vouchers: set of Voucher&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Credentials:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	user: user public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	role: enum of Facilitator Observer Participant Administrator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Voucher:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	key: public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	role: enum of Facilitator Observer Participant Administrator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	expiry: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;Metadata&lt;&#x2F;code&gt; has extra invariants:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A meta-commit is signed by an administrator, a regular user or a voucher.&lt;&#x2F;li&gt;
&lt;li&gt;A regular user signed commit only affects that user and does not increase the maximal role of that user.&lt;&#x2F;li&gt;
&lt;li&gt;A voucher signed commit removes that voucher and can add one user with the role specified in the voucher.&lt;&#x2F;li&gt;
&lt;li&gt;Meta-commits have no vouchers with expiry dates before the signature date.&lt;&#x2F;li&gt;
&lt;li&gt;There is at least one administrator.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Invite User&lt;&#x2F;strong&gt;: An admin can invite a user by adding the user&#x2F;device keys to the credentials. The admin then distributes the updated &lt;code&gt;StoreCertificate&lt;&#x2F;code&gt; and &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt;. When the user&#x2F;device connects to an updated peer it can retrieve the latest version. The public keys of the user&#x2F;device are not always known in advance. In this case, the admin can create a voucher. The admin can then send the user&#x2F;device an &lt;code&gt;Invitation&lt;&#x2F;code&gt; by any secure channel. The voucher is a single-use right to create an account with a predetermined role. The user&#x2F;devices can accept the invitation by creating its own account. The user&#x2F;device can reject the invitation by removing the voucher. This only requires retrieving the latest &lt;code&gt;Version&lt;&#x2F;code&gt; and &lt;code&gt;Metadata&lt;&#x2F;code&gt; objects.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Remove User&lt;&#x2F;strong&gt;: The admin or user&#x2F;device creates a meta-commit that removes the user&#x2F;device from the project. The device then distributes this update.  Later &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt;s will not include a key for the user. Later requests to peers will fail for the removed user. The user&#x2F;device still receives the meta-commit containing its removal, which allows the user&#x2F;device to detect its removal. When removed, a Storro device will remove encrypted data.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-algorithms&quot;&gt;Appendix: Algorithms&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;“Il faut qu’il n’exige pas le secret, et qu’il puisse sans inconvénient tomber entre les mains de l’ennemi;”
— Auguste Kerckhoffs, &lt;em&gt;La Cryptographie Militaire&lt;&#x2F;em&gt; (1883)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Keccak&lt;&#x2F;strong&gt;: The internal state is &lt;span class=&quot;math math-inline&quot;&gt;S ∊ GF(2)^{1600}&lt;&#x2F;span&gt; also represented as &lt;span class=&quot;math math-inline&quot;&gt;A ∊ GF(2)^{5×5×64}&lt;&#x2F;span&gt; by &lt;span class=&quot;math math-inline&quot;&gt;A_{x,y,z} = S_{320x + 64y +z}&lt;&#x2F;span&gt;. The permutation for &lt;em&gt;Keccak&lt;&#x2F;em&gt; is &lt;span class=&quot;math math-inline&quot;&gt;f = R_{23}∘…∘R₀&lt;&#x2F;span&gt; and for &lt;em&gt;Keyak&lt;&#x2F;em&gt; it is &lt;span class=&quot;math math-inline&quot;&gt;f = R_{23}∘…∘R_{12}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;Rᵢ = ιᵢ∘χ∘π∘ρ∘θ&lt;&#x2F;span&gt;. The transform &lt;span class=&quot;math math-inline&quot;&gt;θ&lt;&#x2F;span&gt; is &lt;span class=&quot;math math-inline&quot;&gt;A_{x,y,z} \stackrel+= \sum_{[0,4]}^{u}( A_{x-1,u,z} + A_{x+1,u,z-1})&lt;&#x2F;span&gt;. Steps &lt;span class=&quot;math math-inline&quot;&gt;π∘ρ&lt;&#x2F;span&gt; together are &lt;span class=&quot;math math-inline&quot;&gt;A&amp;#39;_{y,2x+3y,z} = A_{x,y,z - \mathrm{R}_{x,y}}&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{R}_{x,y}&lt;&#x2F;span&gt; is computed by setting &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{R}_{0,0}=0&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{R}_{xᵢ,yᵢ}=\frac{(i+1)(i+2)}2&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;x₀=1&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;y₀=0&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;x_{i+1}=yᵢ&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;y_{i+1}=2xᵢ+3yᵢ \operatorname{mod} 5&lt;&#x2F;span&gt;. The &lt;span class=&quot;math math-inline&quot;&gt;χ&lt;&#x2F;span&gt; step is &lt;span class=&quot;math math-inline&quot;&gt;A_{x,y,z} \stackrel+= (A_{x+1,y,z} + 1)A_{x + 2,y,z}&lt;&#x2F;span&gt;. Step &lt;span class=&quot;math math-inline&quot;&gt;ιᵢ&lt;&#x2F;span&gt; is identity except &lt;span class=&quot;math math-inline&quot;&gt;A_{0,0,2^j-1} \stackrel+= (x^{j+7i} \operatorname{mod} x⁸ + x⁶ + x⁵ + x⁴ + 1) \operatorname{mod} x&lt;&#x2F;span&gt; for &lt;span class=&quot;math math-inline&quot;&gt;j ∊[0,6]&lt;&#x2F;span&gt;. The permutation is used in a sponge or duplex constructions to derive all symmetric cryptography.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Ed448&lt;&#x2F;strong&gt;: Consider the elliptic curve &lt;span class=&quot;math math-inline&quot;&gt;y² + x³ = 1 - 39081 x² + x \phantom{a} \operatorname{mod} 2^{448} - 2^{224} - 1&lt;&#x2F;span&gt; with base point &lt;span class=&quot;math math-inline&quot;&gt;G = (…, 19)&lt;&#x2F;span&gt; of prime order &lt;span class=&quot;math math-inline&quot;&gt;n = 2^{446} - 13 818 066 809 895 115 352 007 386 748 515 426 880 336 692 474 882 178 609 894 547 503 885&lt;&#x2F;span&gt;. The &lt;em&gt;private key&lt;&#x2F;em&gt; is a number &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt; chosen from &lt;span class=&quot;math math-inline&quot;&gt;\{1,…,n-1\}&lt;&#x2F;span&gt;. The &lt;em&gt;public key&lt;&#x2F;em&gt; is the point &lt;span class=&quot;math math-inline&quot;&gt;H = d G&lt;&#x2F;span&gt; encoded as a 448 bit &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;-coordinate. From two keypairs &lt;span class=&quot;math math-inline&quot;&gt;(d_A, H_A)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(d_B, H_B)&lt;&#x2F;span&gt; the Diffie-Hellman secret is calculated as: &lt;span class=&quot;math math-inline&quot;&gt;S = d_A H_B = d_A ( d_B G ) = d_B ( d_A G ) = d_B H_A&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To sign a message &lt;span class=&quot;math math-inline&quot;&gt;m ∊ \{1,…,n-1\}&lt;&#x2F;span&gt; we compute &lt;span class=&quot;math math-inline&quot;&gt;r = \mathrm{hash}(m) \phantom{a} \operatorname{mod} n&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;R = r G&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;s = r + \mathrm{hash}(m ∥ H ∥ R) d \phantom{a} \operatorname{mod} n&lt;&#x2F;span&gt;. The signature is &lt;span class=&quot;math math-inline&quot;&gt;(R,s)&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; encoded like the public key and &lt;span class=&quot;math math-inline&quot;&gt;s&lt;&#x2F;span&gt; as a 56 byte integer. To verify we check &lt;span class=&quot;math math-inline&quot;&gt;s G = R + \mathrm{hash}(m ∥ H ∥ R) H&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hokkaido&lt;&#x2F;strong&gt;: Let &lt;span class=&quot;math math-inline&quot;&gt;D=GF(2)^n&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; be a random permutation on &lt;span class=&quot;math math-inline&quot;&gt;D&lt;&#x2F;span&gt;. Let &lt;span class=&quot;math math-inline&quot;&gt;v&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;w&lt;&#x2F;span&gt; be vectors of random elements of &lt;span class=&quot;math math-inline&quot;&gt;D^l&lt;&#x2F;span&gt;. The domain parameters are &lt;span class=&quot;math math-inline&quot;&gt;(n,l,t,v,w)&lt;&#x2F;span&gt;. The challenge issuer chooses &lt;span class=&quot;math math-inline&quot;&gt;x₀∊D&lt;&#x2F;span&gt; and randomly iterates either &lt;span class=&quot;math math-inline&quot;&gt;x_{i+1} = t(xᵢ ⊕ vᵢ)&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;x_{i+1} = t(xᵢ ⊕ wᵢ)&lt;&#x2F;span&gt; while calculating a checksum &lt;span class=&quot;math math-inline&quot;&gt;c =\⊕[0…l]i \mathrm{rot}(xᵢ,i)&lt;&#x2F;span&gt;. The challenge is &lt;span class=&quot;math math-inline&quot;&gt;(x₀, c)&lt;&#x2F;span&gt;. The solver brute-forces the choices to produce a path that results in the same &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt; sqtarting from &lt;span class=&quot;math math-inline&quot;&gt;x₀&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;SCrypt&lt;&#x2F;strong&gt;: Given a salt &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt;, passphrase &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; and parameters &lt;span class=&quot;math math-inline&quot;&gt;(n, l, r)&lt;&#x2F;span&gt;. Take a random function &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{h}:GF(2)^l→GF(2)^l&lt;&#x2F;span&gt; and initialize an array of bitvectors &lt;span class=&quot;math math-inline&quot;&gt;V ∊ GF(2)^{n×l}&lt;&#x2F;span&gt; by setting &lt;span class=&quot;math math-inline&quot;&gt;V₀ = \mathrm{hash}_{l}(S ∥ P)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Vᵢ = \mathrm{h}(V_{i-1})&lt;&#x2F;span&gt;. A sequence is then started with &lt;span class=&quot;math math-inline&quot;&gt;X₀ = \mathrm{h}(V_{n-1})&lt;&#x2F;span&gt; and iterated with &lt;span class=&quot;math math-inline&quot;&gt;Xᵢ = \mathrm{h}(X_{i-1} ⊕ V_{Xᵢ \operatorname{mod} n})&lt;&#x2F;span&gt;. The resulting key &lt;span class=&quot;math math-inline&quot;&gt;K = \mathrm{hash}(P ∥ X_{r-1})&lt;&#x2F;span&gt;. In our implementation &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{h}&lt;&#x2F;span&gt; is &lt;em&gt;Keyak&lt;&#x2F;em&gt;-&lt;span class=&quot;math math-inline&quot;&gt;f&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Socialist Millionaire&lt;&#x2F;strong&gt;: Take &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; from &lt;em&gt;Ed448&lt;&#x2F;em&gt;. Alice and Bob have secrets &lt;span class=&quot;math math-inline&quot;&gt;s_A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;s_B&lt;&#x2F;span&gt; and want to verify their equality. They each generate three random numbers from &lt;span class=&quot;math math-inline&quot;&gt;\{1,…,n-1\}&lt;&#x2F;span&gt;: &lt;span class=&quot;math math-inline&quot;&gt;a₁, a₂, a₃, b₁, b₂, b₃&lt;&#x2F;span&gt;. Using Diffie-Hellman they establish  &lt;span class=&quot;math math-inline&quot;&gt;S₁ = a₁ b₁ G&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;S₂ = a₂ b₂ G&lt;&#x2F;span&gt;. They compute &lt;span class=&quot;math math-inline&quot;&gt;P_A = a₃ S₁&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;P_B = b₃ S₁&lt;&#x2F;span&gt; and communicate the result. They compute &lt;span class=&quot;math math-inline&quot;&gt;Q_A = a₃ G + s_A S₂&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q_B = b₃ G + s_B S₂&lt;&#x2F;span&gt; and communicate the result. A final Diffie-Hellman establishes &lt;span class=&quot;math math-inline&quot;&gt;S₃ = a₁ b₁ (Q_A - Q_B)&lt;&#x2F;span&gt;. Both now verify: &lt;span class=&quot;math math-inline&quot;&gt;S₃ - P_A + P_B = a₁ b₁ a₂ b₂ (s_A - s_B) G = 0&lt;&#x2F;span&gt; iff &lt;span class=&quot;math math-inline&quot;&gt;s_A = s_B&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Sources&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Niels Ferguson &amp;amp; Bruce Schneier (2003). &lt;em&gt;&quot;Practical Cryptography&quot;&lt;&#x2F;em&gt;, published by Wiley. ISBN 0-471-22357-3.&lt;&#x2F;li&gt;
&lt;li&gt;Yevgeniy Dodis, Adi Shamir, Noah Stephens-Davidowitz &amp;amp; Daniel Wichs (2014). &lt;em&gt;&quot;How to Eat Your Entropy and Have it Too -- Optimal Recovery Strategies for Compromised RNGs&quot;&lt;&#x2F;em&gt;. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;167&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;167&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A. Seznec, N. Sendrier (2005). &lt;em&gt;&quot;HAVEGE: a user-level software heuristic for generating empirically strong random numbers&quot;&lt;&#x2F;em&gt;, ACM Transaction on Modeling and Computer Simulations (TOMACS), Volume 13, Issue 4, October 2003. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.irisa.fr&#x2F;caps&#x2F;projects&#x2F;hipsor&#x2F;publications&#x2F;havege-tomacs.pdf&quot;&gt;https:&#x2F;&#x2F;www.irisa.fr&#x2F;caps&#x2F;projects&#x2F;hipsor&#x2F;publications&#x2F;havege-tomacs.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Guido Bertoni, Joan Daemen, Michaël Peeters &amp;amp; Gilles Van Assche (2011). &lt;em&gt;&quot;The Keccak reference&quot;&lt;&#x2F;em&gt; Version 3.0. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;keccak.noekeon.org&#x2F;Keccak-reference-3.0.pdf&quot;&gt;http:&#x2F;&#x2F;keccak.noekeon.org&#x2F;Keccak-reference-3.0.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Guido Bertoni, Joan Daemen, Michaël Peeters &amp;amp; Gilles Van Assche (2011).  &lt;em&gt;&quot;Cryptographic sponge functions&quot;&lt;&#x2F;em&gt; Version 0.1. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sponge.noekeon.org&#x2F;CSF-0.1.pdf&quot;&gt;http:&#x2F;&#x2F;sponge.noekeon.org&#x2F;CSF-0.1.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;NIST (2014 DRAFT). FIPS PUB 202  &lt;em&gt;&quot;SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions&quot;&lt;&#x2F;em&gt;.  &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;publications&#x2F;drafts&#x2F;fips-202&#x2F;fips_202_draft.pdf&quot;&gt;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;publications&#x2F;drafts&#x2F;fips-202&#x2F;fips_202_draft.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;NIST (2007). Special Publication 800-38D &lt;em&gt;&quot;Recommendation for Block Cipher Modes of Operation: Galois&#x2F;Counter Mode (GCM) and GMAC Appendix C: Requirements and Guidelines for Using Short Tags&quot;&lt;&#x2F;em&gt; &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;publications&#x2F;nistpubs&#x2F;800-38D&#x2F;SP-800-38D.pdf&quot;&gt;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;publications&#x2F;nistpubs&#x2F;800-38D&#x2F;SP-800-38D.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe &amp;amp; Bo-Yin Yang (2011). &lt;em&gt;“High-speed high-security signatures”&lt;&#x2F;em&gt;. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;ed25519.cr.yp.to&#x2F;ed25519-20110926.pdf&quot;&gt;http:&#x2F;&#x2F;ed25519.cr.yp.to&#x2F;ed25519-20110926.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Michael Hamburg (2015). &lt;em&gt;&quot;Ed448-Goldilocks, a new elliptic curve&quot;&lt;&#x2F;em&gt;. NIST Workshop on Elliptic Curve cryptography. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;groups&#x2F;ST&#x2F;ecc-workshop-2015&#x2F;papers&#x2F;session7-hamburg-michael.pdf&quot;&gt;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;groups&#x2F;ST&#x2F;ecc-workshop-2015&#x2F;papers&#x2F;session7-hamburg-michael.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Fabien Coelho (2005). &lt;em&gt;&quot;Exponential Memory-Bound Functions for Proof of Work Protocols&quot;&lt;&#x2F;em&gt;. Cryptology ePrint Archive, Report 2005&#x2F;356. TR Ecole des mines de Paris A&#x2F;370&#x2F;CRI. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2005&#x2F;356&quot;&gt;https:&#x2F;&#x2F;eprint.iacr.org&#x2F;2005&#x2F;356&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Colin Percival (2009). &lt;em&gt;&quot;Stronger Key Derivation via Sequential Memory-Hard Functions&quot;&lt;&#x2F;em&gt;, presented at BSDCan&#x27;09, May 2009. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.tarsnap.com&#x2F;scrypt.html&quot;&gt;https:&#x2F;&#x2F;www.tarsnap.com&#x2F;scrypt.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Fabrice Boudot, Berry Schoenmakers &amp;amp; Jacques Traoré (2011). &lt;em&gt;&quot;A Fair and Efficient Solution to the Socialist Millionaires’ Problem&quot;&lt;&#x2F;em&gt;. In Discrete Applied Mathematics, 111 (2001) 23–36. (Special issue on coding and cryptology) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.win.tue.nl&#x2F;~berry&#x2F;papers&#x2F;dam.pdf&quot;&gt;https:&#x2F;&#x2F;www.win.tue.nl&#x2F;~berry&#x2F;papers&#x2F;dam.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cointel flyer</title>
        <published>2015-08-27T00:00:00+00:00</published>
        <updated>2015-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/15/cointel-flyer/"/>
        <id>https://2π.com/15/cointel-flyer/</id>
        
        <content type="html" xml:base="https://2π.com/15/cointel-flyer/">&lt;h1 id=&quot;cointel-flyer&quot;&gt;Cointel flyer&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Still ~44 markets active. MultiSig.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Tor and I2P&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Ransom situations.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;What are Bitcoins?&lt;&#x2F;strong&gt;
Bitcoin is an online currency that can be used for payments. Bitcoin is decentralized by design, that means there is no central authority that controls the currency. Bitcoin requires no government, no central bank and no mint. The security of the currency is guaranteed by innovative use of cryptographic technology.&lt;&#x2F;p&gt;
&lt;p&gt;Since it&#x27;s introduction, more than a hundred thousand merchants started accepting Bitcoins. Among these are PayPal, Microsoft and Dell. Consumers are also using Bitcoins, in the 2014&#x27;s Black Friday sale Bitcoin was a top ten payment processors, handling three hundred million US Dollars. Investors are also seeing the potential of the Bitcoin ecosystems. Venture capital investment in Bitcoin related companies has been growing rapidly, with over two hundred million US Dollars invested in the first quarter of 2015.&lt;&#x2F;p&gt;
&lt;p&gt;There are many advantages for merchants. Credit cards charge around three percent transaction fees, where Bitcoin charges less than one percent. There is no risk of chargebacks because transactions are always final. Payment processors such as BitPay offer turnkey solutions to merchants. You sign up for a free account and place the button on your website. BitPay will handle the transaction and convert to a currency of your choosing. Transactions are handled within the hour and can be made anywhere in the world.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Criminal use of Bitcoins&lt;&#x2F;strong&gt;
The lack of regulations and control make Bitcoin particularly interesting for criminal payments. The currency has enabled the creation of online marketplaces for illegal goods like the Silk Road and its successors. Here all sorts of goods are traded:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Drugs&lt;&#x2F;li&gt;
&lt;li&gt;Imitation goods&lt;&#x2F;li&gt;
&lt;li&gt;Money laundering&lt;&#x2F;li&gt;
&lt;li&gt;Fake money and passports&lt;&#x2F;li&gt;
&lt;li&gt;Weapons and ammunition&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;and it get&#x27;s worse,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ransomware that holds your files hostage&lt;&#x2F;li&gt;
&lt;li&gt;Botnets and hacking services&lt;&#x2F;li&gt;
&lt;li&gt;Child exploitation&lt;&#x2F;li&gt;
&lt;li&gt;Kidnappings&lt;&#x2F;li&gt;
&lt;li&gt;Murder for hire&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Call for tools&lt;&#x2F;strong&gt;
Regulatory agencies are currently looking for an answer to Bitcoins. The Europeans Central Bank took the position that they would like to promote the innovation, but currently recommends against Bitcoin due to a lack of regulatory tools. Intelligence and law enforcement agency are also looking for tools to investigate cases involving Bitcoin payments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cointel-eu&quot;&gt;Cointel.eu&lt;&#x2F;h2&gt;
&lt;p&gt;The Dutch technology innovator Coblue Cybersecurity B.V. has answered the call for tools with Cointel. Launched at the Interpol World Conference in Singapore, Cointel allows investigators to track transactions through the Bitcoin system and assists in identifying the individuals behind it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wiki-leaks&quot;&gt;Wiki-Leaks&lt;&#x2F;h3&gt;
&lt;p&gt;Take for example Wiki-Leaks, an organization that has every reason to hide it&#x27;s financials doings. On their donation page, one of the options is Bitcoin:&lt;&#x2F;p&gt;
&lt;p&gt;[Screenshot donation page, Bitcoin address highlighted]&lt;&#x2F;p&gt;
&lt;p&gt;This is the main donation address.&lt;&#x2F;p&gt;
&lt;p&gt;[Screenshot donation address overview page]&lt;&#x2F;p&gt;
&lt;p&gt;We can see&lt;&#x2F;p&gt;
&lt;p&gt;[Screenshot balance graph]&lt;&#x2F;p&gt;
&lt;p&gt;[Screenshot yearly activity]&lt;&#x2F;p&gt;
&lt;p&gt;[Screenshot daily activity]&lt;&#x2F;p&gt;
&lt;p&gt;[Screenshot geo-ip]&lt;&#x2F;p&gt;
&lt;p&gt;At the top of the page, there is a link to the &lt;em&gt;entity&lt;&#x2F;em&gt;. This will take you to the following page&lt;&#x2F;p&gt;
&lt;p&gt;Now, if you look back at the donation page, you will see a little button next to the Bitcoin address. This allows you to generate a unique new address for your donation. The supposed goal of this is to make your donation untraceable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-user-1&quot;&gt;Example User 1&lt;&#x2F;h3&gt;
&lt;p&gt;[Screenshot of yearly activity]&lt;&#x2F;p&gt;
&lt;p&gt;[Screenshot of daily activity]&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-user-2&quot;&gt;Example User 2&lt;&#x2F;h3&gt;
&lt;p&gt;[Screenshot of yearly activity]&lt;&#x2F;p&gt;
&lt;p&gt;[Screenshot of daily activity]&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Deep dot web. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.deepdotweb.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.deepdotweb.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cointel investigation of ‘DD4BC’</title>
        <published>2015-08-27T00:00:00+00:00</published>
        <updated>2015-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/15/dd4bc/"/>
        <id>https://2π.com/15/dd4bc/</id>
        
        <content type="html" xml:base="https://2π.com/15/dd4bc/">&lt;h1 id=&quot;cointel-investigation-of-dd4bc&quot;&gt;Cointel investigation of ‘DD4BC’&lt;&#x2F;h1&gt;
&lt;p&gt;This is an example investigation of one particular threat made using the moniker DD4BC.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;threats&quot;&gt;Threats&lt;&#x2F;h2&gt;
&lt;p&gt;On Saturday November 15th several emails where sent with the subject &lt;code&gt;mpex.co - DDOS ATTACK!&lt;&#x2F;code&gt; was send from &lt;code&gt;DD4BC TEAM &amp;lt;dd4bc@outlook.com&amp;gt;&lt;&#x2F;code&gt;. The email headers indicate the origin is indeed the webmail service outlook.com. The sender was GMT+1, all times are in GMT.&lt;&#x2F;p&gt;
&lt;p&gt;At 12:45:59:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello,&lt;&#x2F;p&gt;
&lt;p&gt;To introduce myself first:&lt;br &#x2F;&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cointelegraph.com&#x2F;news&#x2F;112606&#x2F;nitrogensports-goes-public-to-combat-extortion-blackmail-and-slander&quot;&gt;http:&#x2F;&#x2F;cointelegraph.com&#x2F;news&#x2F;112606&#x2F;nitrogensports-goes-public-to-combat-extortion-blackmail-and-slander&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;:)&lt;&#x2F;p&gt;
&lt;p&gt;Now, to business:&lt;&#x2F;p&gt;
&lt;p&gt;My&lt;br &#x2F;&gt;
attacks are sophisticated and too strong that I can bypass any&lt;br &#x2F;&gt;
protection other then PROLEXIC ( and i will cost you 5-10 K per month).&lt;br &#x2F;&gt;
Google and check how many sites behind CloudFlare and similar shitty&lt;br &#x2F;&gt;
protections I crashed.&lt;&#x2F;p&gt;
&lt;p&gt;Pay me 1 BTC and your site is &quot;protected&quot; for lifetime. Pay to BTC address:&lt;br &#x2F;&gt;
132EdUarcghK2barhkxgaKQ2XqnchPbWSB&lt;&#x2F;p&gt;
&lt;p&gt;Right now I&#x27;m running small attack for 1 hour as proof.&lt;&#x2F;p&gt;
&lt;p&gt;After that I expect your payment.&lt;&#x2F;p&gt;
&lt;p&gt;Please not that if I&#x27;m not paid within 2 hours, price will increase to 1 BTC to stop&lt;br &#x2F;&gt;
and will keep increasing 0.1 BTC for every hour of attack.&lt;&#x2F;p&gt;
&lt;p&gt;Thank you.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;At 14:29:01:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello :)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;At 16:36:07:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Attack temporarily stopped to give you time to read email and act.&lt;&#x2F;p&gt;
&lt;p&gt;You still have chance to end this for 1 BTC.&lt;&#x2F;p&gt;
&lt;p&gt;If not, attack restarts in 1 hour and price goes to 2 BTC.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;At 17:44:26:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Not sure if you are online and reading my emails, so I will be nice and wait a few
more hours...&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We have not looked for further messages or execution of threats.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-money-chain&quot;&gt;The money chain&lt;&#x2F;h2&gt;
&lt;p&gt;The threats demand a ransom to be paid to the Bitcoin address:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;132EdUarcghK2barhkxgaKQ2XqnchPbWSB&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Only two transactions involving this address ever appeared on the Blockchain. The transactions are made on December 4th, nineteen days after the threat. The transaction amount is only 21.7 mBTC, which is roughly € 6 at the time.&lt;&#x2F;p&gt;
&lt;p&gt;The two transactions are part of a larger structure of single-output and zero-confirmation transfers. The money is transfered from &lt;em&gt;Laxo Trade Ltd.&lt;&#x2F;em&gt; to the &lt;em&gt;Satoshi Bones&lt;&#x2F;em&gt; casino. The transfers is indirect and involves 13 intermediary addresses, of which the ransom address is one.&lt;&#x2F;p&gt;
&lt;p&gt;First the money is transfered from &lt;em&gt;Laxo Trade Ltd.&lt;&#x2F;em&gt; with twelve transactions to address 13. About 5% is lost in transactions fees in the process. The transactions are created on 4 December in one and a half hour before midnight. The transactions end up in five blocks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Block 332896 mined on 2014-12-04 22:35:13&lt;&#x2F;li&gt;
&lt;li&gt;Block 332900 mined on 2014-12-04 22:58:26&lt;&#x2F;li&gt;
&lt;li&gt;Block 332901 mined on 2014-12-04 23:16:34&lt;&#x2F;li&gt;
&lt;li&gt;Block 332903 mined on 2014-12-04 23:30:58&lt;&#x2F;li&gt;
&lt;li&gt;Block 332905 mined on 2014-12-05 00:02:52&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Most transactions, including the first, use zero-confirmation inputs. The first part of the chain only has a single output with no change. The second part re-uses the same change address. The addresses involved have not been used before or since, with the notable exception of the ransom address.&lt;&#x2F;p&gt;
&lt;p&gt;This leads us to believe the chain was orchestrated by a single individual operating all addresses except the last one. In particular, this individual has the access to both the &lt;em&gt;Laxo Trade Ltd.&lt;&#x2F;em&gt; wallet key and the wallet associated to the ransom address.&lt;&#x2F;p&gt;
&lt;p&gt;The money ultimately ends up in the &lt;em&gt;Satoshi Bones 0.09766%&lt;&#x2F;em&gt; address. This places a bet with a less than one-in-thousand odds of winning. Eighteen bets are placed, constructed using the minimal bet amount of 1 mBTC. The money&lt;&#x2F;p&gt;
&lt;p&gt;Inputs  Outputs   Amount (mBTC)  Fee (μBTC)  Block   Received From&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;1, 1    2                  21.8      126.56  332896  22:31:57 blockchain.info
2       3                  21.7      100.00  332896  22:32:29 54.72.94.231
3       4                  21.6      100.00  332896  22:33:03 104.131.128.248
4       5                  21.5      100.00  332896  22:33:29 97.107.135.113
5       6                  21.4      100.00  332900  22:46:04 162.220.47.184
6       7                  21.3      100.00  332900  22:47:43 63.142.215.160
7       8                  21.2      100.00  332901  23:01:03 72.191.29.242
8       9                  21.1      100.00  332901  23:01:23 185.19.104.122
9       10                 21.0      100.00  332901  23:15:29 108.219.80.251
10      11                 21.9      100.00  332903  23:19:34 81.30.203.67
11      12                 20.8      100.00  332903  23:21:27 88.198.6.235
12      13                 20.7      100.00  332903  23:21:47 85.17.238.8&lt;&#x2F;p&gt;
&lt;p&gt;Inputs  Outputs   Amount (mBTC)  Fee (μBTC)   Block  Received From&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;13      14, 15        19.6, 1.0      100.00  332903  23:22:44 83.243.255.226
14      14, 15        18.5, 1.0      100.00  332903  23:23:01 85.10.234.22
14      14, 15        17.4, 1.0      100.00  332903  23:23:13 162.220.47.184
14      14, 15        16.3, 1.0      100.00  332903  23:23:28 69.246.9.178
14      14, 15        15.2, 1.0      100.00  332903  23:23:40 95.154.200.216
14      14, 15        14.1, 1.0      100.00  332903  23:23:50 72.228.153.102
14      14, 15        13.0, 1.0      100.00  332903  23:23:59 104.131.247.112
14      14, 15        11.9, 1.0      100.00  332903  23:24:21 162.220.47.184
14      14, 15        10.8, 1.0      100.00  332903  23:24:34 107.170.26.17
14      14, 15         9.7, 1.0      100.00  332903  23:24:53 23.226.70.194
14      14, 15         8.6, 1.0      100.00  332903  23:25:07 104.131.247.112
14      14, 15         7.5, 1.0      100.00  332903  23:25:32 162.220.47.184
14      14, 15         6.4, 1.0      100.00  332903  23:25:48 54.172.163.55
14      14, 15         5.3, 1.0      100.00  332905  23:46:00 208.12.64.254
14      14, 15         4.2, 1.0      100.00  332905  23:46:15 178.79.189.150
14      14, 15         3.1, 1.0      100.00  332905  23:46:25 178.79.189.150
14      14, 15         2.0, 1.0      100.00  332905  23:46:36 162.220.47.184
14      15                  1.9      100.00  332905  23:47:02 73.181.23.132&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Addresses&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;1LaxoTrQy51LnB289VmoSAgN6J6UrJbfL9&lt;&#x2F;code&gt; Laxo Trade Ltd.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1HoKWoK7X7cGJkWNgzjvjRM1G7H3pvNmE9&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;132EdUarcghK2barhkxgaKQ2XqnchPbWSB&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1KzKw6ssAF1THNJHCED5XASnyupELbcrxM&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1MjrL4tq2duUhhdxHYPLBgwH6uc1TokS5v&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1LBod6Gocz2PQRb4yJNuZ9dw52aprmGTdP&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1G7pLf1xcGPkqxFBdUniv6KeaodVFqAHxr&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1CJbRJbcajKcEN4mdTGh1XLPKXBetP2N7q&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1cq5a48DBXAbevcVC9Kaa265wphXboRsQ &lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;18TinsgCuwtzKw4Z8i4i5iTH1FTGyAv4fJ&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;141ntTr3VUHa8i9fA8Ut9eLzhXQjZougTk&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1ErYHkQ7yi1i5a16yJJb27hC1zBsoePUxf&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;15yTh12V4YY5Y6YbCetTKad9jbdntsHUph&lt;&#x2F;code&gt; Single use&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;16yzpVa3eR7xdXni1PGAW55X92HBkodZda&lt;&#x2F;code&gt; Change address, only used here&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;1bonesbTK2GjYasv5yzGPFCMAaQHup4vk &lt;&#x2F;code&gt; Satoshi Bones 0.09766%&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;laxo-trade-ltd&quot;&gt;Laxo Trade Ltd.&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;laxotrade.com&lt;&#x2F;code&gt; was registered on 2014-02-13 14:18:07 for &lt;em&gt;Laxo Trade Ltd.&lt;&#x2F;em&gt;  It operated an online Ponzi scheme during 2014. &lt;em&gt;Laxo Trade Ltd.&lt;&#x2F;em&gt; is unique in that it is the first company to send bitcoins to bitcoin addresses as a means of advertisement. It did this using the address &lt;code&gt;1LaxoTrQy51LnB289VmoSAgN6J6UrJbfL9&lt;&#x2F;code&gt; found above.&lt;&#x2F;p&gt;
&lt;p&gt;WHOIS &lt;code&gt;laxotrade.com&lt;&#x2F;code&gt; on 2014-05-21:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Orville Gibbs&lt;br &#x2F;&gt;
Laxo Trade Ltd&lt;br &#x2F;&gt;
admin@laxotrade.com&lt;br &#x2F;&gt;
+44.2074059813 fax: +44.2074059813&lt;br &#x2F;&gt;
236 Gray’s Inn Road, Floor 7&lt;br &#x2F;&gt;
London England WC1X 8HB&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;WHOIS &lt;code&gt;laxotrade.com&lt;&#x2F;code&gt; on 2014-05-21:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ognjen Plameny&lt;br &#x2F;&gt;
Laxo Trade Ltd&lt;br &#x2F;&gt;
plameny@safe-mail.net&lt;br &#x2F;&gt;
+3346534534 fax: +3346534534&lt;br &#x2F;&gt;
15-22 New Inn Yard&lt;br &#x2F;&gt;
London England EC2A 3EA&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Catena Finance Ltd.&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;A similar Ponzi scheme, &lt;em&gt;Catenda Finance Ltd.&lt;&#x2F;em&gt; was operating in 2013. The scheme operated online on the domain &lt;code&gt;catenafinance.com&lt;&#x2F;code&gt; created on 2013-03-21. According to the archived website the limited incorporated on 15th April 2013 with number 8488673. The WHOIS information has the identity &lt;em&gt;Ognjen Plameny&lt;&#x2F;em&gt; in common. The name &lt;em&gt;Ognjen Plameny&lt;&#x2F;em&gt; is Czech for “Fiery Flames” and possibly a pseudonym.&lt;&#x2F;p&gt;
&lt;p&gt;WHOIS &lt;code&gt;catenafinance.com&lt;&#x2F;code&gt; on 2013-12-26:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ognjen Plameny&lt;br &#x2F;&gt;
Catena Finance LTD&lt;br &#x2F;&gt;
plameny@safe-mail.net&lt;br &#x2F;&gt;
+86.05922577111 fax: +86.05922577111&lt;br &#x2F;&gt;
15-22 New Inn Yard&lt;br &#x2F;&gt;
London England EC2A 3EA&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;WHOIS &lt;code&gt;catenafinance.com&lt;&#x2F;code&gt; on 2013-07-28:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Enver Hasanbasic&lt;br &#x2F;&gt;
Catena Finance LTD&lt;br &#x2F;&gt;
domain@catenafinance.com&lt;br &#x2F;&gt;
+86.05922577111 fax: +86.05922577111&lt;br &#x2F;&gt;
15-22 New Inn Yard&lt;br &#x2F;&gt;
London England EC2A 3EA&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;WHOIS &lt;code&gt;catenafinance.com&lt;&#x2F;code&gt; on 2013-07-01:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Whois Privacy Protection Service&lt;br &#x2F;&gt;
Whois Agent gmvjcxkxhs@whoisservices.cn&lt;br &#x2F;&gt;
+86.05922577888 fax: +86.05922577111&lt;br &#x2F;&gt;
No. 61 Wanghai Road, Xiamen Software Park&lt;br &#x2F;&gt;
Ciamen Fujian China 361008&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;em&gt;Sources:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;bitzillions.com&#x2F;satoshibones&#x2F;betaddress&#x2F;201412&quot;&gt;http:&#x2F;&#x2F;bitzillions.com&#x2F;satoshibones&#x2F;betaddress&#x2F;201412&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.cryptocoinsnews.com&#x2F;companies-send-free-bitcoins-advertisements&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.cryptocoinsnews.com&#x2F;companies-send-free-bitcoins-advertisements&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20150214150509&#x2F;https:&#x2F;&#x2F;www.laxotrade.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20150214150509&#x2F;https:&#x2F;&#x2F;www.laxotrade.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;whois.easycounter.com&#x2F;laxotrade.com&quot;&gt;https:&#x2F;&#x2F;whois.easycounter.com&#x2F;laxotrade.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;whois.easycounter.com&#x2F;catenafinance.com&quot;&gt;https:&#x2F;&#x2F;whois.easycounter.com&#x2F;catenafinance.com&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20130819063839&#x2F;https:&#x2F;&#x2F;www.catenafinance.com&#x2F;index.php?a=home&quot;&gt;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20130819063839&#x2F;https:&#x2F;&#x2F;www.catenafinance.com&#x2F;index.php?a=home&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20130818084452&#x2F;http:&#x2F;&#x2F;money-news-online.com&#x2F;blog&#x2F;2013&#x2F;07&#x2F;25&#x2F;25072013-interview-with-the-admin-of-catenafinance&#x2F;&quot;&gt;https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20130818084452&#x2F;http:&#x2F;&#x2F;money-news-online.com&#x2F;blog&#x2F;2013&#x2F;07&#x2F;25&#x2F;25072013-interview-with-the-admin-of-catenafinance&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Full deniability</title>
        <published>2015-08-27T00:00:00+00:00</published>
        <updated>2015-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/15/mesh-cipher-2/"/>
        <id>https://2π.com/15/mesh-cipher-2/</id>
        
        <content type="html" xml:base="https://2π.com/15/mesh-cipher-2/">&lt;h1 id=&quot;full-deniability&quot;&gt;Full deniability&lt;&#x2F;h1&gt;
&lt;p&gt;https:&#x2F;&#x2F;moderncrypto.org&#x2F;mail-archive&#x2F;curves&#x2F;2014&#x2F;000107.html&lt;&#x2F;p&gt;
&lt;p&gt;Similar to KEA+ http:&#x2F;&#x2F;research.microsoft.com&#x2F;en-us&#x2F;um&#x2F;people&#x2F;klauter&#x2F;security_of_kea_ake_protocol.pdf&lt;&#x2F;p&gt;
&lt;p&gt;http:&#x2F;&#x2F;nvlpubs.nist.gov&#x2F;nistpubs&#x2F;SpecialPublications&#x2F;NIST.SP.800-56Ar2.pdf&lt;&#x2F;p&gt;
&lt;p&gt;Noise pipes begin with a Triple Diffie-Hellman key agreement, as sketched above. This key agreement is similar to the variant of &quot;Protocol 1&quot; from Kudla and Paterson, section 5.1 where forward-secrecy is added via a DH between the two ephemeral keys. However, the parties&#x27; identities are encrypted, accomplishing &quot;identity-hiding&quot; in the style of SIGMA-I. Since signatures are not used, Noise offers smaller messages, simpler cryptography, and stronger deniability than SIGMA-I.&lt;&#x2F;p&gt;
&lt;p&gt;Next version:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Full deniability: Handshake using Triple-DH&lt;&#x2F;li&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Plaintext length hiding&lt;&#x2F;li&gt;
&lt;li&gt;All Diffie-Hellman (no signatures): Using TLS with ephemeral ECDH requires signatures. Noise relies only on ECDH (no signatures). This yields a simpler and more robust protocol, reduces bandwidth, and avoids creating hard-to-deny evidence of who has communicated with who.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Proposal:&lt;&#x2F;p&gt;
&lt;!--
sloccount .&#x2F;Cryptography&#x2F;{SymmetricKey2,SharedSecretKey,SignatureKey,Hash,Keccak,SpongeWrap}* .&#x2F;Networking&#x2F;{MeshCipher,MeshHandshake}*
sloccount .&#x2F;Cryptography&#x2F;{SymmetricKey2,SharedSecretKey,Hash,Keccak,SpongeWrap}* .&#x2F;Networking&#x2F;{MeshCipher,MeshHandshake}*
--&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;&#x2F;th&gt;&lt;th&gt;New&lt;&#x2F;th&gt;&lt;th&gt;Old&lt;&#x2F;th&gt;&lt;th&gt;TLS&lt;&#x2F;th&gt;&lt;th&gt;SSH&lt;&#x2F;th&gt;&lt;th&gt;IPSec&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Complexity (lines of code)&lt;&#x2F;td&gt;&lt;td&gt;1639&lt;&#x2F;td&gt;&lt;td&gt;3447&lt;&#x2F;td&gt;&lt;td&gt;437,157&lt;&#x2F;td&gt;&lt;td&gt;44,140&lt;&#x2F;td&gt;&lt;td&gt;25,075&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Handshake round trips&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Handshake overhead (bytes)&lt;&#x2F;td&gt;&lt;td&gt;148&lt;&#x2F;td&gt;&lt;td&gt;584&lt;&#x2F;td&gt;&lt;td&gt;2403&lt;&#x2F;td&gt;&lt;td&gt;4485&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Packet overhead (bytes)&lt;&#x2F;td&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;29—203&lt;&#x2F;td&gt;&lt;td&gt;33&lt;&#x2F;td&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt; is the generator of Curve25519.&lt;&#x2F;p&gt;
&lt;p&gt;Alice has long term authenticating secret &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; and generates one-time ephemeral secret &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Bob has long term authenticating secret &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and generates one-time ephemeral secret &lt;span class=&quot;math math-inline&quot;&gt;d&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;To initiate a session using triple DH.&lt;&#x2F;p&gt;
&lt;p&gt;Alice: compute &lt;span class=&quot;math math-inline&quot;&gt;C = c G&lt;&#x2F;span&gt; and send &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; to Bob&lt;&#x2F;p&gt;
&lt;p&gt;Bob: compute&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;D = d G&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;s₁ = \mathrm{hash}(d C)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;s₂ = \mathrm{hash}( ∥ s₁)&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;S₁ = a b G&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;S₂ = a b G&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;See: https:&#x2F;&#x2F;whispersystems.org&#x2F;blog&#x2F;simplifying-otr-deniability&#x2F;
See: https:&#x2F;&#x2F;github.com&#x2F;trevp&#x2F;noise&#x2F;wiki&#x2F;Overview&lt;&#x2F;p&gt;
&lt;p&gt;(A,a)   : client&#x27;s public key C and private key c
(B,b)   : server&#x27;s public key S and private key s
(C,c) : client&#x27;s ephemeral public key C&#x27; and private key c&#x27;
(D,d) : server&#x27;s ephemeral public key D and private key d&lt;&#x2F;p&gt;
&lt;p&gt;Client -&amp;gt; Server : C
56 bytes&lt;&#x2F;p&gt;
&lt;p&gt;key1 = HASH(c * D) = HASH(d * C)
key2 = HASH((c * B) || key1) = HASH((b * C) || key1)&lt;&#x2F;p&gt;
&lt;p&gt;Client &amp;lt;- Server : D || Encrypt(key1, B) || Encrypt(key2, data)
56 + 56 bytes&lt;&#x2F;p&gt;
&lt;p&gt;key3 = HASH((a * D) || key2) = HASH()&lt;&#x2F;p&gt;
&lt;p&gt;Client -&amp;gt; Server : Encrypt(key2, A) || Encrypt(key3, data)
56 bytes&lt;&#x2F;p&gt;
&lt;p&gt;Serve -&amp;gt; Client&lt;&#x2F;p&gt;
&lt;p&gt;128 bytes.&lt;&#x2F;p&gt;
&lt;p&gt;(A,a)   : client&#x27;s public key C and private key c
(B,b)   : server&#x27;s public key S and private key s
(C,c) : client&#x27;s ephemeral public key C&#x27; and private key c&#x27;
(D,d) : server&#x27;s ephemeral public key D and private key d&lt;&#x2F;p&gt;
&lt;p&gt;Client -&amp;gt; Server : C
32 bytes&lt;&#x2F;p&gt;
&lt;p&gt;key1 = HASH(c * D) = HASH(d * C)&lt;&#x2F;p&gt;
&lt;p&gt;Client &amp;lt;- Server : D || Encrypt(key1, B)
64 bytes&lt;&#x2F;p&gt;
&lt;p&gt;key2 = HASH((c * B) || key1) = HASH((b * C) || key1)
key3 = HASH((a * D) || key2) = HASH()&lt;&#x2F;p&gt;
&lt;p&gt;Client -&amp;gt; Server: Encrypt(key2, A)
32 bytes&lt;&#x2F;p&gt;
&lt;p&gt;Server -&amp;gt; Client&lt;&#x2F;p&gt;
&lt;p&gt;128 bytes.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Position log</title>
        <published>2015-08-27T00:00:00+00:00</published>
        <updated>2015-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/15/position-log/"/>
        <id>https://2π.com/15/position-log/</id>
        
        <content type="html" xml:base="https://2π.com/15/position-log/">&lt;h1 id=&quot;position-log&quot;&gt;Position log&lt;&#x2F;h1&gt;
&lt;p&gt;The logging app I&#x27;m using is
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;play.google.com&#x2F;store&#x2F;apps&#x2F;details?id=com.mendhak.gpslogger&quot;&gt;GPS Logger&lt;&#x2F;a&gt;.
I&#x27;m storing in &lt;code&gt;GPX&lt;&#x2F;code&gt; and &lt;code&gt;KML&lt;&#x2F;code&gt; files. Their formats are as follows:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Keyhole Markup Language&lt;&#x2F;strong&gt;: The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Keyhole_Markup_Language&quot;&gt;KML&lt;&#x2F;a&gt;. Is very simple, but also doesn&#x27;t offer much. It Looks like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;xml&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; version&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;1.0&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; encoding&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;kml&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;http:&#x2F;&#x2F;www.opengis.net&#x2F;kml&#x2F;2.2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;	xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;gx&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;http:&#x2F;&#x2F;www.google.com&#x2F;kml&#x2F;ext&#x2F;2.2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;	xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;kml&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;http:&#x2F;&#x2F;www.opengis.net&#x2F;kml&#x2F;2.2&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;	xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;atom&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2005&#x2F;Atom&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Document&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;2015-08-12T22:01:58Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Placemark&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;gx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Track&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&amp;lt;!-- Then many repetitions looking like  --&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;when&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;2015-08-12T22:01:58Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;when&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;gx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;coord&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;2.662407 49.23818433 147.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;gx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;coord&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;gx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Track&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Placemark&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;Document&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;kml&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;GPS Exchange Format&lt;&#x2F;strong&gt;. The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;GPS_Exchange_Format&quot;&gt;GPX&lt;&#x2F;a&gt; format looks like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;xml&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; version&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;1.0&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; encoding&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt; ?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;gpx&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; version&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;1.0&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; creator&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;GPSLogger - http:&#x2F;&#x2F;gpslogger.mendhak.com&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;	xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;xsi&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;http:&#x2F;&#x2F;www.w3.org&#x2F;2001&#x2F;XMLSchema-instance&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;	xmlns&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;http:&#x2F;&#x2F;www.topografix.com&#x2F;GPX&#x2F;1&#x2F;0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;	xsi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt;schemaLocation&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;http:&#x2F;&#x2F;www.topografix.com&#x2F;GPX&#x2F;1&#x2F;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string z-punctuation z-definition z-string&quot;&gt;		http:&#x2F;&#x2F;www.topografix.com&#x2F;GPX&#x2F;1&#x2F;0&#x2F;gpx.xsd&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;time&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;2015-08-12T22:01:58Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;time&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;trk&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;trkseg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&amp;lt;!-- It then proceeds with repetitions of --&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;trkpt&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; lat&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;49.24454858&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; lon&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;2.67159307&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ele&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;148.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;ele&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;time&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;2015-08-12T22:02:32Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;time&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;course&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;45.2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;course&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;speed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;27.89&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;speed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;gps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;22&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;hdop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;1.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;hdop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;vdop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;1.3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;vdop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;pdop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;1.6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;pdop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;geoidheight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;48.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;geoidheight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;trkpt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&amp;lt;!-- Mixed with repetitions of --&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;trkpt&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; lat&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;52.4060613&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-other z-attribute-name&quot;&gt; lon&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;6.9069997&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;time&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;2015-08-13T21:38:19Z&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;time&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;network&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;src&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text&quot;&gt;27&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;sat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;trkpt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;trkseg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;trk&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag&quot;&gt;gpx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After navigating the spec (combining version 1.0 with the more extensively documented 1.1), the following can be found:&lt;&#x2F;p&gt;
&lt;p&gt;Element       Documentation&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;trkpt&lt;&#x2F;code&gt;       A Track Point holds the coordinates, elevation, timestamp, and metadata for a single point in a track.
&lt;code&gt;lat&lt;&#x2F;code&gt;         The latitude of the point. Decimal degrees, WGS84 datum.
&lt;code&gt;lon&lt;&#x2F;code&gt;         The longitude of the point. Decimal degrees, WGS84 datum.
&lt;code&gt;ele&lt;&#x2F;code&gt;         Elevation (in meters) of the point.
&lt;code&gt;time&lt;&#x2F;code&gt;        Creation&#x2F;modification timestamp for element. Date and time in are in Univeral Coordinated Time (UTC), not local time! Conforms to ISO 8601 specification for date&#x2F;time representation. Fractional seconds are allowed for millisecond timing in tracklogs.
&lt;code&gt;course&lt;&#x2F;code&gt;      Instantaneous course at the point. (degrees, true) (only in 1.0)
&lt;code&gt;speed&lt;&#x2F;code&gt;       Instantaneous speed at the point. (meters per second) (only in 1.0)
&lt;code&gt;src&lt;&#x2F;code&gt;         Source of data. Included to give user some idea of reliability and accuracy of data. &quot;Garmin eTrex&quot;, &quot;USGS quad Boston North&quot;, e.g.
&lt;code&gt;sat&lt;&#x2F;code&gt;         Number of satellites used to calculate the GPX fix.
&lt;code&gt;hdop&lt;&#x2F;code&gt;        Horizontal dilution of precision.
&lt;code&gt;vdop&lt;&#x2F;code&gt;        Vertical dilution of precision.
&lt;code&gt;pdop&lt;&#x2F;code&gt;        Position dilution of precision.
&lt;code&gt;geoidheight&lt;&#x2F;code&gt; Height (in meters) of geoid (mean sea level) above WGS84 earth ellipsoid. As defined in NMEA GGA message.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Source&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.topografix.com&#x2F;gpx_manual.asp&quot;&gt;Specification version 1.0&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.topografix.com&#x2F;GPX&#x2F;1&#x2F;1&#x2F;&quot;&gt;Specification version 1.1&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;dilution-of-precision&quot;&gt;Dilution of precision&lt;&#x2F;h2&gt;
&lt;p&gt;Measurements are never exact and always have an error. This modelled as either an interval, or a probability distribution around the true value. The &lt;code&gt;hdop&lt;&#x2F;code&gt;, &lt;code&gt;vdop&lt;&#x2F;code&gt; and &lt;code&gt;pdop&lt;&#x2F;code&gt; values provide an error estimate. According to  &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dilution_of_precision_%28GPS%29&quot;&gt;wikipedia&lt;&#x2F;a&gt; they are defined as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\text{hdop} &amp;amp;= \sqrt{σ_{xx} + σ_{yy}} \\
\text{vdop} &amp;amp;= \sqrt{σ_{zz}} \\
\text{pdop} &amp;amp;= \sqrt{σ_{xx} + σ_{yy} + σ_{zz}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;σ&lt;&#x2F;span&gt;&#x27;s are diagonal elements of the covariance matrix of the four space-time coordinates:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Σ =
\operatorname{cov} \begin{bmatrix} x \\ y \\ z \\ t \end{bmatrix} =
\begin{bmatrix}
σ_{xx} &amp;amp; σ_{yx} &amp;amp; σ_{zx} &amp;amp; σ_{tx} \\
σ_{xy} &amp;amp; σ_{yy} &amp;amp; σ_{zy} &amp;amp; σ_{ty} \\
σ_{xz} &amp;amp; σ_{yz} &amp;amp; σ_{zz} &amp;amp; σ_{tz} \\
σ_{xt} &amp;amp; σ_{yt} &amp;amp; σ_{zt} &amp;amp; σ_{tt}
\end{bmatrix}
= Σ^T
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;span class=&quot;math math-inline&quot;&gt;\text{pdop}² = \text{hdop}² + \text{vdop}²&lt;&#x2F;span&gt; we really only have two values out of the ten that are relevant. And we are still missing a description of distribution of the errors. Bbzippo wrote about the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bbzippo.wordpress.com&#x2F;2012&#x2F;02&#x2F;13&#x2F;distribution-of-gps-accuracy&#x2F;&quot;&gt;error distribution&lt;&#x2F;a&gt;. He&#x2F;she mentions that the simple assumption of independent normally distributed coordinates agrees well with measurements. Let&#x27;s run with this assumption.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x &amp;amp;\sim N(\bar x, σ_{xx}) &amp;amp;
y &amp;amp;\sim N(\bar x, σ_{yy}) &amp;amp;
z &amp;amp;\sim N(\bar x, σ_{zz}) &amp;amp;
t &amp;amp;\sim N(\bar x, σ_{tt})
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For the elevation, &lt;span class=&quot;math math-inline&quot;&gt;z&lt;&#x2F;span&gt;, we can directly use the distribution. For the time we have no error estimates whatsoever. The horizontal error is a bit more involved, we know &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{σ_{xx} + σ_{yy}}&lt;&#x2F;span&gt; but not the individual values of &lt;span class=&quot;math math-inline&quot;&gt;σ_{xx}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;σ_{yy}&lt;&#x2F;span&gt;. If we assume &lt;span class=&quot;math math-inline&quot;&gt;σ_{xx} = σ_{yy} = σ&lt;&#x2F;span&gt; then we can set &lt;span class=&quot;math math-inline&quot;&gt;σ = ½\mathrm{hdop}²&lt;&#x2F;span&gt;. We can move further and calculate the horizontal error distribution:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left\vert \begin{bmatrix} x \\ y \end{bmatrix} - \begin{bmatrix} \bar x \\ \bar y \end{bmatrix} \right\vert
= \sqrt{ (x - \bar x)² + (y - \bar y)²} \sim \operatorname{Rayleight} (σ)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data&quot;&gt;Data&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cat *.csv | sort &amp;gt; full.csv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;time,longitude,latitude,elevation,hdop,vdop&amp;quot; &amp;gt; short.csv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;awk &amp;#39;NR % 100 == 0&amp;#39; full.csv &amp;gt;&amp;gt; short.csv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;plot&quot;&gt;Plot&lt;&#x2F;h2&gt;
&lt;div id=&quot;world&quot;&gt;&lt;&#x2F;div&gt;
&lt;style type=&quot;text&#x2F;css&quot; scoped&gt;

svg.map .stroke {
	fill: none;
	stroke: #000;
	stroke-width: 1px;
}

svg.map .fill {
	fill: black;
}

svg.map .graticule {
	fill: none;
	stroke: orange;
	stroke-opacity: .5;
	stroke-width: .5px;
}

svg.map .land {
	fill: black;
	stroke: orange;
}

svg.map .borders {
	fill: none;
	stroke: orange;
	stroke-width: .5px;
}

svg.map .node {
	fill: white;
	stroke: none;
	opacity: .1;
}
&lt;&#x2F;style&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;cdnjs.cloudflare.com&#x2F;ajax&#x2F;libs&#x2F;d3&#x2F;3.5.5&#x2F;d3.min.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;cdnjs.cloudflare.com&#x2F;ajax&#x2F;libs&#x2F;queue-async&#x2F;1.0.7&#x2F;queue.min.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;script defer src=&quot;http:&#x2F;&#x2F;d3js.org&#x2F;d3.geo.projection.v0.min.js&quot; charset=&quot;utf-8&quot;&gt;&lt;&#x2F;script&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;cdnjs.cloudflare.com&#x2F;ajax&#x2F;libs&#x2F;topojson&#x2F;1.6.19&#x2F;topojson.min.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;script&gt;window.on(&quot;load&quot;,function() {

var s = .7;
var width = 960 * s,
	height = 500 * s;

&#x2F;&#x2F; https:&#x2F;&#x2F;github.com&#x2F;d3&#x2F;d3-geo-projection&#x2F;
projection = d3.geo.naturalEarth()
	.scale(167 * s)
	.translate([width &#x2F; 2, height &#x2F; 2])
	.precision(.1);
var path = d3.geo.path().projection(projection);
var graticule = d3.geo.graticule();

var svg = d3.select(&quot;#world&quot;)
	.append(&quot;svg&quot;)
		.attr(&quot;class&quot;, &quot;map&quot;)
		.attr(&quot;width&quot;, width)
		.attr(&quot;height&quot;, height)
		.attr(&quot;style&quot;, &quot;display:block; margin:0 auto;&quot;)

svg.append(&quot;path&quot;)
	.datum(graticule.outline())
	.attr(&quot;class&quot;, &quot;stroke&quot;)
	.attr(&quot;d&quot;, path);
svg.append(&quot;path&quot;)
	.datum(graticule.outline())
	.attr(&quot;class&quot;, &quot;fill&quot;)
	.attr(&quot;d&quot;, path);
svg.append(&quot;path&quot;)
	.datum(graticule)
	.attr(&quot;class&quot;, &quot;graticule&quot;)
	.attr(&quot;d&quot;, path);
var gcountries = svg.append(&quot;g&quot;)
	.attr(&quot;class&quot;, &quot;countries&quot;);
var dl = svg.append(&quot;g&quot;)
	.attr(&quot;class&quot;, &quot;data-layer&quot;);

var color1 = d3.scale.category20();

function color(n) {
	return d3.interpolateRgb(color1(n), &quot;#e2caba&quot;)(0.9);
}

d3.json(&quot;&#x2F;15&#x2F;position-log&#x2F;world-110m.json&quot;, function(error, world) {
	var countries = topojson.feature(world, world.objects.countries).features,
		neighbors = topojson.neighbors(world.objects.countries.geometries);
	&#x2F;*
	gcountries.selectAll(&quot;.country&quot;)
		.data(countries).enter()
		.insert(&quot;path&quot;)
		.attr(&quot;class&quot;, &quot;country&quot;)
		.attr(&quot;d&quot;, path)
		.style(&quot;fill&quot;, function(d, i) {
			return color(d.color = d3.max(neighbors[i], function(n) { return countries[n].color; }) + 1 | 0); });
	*&#x2F;
	svg.insert(&quot;path&quot;, &quot;.data-layer&quot;)
		.datum(topojson.feature(world, world.objects.land))
		.attr(&quot;class&quot;, &quot;land&quot;)
		.attr(&quot;d&quot;, path);
	gcountries.insert(&quot;path&quot;, &quot;.data-layer&quot;)
		.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
		.attr(&quot;class&quot;, &quot;borders&quot;)
		.attr(&quot;d&quot;, path);
})

d3.csv(&quot;&#x2F;15&#x2F;position-log&#x2F;short.csv&quot;, function(d) {
	return [+d.longitude, +d.latitude];
},function(error, rows) {
	dl.selectAll(&quot;circle&quot;).data(rows).enter()
		.append(&quot;circle&quot;)
		.attr(&quot;cx&quot;, function(d) {
			return projection(d)[0];
		})
		.attr(&quot;cy&quot;, function(d) {
			return projection(d)[1];
		})
		.attr(&quot;r&quot;, 2)
		.attr(&quot;class&quot;, &quot;node&quot;);
})

})
&lt;&#x2F;script&gt;
&lt;ul&gt;
&lt;li&gt;TODO: Give the countries a slight tint http:&#x2F;&#x2F;bl.ocks.org&#x2F;jasondavies&#x2F;4188334&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Principia</title>
        <published>2015-08-27T00:00:00+00:00</published>
        <updated>2015-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/15/principia/"/>
        <id>https://2π.com/15/principia/</id>
        
        <content type="html" xml:base="https://2π.com/15/principia/">&lt;h1 id=&quot;principia&quot;&gt;Principia&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hello_world ↦ “Hello, World!”&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Futuristic programming, reasoning and proof language.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;about-the-name&quot;&gt;About the name&lt;&#x2F;h3&gt;
&lt;p&gt;The name is a reference to Whitehead &amp;amp; Russel&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Principia_Mathematica&quot;&gt;Principia Mathemica&lt;&#x2F;a&gt;. ‘Mathematica’ was already taken by another cool programming language, so I choose ‘Principia’. It fits, because this language is focused more on principles and less on mathematics. (Although I envision a fully-proven high performance computer algebra library to be one of the first applications).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;syntax&quot;&gt;Syntax&lt;&#x2F;h2&gt;
&lt;p&gt;The syntax is minimalist and heavily uses the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.unicode.org&#x2F;versions&#x2F;Unicode6.2.0&#x2F;&quot;&gt;Unicode Standard&lt;&#x2F;a&gt;. Please use something like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Compose_key&quot;&gt;compose keys&lt;&#x2F;a&gt; to enter Unicode characters (here&#x27;s my setup: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Recmo&#x2F;XCompile&quot;&gt;XCompile&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The language is a union between a programming language and a proof language. The programming language consists of just two constructs, &lt;em&gt;calls&lt;&#x2F;em&gt; and &lt;em&gt;closures&lt;&#x2F;em&gt;. It has eager evaluation, first-class functions and multiple return values. The proof language has four constructs, &lt;em&gt;because&lt;&#x2F;em&gt;, &lt;em&gt;axiom&lt;&#x2F;em&gt;, &lt;em&gt;therefore&lt;&#x2F;em&gt; and &lt;em&gt;proofs&lt;&#x2F;em&gt;. Both these languages live in a space that is similar to a directed cyclic multi-graph.&lt;&#x2F;p&gt;
&lt;p&gt;Unifying these languages is a meta-language that turns these graphs into a linear syntax for consumption by text editors. The meta-language handles scoping and identifier binding. It should be noted that binding is separate from the programming language. The programming language has &lt;em&gt;no&lt;&#x2F;em&gt; concept of variables and binding (and therefore, none of the problems associated with it).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;identifiers&quot;&gt;Identifiers&lt;&#x2F;h3&gt;
&lt;p&gt;The syntax for identifiers conforms to Unicode 6.2.0 &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.unicode.org&#x2F;reports&#x2F;tr31&#x2F;&quot;&gt;UAX31-C1&lt;&#x2F;a&gt; revision 17. This essentially means that anything that could be considered a sensible identifier in any language is recognized as such.&lt;&#x2F;p&gt;
&lt;p&gt;In addition to these identifiers there are symbol identifiers such as &lt;code&gt;+&lt;&#x2F;code&gt; or &lt;code&gt;≥&lt;&#x2F;code&gt;. These are defined by the Unicode &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.unicode.org&#x2F;reports&#x2F;tr31&#x2F;#Pattern_Syntax&quot;&gt;Pattern Syntax&lt;&#x2F;a&gt;. The parser will consider them identifier on their own, so &lt;code&gt;ab+cd&lt;&#x2F;code&gt; is a sequence of three identifiers: &lt;code&gt;ab&lt;&#x2F;code&gt;, &lt;code&gt;+&lt;&#x2F;code&gt; and &lt;code&gt;bc&lt;&#x2F;code&gt;. Currently the parser treats &lt;code&gt;+&lt;&#x2F;code&gt; and other symbolic identifiers as any identifier.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;: have some sort of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Infix_notation&quot;&gt;infix notation&lt;&#x2F;a&gt; parsing.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;statements&quot;&gt;Statements&lt;&#x2F;h3&gt;
&lt;p&gt;The language consists of a list of statements, each followed by a newline (or more precisely, a paragraph separator). Statements are of the general form:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;outbound₁ outbound₂ … statement_kind inbound₁ inbound₂ …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where &lt;code&gt;outbound&lt;&#x2F;code&gt; are identifiers and &lt;code&gt;inbound&lt;&#x2F;code&gt; can be both identifiers, literals and expressions. The &lt;code&gt;statement_kind&lt;&#x2F;code&gt; is one of six specific symbols:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;≔&lt;&#x2F;code&gt; call&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;↦&lt;&#x2F;code&gt; closure&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;∵&lt;&#x2F;code&gt; because&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;∴&lt;&#x2F;code&gt; therefore&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;⊨&lt;&#x2F;code&gt; axiom&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;⊢&lt;&#x2F;code&gt; proofs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These are discussed further down. Since these are keywords, they are excluded from the list of usable identifier symbols. They are the only keywords in the language.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;string-literals&quot;&gt;String literals&lt;&#x2F;h3&gt;
&lt;p&gt;String literals start with a double opening quote (&lt;code&gt;“&lt;&#x2F;code&gt;, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;2009&#x2F;index.htm&quot;&gt;U+201C&lt;&#x2F;a&gt;) and are closed with a double closing quote (&lt;code&gt;”&lt;&#x2F;code&gt;,  &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;2009&#x2F;index.htm&quot;&gt;U+201D&lt;&#x2F;a&gt;). Note that the dumb symmetrical typewriter quotes &lt;code&gt;&quot;&lt;&#x2F;code&gt; you find on your keyboard have no role.&lt;&#x2F;p&gt;
&lt;p&gt;The parser keeps track of the number of open quotes &lt;em&gt;within&lt;&#x2F;em&gt; the literal and only stops the literal when the opening double quote is closed. This has the advantage that to quote a piece of code, you simply enclose it in double quotes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hello_world_source ↦ “&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	hello_world ↦ “Hello, World!”&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;”&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are no escape sequences or ‘here-doc’ syntax. Any Unicode text that has balanced double quotes can be turned into a valid string literal by quoting it. This is basically any sensible string. Strings with unbalanced double quotes can not be literals. They can be create it programmatically.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;numeric-constants&quot;&gt;Numeric constants&lt;&#x2F;h3&gt;
&lt;p&gt;Numeric constants are written with &lt;em&gt;mantissa&lt;&#x2F;em&gt;, optional &lt;em&gt;base&lt;&#x2F;em&gt; and optional signed &lt;em&gt;exponent&lt;&#x2F;em&gt;. If no base is specified it is assumed decimal.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;57 885 161&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5F3759DF₁₆&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;10 0110 0110 0101₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1₂⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6.626 069 57₁₀⁻³⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The mantissa digits are taken from &lt;code&gt;0&lt;&#x2F;code&gt;—&lt;code&gt;9&lt;&#x2F;code&gt; and &lt;code&gt;A&lt;&#x2F;code&gt;—&lt;code&gt;Z&lt;&#x2F;code&gt; (uppercase, because Unicode does not recognize &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Lowercase_digits&quot;&gt;lowercase digits&lt;&#x2F;a&gt;). This means the maximum base is 36.
The radix point is given by a full stop dot (&lt;code&gt;.&lt;&#x2F;code&gt;, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;002e&#x2F;index.htm&quot;&gt;U+002E&lt;&#x2F;a&gt;).
Thin spaces (&lt;code&gt; &lt;&#x2F;code&gt;, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;2009&#x2F;index.htm&quot;&gt;U+2009&lt;&#x2F;a&gt;) can be used to group digits in the mantissa.&lt;&#x2F;p&gt;
&lt;p&gt;The base and exponent are written in decimal using &lt;code&gt;₀&lt;&#x2F;code&gt;—&lt;code&gt;₉&lt;&#x2F;code&gt; and &lt;code&gt;⁰&lt;&#x2F;code&gt;—&lt;code&gt;⁹&lt;&#x2F;code&gt; respectively. The exponent can have optional signs &lt;code&gt;⁺&lt;&#x2F;code&gt; or &lt;code&gt;⁻&lt;&#x2F;code&gt;. Unicode codepoints &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;2080&#x2F;index.htm&quot;&gt;U+2080&lt;&#x2F;a&gt;—&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;2089&#x2F;index.htm&quot;&gt;U+2089&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;2070&#x2F;index.htm&quot;&gt;U+2070&lt;&#x2F;a&gt;—&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;2079&#x2F;index.htm&quot;&gt;U+2079&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;207A&#x2F;index.htm&quot;&gt;U+207A&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;207B&#x2F;index.htm&quot;&gt;U+207B&lt;&#x2F;a&gt; respectively.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scoped-statements-advanced&quot;&gt;Scoped statements (advanced)&lt;&#x2F;h3&gt;
&lt;p&gt;Statements can be scoped by&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;scoping_statement₁&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	statement₁&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	statement₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	scoping_statement₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		statement₃&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		statement₄&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			⋱&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	statement₅&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	⋮&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scope_resolution_operator&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;… (out₁ · out₃  … statement_kind (a ↦ b) in₂ …) (≔ f out₃) out₁ …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;… dummy d2 out₁ …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	out₁ dummy out₃  … statement_kind tmp in₂ …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		tmp a ↦ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	d2 ≔ f out₃&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;func out₁ out₂ ↦ in₁ in₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&amp;lt;body&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;→func&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;func out₁ out₂ ↦ in₁ in₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	→out₁&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	→out₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&amp;lt;body&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	←in₁&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	←in₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;out₁ out₂ ≔ func in₁ in₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&amp;lt;body&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;out₁ out₂ ≔ func in₁ in₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&amp;lt;body&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	←func&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	←in₁&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	←in₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;→out₁&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;→out₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;If statement_kind₁ is a ↦, out₁ is visible to the root scope, all are visible
in the nested scope. in₁ and in₂ are resolved at the end of the nested scope.&lt;&#x2F;li&gt;
&lt;li&gt;If statement_kind₁ is a ≔, out₁ is visible to the root scope&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Resolution:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Look up in the scope&lt;&#x2F;li&gt;
&lt;li&gt;Look down in the scope&lt;&#x2F;li&gt;
&lt;li&gt;Go up one scope&lt;&#x2F;li&gt;
&lt;li&gt;Repeat&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;inline-statements-advanced&quot;&gt;Inline statements (advanced)&lt;&#x2F;h3&gt;
&lt;p&gt;A statement enclosed in parentheses can be used in place of an inbound. The syntax is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;… (out₁ · out₃  … statement_kind in₁ in₂ …) …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where the middle dot (&lt;code&gt;·&lt;&#x2F;code&gt;, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;b7&#x2F;index.htm&quot;&gt;U+00B7&lt;&#x2F;a&gt;) is used as a placeholder to specify which inbound or outbound represents the expression in the parent expression.&lt;&#x2F;p&gt;
&lt;p&gt;If there is no middle dot, then it is implicitly prepended, so&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;… (out₂ … statement_kind in₁ in₂ …) …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;is equivalent to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;… (· out₂ … statement_kind in₁ in₂ …) …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the purposes of binding identifiers, the inline statement is considered to be in the scope of the parent statement.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;binding-rules-advanced&quot;&gt;Binding rules (advanced)&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;To be written&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Generally tries to be intuitive, with both forward and backward searching.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;syntax-extensions-proposal&quot;&gt;Syntax extensions (proposal)&lt;&#x2F;h3&gt;
&lt;p&gt;Similar to Coq&#x27;s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;coq.inria.fr&#x2F;refman&#x2F;Reference-Manual014.html&quot;&gt;Notation mechanism&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[ (x) , … , (y) ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;is parsed as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₁ s₂ x s₃ s₄ … s₄ s₂ y s₃ s₅&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;with&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₁ → [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₂ → (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₃ → )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₄ → ,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₅ → ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Expressions of length 0 … n are parsed as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₁ s₅&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₁ s₂ x₁ s₃ s₅&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₁ s₂ x₁ s₃ s₄ s₂ x₂ s₃ s₅&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;s₁ s₂ x₁ s₃ s₄ s₂ x₂ s₃ s₄ s₂ x₃ s₃ s₅&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;⋮&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A substitution can be defined as&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(≔ cons x … (≔ cons y nil) … )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Todo&lt;&#x2F;strong&gt;: Remove &lt;code&gt;( · ≔ )&lt;&#x2F;code&gt; and &lt;code&gt;( · ↦ )&lt;&#x2F;code&gt; notation from the formal language and reimplemented it as a notation extension.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;( o₂ … oᵢ ≔ f i₁ … iᵢ )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which is to be replaced by &lt;code&gt;t&lt;&#x2F;code&gt; and the following statement added:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;t o₂ … oᵢ ≔ f i₁ … iᵢ&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The case for &lt;code&gt;↦&lt;&#x2F;code&gt; is equivalent. If we can capture &lt;code&gt;≔&lt;&#x2F;code&gt; and &lt;code&gt;↦&lt;&#x2F;code&gt; in a variable we can even do it like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;( x₂ … xᵢ )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to be replaced by &lt;code&gt;t&lt;&#x2F;code&gt; with the following statement added:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;t x₂ … xᵢ&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And similarly for the variation with &lt;code&gt;·&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;( x₁ … xᵢ · y₁ … y₂ )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x₁ … xᵢ t y₁ … y₂&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This version neatly captures the variation where an incoming variable is captured.&lt;&#x2F;p&gt;
&lt;p&gt;While this is already quite powerful, likely enough to define a . Al these examples replace a pattern by a single temporary variable. Is there a use-case for patterns that get replaced&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ideas&quot;&gt;Ideas&lt;&#x2F;h2&gt;
&lt;p&gt;Things to express:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Yoneda_lemma#The_Yoneda_embedding&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Continuation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Delimited_continuation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;http:&#x2F;&#x2F;citeseerx.ist.psu.edu&#x2F;viewdoc&#x2F;download?doi=10.1.1.41.125&amp;amp;rep=rep1&amp;amp;type=pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;programming-language&quot;&gt;Programming language&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;call-statement&quot;&gt;Call statement&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;return₁ return₂ … ≔ function argument₁ argument₂ …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The call statement calls the function in inbound position one with the remaining inbounds as arguments. The return values are assigned to the outbounds.&lt;&#x2F;p&gt;
&lt;p&gt;If the arity of the closure mismatches the call, the arguments and retun values are padded with &lt;code&gt;(↦)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;closure-statement&quot;&gt;Closure statement&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function argument₁ argument₂ … ↦ return₁ return₂ …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The closure statement is perfectly symmetrical to the call statement. Now, the function and it&#x27;s arguments are outbound and the return values are inbound.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;on-eagerness&quot;&gt;On eagerness&lt;&#x2F;h3&gt;
&lt;p&gt;The language is eager&lt;&#x2F;p&gt;
&lt;h2 id=&quot;object-oriented-programming-and-other-conventions&quot;&gt;Object oriented programming and other conventions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mogensen%E2%80%93Scott_encoding&quot;&gt;Scott encoding&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;proof-language&quot;&gt;Proof language&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;To be written&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;because-pre-conditions&quot;&gt;Because (pre-conditions)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∵ proposition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;therefore-post-conditions&quot;&gt;Therefore (post-conditions)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∴ proposition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;axiom&quot;&gt;Axiom&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;⊨ proposition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;proofs-assertions&quot;&gt;Proofs (assertions)&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;⊢ proposition&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;C++11 (Clang)&lt;&#x2F;li&gt;
&lt;li&gt;Queχ (only if you regenerate the parser)&lt;&#x2F;li&gt;
&lt;li&gt;LLVM (MCJIT)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The Queχ based parser produces an abstract syntax tree (AST). The binder then binds all the identifiers in the AST. From this the program data flow graph (DFG) is created. The DFG is the natural representation of the program and is where static verification and optimizations like constant propagation happen.&lt;&#x2F;p&gt;
&lt;p&gt;From this DFG the (nested) closures are extracted and lambda lifted. The lifted closures are then serialized and converted to a simple stack machine language. The stack machine language is compiled to LLVM intermediate representation (IR). The IR run through optimization passes and JIT compiled to native machine code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-build-and-run&quot;&gt;How to build and run&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git clone git@github.com:Recmo&#x2F;Principia.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd Principia&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;make -j4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&#x2F;Principia Ackermann.txt PRA 3 3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;appendix-recommended-compose-bindings&quot;&gt;Appendix: Recommended compose bindings&lt;&#x2F;h2&gt;
&lt;p&gt;For programming in this Unicode heavy language I use XCompose. My compose key is &lt;code&gt;caps lock&lt;&#x2F;code&gt; which is otherwise disabled.&lt;&#x2F;p&gt;
&lt;p&gt;Symbol  Key sequence&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;↦&lt;&#x2F;code&gt;    &lt;code&gt;caps lock&lt;&#x2F;code&gt; &lt;code&gt;|&lt;&#x2F;code&gt; &lt;code&gt;→&lt;&#x2F;code&gt;
&lt;code&gt;≔&lt;&#x2F;code&gt;    &lt;code&gt;caps lock&lt;&#x2F;code&gt; &lt;code&gt;:&lt;&#x2F;code&gt; &lt;code&gt;=&lt;&#x2F;code&gt;
&lt;code&gt;·&lt;&#x2F;code&gt;    &lt;code&gt;caps lock&lt;&#x2F;code&gt; &lt;code&gt;c&lt;&#x2F;code&gt; &lt;code&gt;.&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-unicode-symmetric-pairs&quot;&gt;Appendix: Unicode symmetric pairs&lt;&#x2F;h2&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bracket&lt;&#x2F;p&gt;
&lt;p&gt;( ) [ ] { } &amp;lt; &amp;gt; ‘ ’ “ ” ⸤ ⸥ ｢ ｣ ⟦ ⟧ ⟨ ⟩ 【 】 ⟦ ⟧ ⟨ ⟩ ⟪ ⟫ ⟬ ⟭ ⟮ ⟯ ⦃ ⦄ ⦅ ⦆ ⦇ ⦈ ⦉ ⦊ ⦋ ⦌ ⦍ ⦎ ⦏ ⦐ ⦑ ⦒ ⦓ ⦔ ⦕ ⦖ ⦗ ⦘  ⌈ ⌉ ⌊ ⌋ ⌌ ⌍ ⌎ ⌏ ⌜ ⌝ ⌞ ⌟&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experiment-strict-cps&quot;&gt;Experiment: strict CPS&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;≔ function argument₁ argument₂ …&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function argument₁ argument₂ … ↦&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyth x y ↦ r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	x2 ≔ mul x x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	y2 ≔ mul y y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	r2 ≔ add x2 y2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	r ≔ sqrt r2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pyth x y r ↦&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	≔ mul x x (x2 ↦)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	≔ mul y y (y2 ↦)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	≔ add x2 y2 (r2 ↦)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	≔ sqrt r2 r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;generalized-algebraic-data-types&quot;&gt;Generalized Algebraic Data Types&lt;&#x2F;h2&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Storro Key Management</title>
        <published>2015-08-27T00:00:00+00:00</published>
        <updated>2015-08-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/15/storro/"/>
        <id>https://2π.com/15/storro/</id>
        
        <content type="html" xml:base="https://2π.com/15/storro/">&lt;h1 id=&quot;storro-key-management&quot;&gt;Storro Key Management&lt;&#x2F;h1&gt;
&lt;p&gt;Storro allows users to collaborate on projects. It creates an encrypted drive on the users devices. The drive contains a folder for each project the user has joined. Changes made to the folder distribute to the project&#x27;s other users. Every user independently validates correct operation. Storro resolves any conflicting changes without user interaction. A revision history logs all changes. All historical versions are retrievable. The integrity is cryptographically guaranteed.&lt;&#x2F;p&gt;
&lt;p&gt;A user can be in one of five different roles in a project. In monotonically increasing order of privilege they are:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Uninvited&lt;&#x2F;em&gt;: The user is not a part of the project in any way.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Facilitator&lt;&#x2F;em&gt;: The user provides backup and hosting. Other than that, there is
not even read access. The user is not able to learn anything about the
contents of the project. Not even a list of files.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Observer&lt;&#x2F;em&gt;: The user has full read-only access to the project. The user is a
passive observer and not able to make any changes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Participant&lt;&#x2F;em&gt;: The user participates in the project. The user has full write
access to the project folder. He&#x2F;she is able to create, change and remove all
files and folders.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Administrator&lt;&#x2F;em&gt;: The user administrates the project. Like a participant, he&#x2F;she
has read&#x2F;write access. Administrators can also change the project metadata.
This includes adding or removing users and changing their roles. (With one
exception: the last administrators can not remove him&#x2F;her self.)&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Storro enforces non-mutable privileges by controlling access to read-keys. It forces mutating privileges by having every participant confirm the correctness of the mutation. Storro limits storage of encrypted information to a set of allowed devices.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;license-management&quot;&gt;License Management&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LicenseCertificate:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	user: User public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	device: Device public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	kind: enum of Server Desktop Laptop Smartphone&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	validity: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature: Signature by a license authority&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LicenseService:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	refreshLicense: ∅ → LicenseCertificate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A device maintains an up-to-date &lt;code&gt;LicenseCertificate&lt;&#x2F;code&gt; object. It periodically requests a new one from a license authority. The license authority&#x27;s signature validates a license. Storro has a fixed set of license authorities, compiled into the executable. Initial authentication uses the socialist millionaire protocol on the license key. Later authentications can also use user&#x2F;device keys.&lt;&#x2F;p&gt;
&lt;p&gt;The full version of the licensing protocol contains more details about the licensee. Storro only shares these between the licensee and the license authority. The authority can hand out &lt;code&gt;LicenseCertificate&lt;&#x2F;code&gt; objects with longer or shorter validity. The validity forces peers to come online and refresh the license. The validity is a trade-off between offline functionality and revoking licenses.&lt;&#x2F;p&gt;
&lt;p&gt;Storro peers will request a valid &lt;code&gt;LicenseCertificate&lt;&#x2F;code&gt; object before they interact. An expired license will lock a user&#x2F;device out of the network. The user can continue local work. A renewed license reconnects the user. Storro then integrates the local and remote changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;distributed-content-addressed-store&quot;&gt;Distributed Content Addressed Store&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;StoreCertificate:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	projectUuid: Uuid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	users: set of public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	admins: set of public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	timestamp: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature: signature by an admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;StoreService:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	exchangeCertificate: set of StoreCertificate → set of StoreCertificate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	get: (Uuid, Hash) → (Uuid, Value)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	put: (Uuid, Value) → ∅&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	sync: Binary → Binary&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Storro stores all the projects state in a content addressed store. The stores synchronize between all users that are at least facilitator in the project. Facilitators can not decrypt anything in the store. The facilitators know who to synchronize with and who administrates this. Storro maintains an up to date &lt;code&gt;StoreCertificate&lt;&#x2F;code&gt; object for every project. This object contains the list of devices that can access it. It also contains a list of admins that can update the certificate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Exchange Certificate&lt;&#x2F;strong&gt;: When two Storro peers connect, they check which projects the other has access to. They then exchange the latest &lt;code&gt;StoreCertificate&lt;&#x2F;code&gt;s for those projects. For every certificate received, the peer verifies and updates. Only admins can sign valid certificates. The timestamp guarantees that the latest certificates eventually reach every peer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Get, Put and Sync&lt;&#x2F;strong&gt;: The store has the conventional &lt;code&gt;get&lt;&#x2F;code&gt; and &lt;code&gt;put&lt;&#x2F;code&gt; calls. Get retrieves a value based on its hash. The requester verifies correct behaviour by verifying the hash of the returned value. The &lt;code&gt;sync&lt;&#x2F;code&gt; call uses an efficient protocol to discover missing hashes between two stores. The &lt;code&gt;put&lt;&#x2F;code&gt; call is for completeness. Every store can validity it&#x27;s own integrity by checking the hashes. Observers can decrypt the contents and perform full integrity checks and garbage collection.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;version-management&quot;&gt;Version Management&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VersionCertificate:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	projectUuid: Uuid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	readKey: set of encrypted keys to Version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	timestamp: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature: signature by an observer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VersionService:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	exchangeVersions: set of VersionCertificate → set of VersionCertificate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;readKey&lt;&#x2F;code&gt; contains the keys to read the latest &lt;code&gt;Version&lt;&#x2F;code&gt; object. The certificate writer encrypts them for each user with at least observer role. Storro stores the &lt;code&gt;Version&lt;&#x2F;code&gt; object and related objects encrypted in the content addressed store:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Version:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	metadata: key to Metadata&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	previous: set of key to Version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	root: key to Directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	signature: user signature&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Directory:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	entries: set of (key to File or Director)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;File:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	contents: key to binary&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The next section describes the &lt;code&gt;Metadata&lt;&#x2F;code&gt; object. The specification leaves out details such as modification times and compression. Observers can create a new version and corresponding certificate. This new version merges updates from every other version the device is aware off. Devices with observer role have one unique latest version. Facilitators have insufficient permission to create their own versions. Facilitator will store and pass along the latest versions of other users.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;Version&lt;&#x2F;code&gt; objects satisfy invariants. They are a state-based conflict-free replicated data type with strong eventual consistency. The state is monotonically increasing. This is explicitly constructed by the &lt;code&gt;previous&lt;&#x2F;code&gt; hashes. These create a causal lattice of &lt;code&gt;Version&lt;&#x2F;code&gt; objects:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The versions form a directed acyclic graph through their &lt;code&gt;previous&lt;&#x2F;code&gt; fields, the &lt;em&gt;version graph&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The version graph has a least element, the &lt;em&gt;initial version&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The hash of the initial version is the projects &lt;em&gt;universally unique identifier&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The version graph has a greatest element, the &lt;em&gt;latest version&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Converged replicas have the same latest version.&lt;&#x2F;li&gt;
&lt;li&gt;Converged replicas have identical states.&lt;&#x2F;li&gt;
&lt;li&gt;Non-initial versions have either one parent, the &lt;em&gt;commits&lt;&#x2F;em&gt;, or more, the &lt;em&gt;merges&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The initial version has one user with the administrator role, the &lt;em&gt;founder&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The initial version is signed by the founder.&lt;&#x2F;li&gt;
&lt;li&gt;Commits differ from their previous in either the &lt;code&gt;metadata&lt;&#x2F;code&gt; or &lt;code&gt;root&lt;&#x2F;code&gt; field, not both. These are called &lt;em&gt;meta-commits&lt;&#x2F;em&gt; and &lt;em&gt;root-commits&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Root-commits are signed by user that has participant or administrator role in the previous version.&lt;&#x2F;li&gt;
&lt;li&gt;The previous versions in a merge are commits.&lt;&#x2F;li&gt;
&lt;li&gt;The previous versions in a merge are pair-wise unreachable.&lt;&#x2F;li&gt;
&lt;li&gt;Merges are a known deterministic function of their previous versions.&lt;&#x2F;li&gt;
&lt;li&gt;No two elements in a &lt;code&gt;Directory.entries&lt;&#x2F;code&gt; have the same &lt;code&gt;name&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Create Project&lt;&#x2F;strong&gt;: The founder creates a initial version that satisfies all invariants. The founder can work in the project on his device and invite other users&#x2F;devices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Exchange Versions&lt;&#x2F;strong&gt;: Two devices start with the content addressed store synchronization. Next they exchange &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt;s for the latest versions of the project. Storro peers restrict this to versions the other device is also member of. Peers validate the certificate on receipt. Facilitators can stop here. Observers proceed to construct the &lt;code&gt;Version&lt;&#x2F;code&gt; object and verify the invariants. Peers ignore invalid data. Peers integrate new data and update their &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Add Commit&lt;&#x2F;strong&gt;: The devices registers local changes to the projects directory. Storro peers store these changes as a commits in the &lt;code&gt;Version&lt;&#x2F;code&gt; history. They update their &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt; and distributed it to other devices. Devices validate the new &lt;code&gt;Version&lt;&#x2F;code&gt; on receipt. Storro rejects illegal &lt;code&gt;Version&lt;&#x2F;code&gt;s. Illegal changes will not propagate the network beyond the malicious device(s).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;user-management&quot;&gt;User Management&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Invitation:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	projectUuid:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name: String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	readKey: key to Version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	voucher: private key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	expiry: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Storro devices store the following encrypted in the content addressed store:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Metadata:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	description: string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	users: set of Credentials&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	vouchers: set of Voucher&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Credentials:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	user: user public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	role: enum of Facilitator Observer Participant Administrator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Voucher:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	key: public key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	role: enum of Facilitator Observer Participant Administrator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	expiry: DateTime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;Metadata&lt;&#x2F;code&gt; has extra invariants:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A meta-commit is signed by and administrator, a regular user or a voucher.&lt;&#x2F;li&gt;
&lt;li&gt;A regular user signed commit only affects that user and does not increase the maximal role of that users.&lt;&#x2F;li&gt;
&lt;li&gt;A voucher signed commit removes that voucher and can add one user with the role specified in the voucher.&lt;&#x2F;li&gt;
&lt;li&gt;Meta-commits have no vouchers with expiry dates before the signature date.&lt;&#x2F;li&gt;
&lt;li&gt;There is at least one administrator.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Invite User&lt;&#x2F;strong&gt;: An admin can invite a user by adding the user&#x2F;device keys to the credentials. The admin then distributes the updated &lt;code&gt;StoreCertificate&lt;&#x2F;code&gt; and &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt;. When the user&#x2F;device connects to an updated peer it can retrieve the latest version. The public keys of the user&#x2F;device are not always known in advance. In this case, the admin can create a voucher. The admin can then send the user&#x2F;device an &lt;code&gt;Invitation&lt;&#x2F;code&gt; by any secure channel. The voucher is a single-use right to create an account with a predetermined role. The user&#x2F;devices can accept the invitation by creating its own account. The user&#x2F;device can reject the invitation by making removing the voucher. This only requires retrieving the latest &lt;code&gt;Version&lt;&#x2F;code&gt; and &lt;code&gt;Metadata&lt;&#x2F;code&gt; objects.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Remove User&lt;&#x2F;strong&gt;: The admin or user&#x2F;device creates a meta-commit that removes the user&#x2F;device from the project. The device then distributes this update.  Later &lt;code&gt;VersionCertificate&lt;&#x2F;code&gt;s will not include a key for the user. Later requests to peers will fail for the removed user. The user&#x2F;device still receives the meta-commit containing its removal. This allows it to detect its removal. When removed a Storro device will remove encrypted data.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>3D Printer Log</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/3d-printer/log/"/>
        <id>https://2π.com/14/3d-printer/log/</id>
        
        <content type="html" xml:base="https://2π.com/14/3d-printer/log/">&lt;h1 id=&quot;3d-printer-log&quot;&gt;3D Printer Log&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;hardware&quot;&gt;Hardware&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;frame&quot;&gt;Frame&lt;&#x2F;h3&gt;
&lt;p&gt;RepRap Prusa i3 Rework with 6mm aluminium plate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;Prusa_i3_Rework_Introduction&quot;&gt;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;Prusa_i3_Rework_Introduction&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.thingiverse.com&#x2F;thing:119616&quot;&gt;http:&#x2F;&#x2F;www.thingiverse.com&#x2F;thing:119616&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lubricated both Z-axis to fix underpowered motor.&lt;&#x2F;li&gt;
&lt;li&gt;14-05-24 Designed and printed a power supply standoff&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.thingiverse.com&#x2F;thing:71488&quot;&gt;End stop clamps&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;extruder&quot;&gt;Extruder&lt;&#x2F;h3&gt;
&lt;p&gt;Greg’s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.reprap.org&#x2F;wiki&#x2F;Greg%27s_Hinged_Extruder&quot;&gt;Hinged Extruder&lt;&#x2F;a&gt; (
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.thingiverse.com&#x2F;thing:8252&quot;&gt;thingiverse&lt;&#x2F;a&gt; ), which is based
on Wade’s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.reprap.org&#x2F;wiki&#x2F;Wade%27s_Geared_Extruder&quot;&gt;Geared_Extruder&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A J-Head &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;J_Head_Nozzle#Mk_V-B&quot;&gt;Mk V-B&lt;&#x2F;a&gt; or &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;J_Head_Nozzle#Mk_V-BV&quot;&gt;Mk V-BV&lt;&#x2F;a&gt; with a 100k thermisistor.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;electronics&quot;&gt;Electronics&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;Sanguinololu&quot;&gt;Sanguinololu&lt;&#x2F;a&gt;, a
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sanguino.cc&#x2F;&quot;&gt;Sanguino&lt;&#x2F;a&gt; based Arduino clone with with four
sockets for &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;Pololu_stepper_driver_board&quot;&gt;Pololu stepper motor
controlers&lt;&#x2F;a&gt;. Based
on an Atmega644P, can be upgraded to Atmega128.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Z-axis (dual NEMA17) pololu died and was replaced by &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.dx.com&#x2F;p&#x2F;a4988-3d-printer-reprap-stepper-motor-driver-green-260021&quot;&gt;this one&lt;&#x2F;a&gt; with heat sink.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;14-05-25: TODO: Check Y-axis stepper power, it skips&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;wiring-plan&quot;&gt;Wiring plan&lt;&#x2F;h3&gt;
&lt;p&gt;14-05-24&lt;&#x2F;p&gt;
&lt;h3 id=&quot;spool-holder&quot;&gt;Spool holder&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.thingiverse.com&#x2F;thing:60720&quot;&gt;Holder&lt;&#x2F;a&gt; with &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.thingiverse.com&#x2F;thing:60723&quot;&gt;spool adapter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Added on 14-05-24&lt;&#x2F;p&gt;
&lt;h2 id=&quot;firmware&quot;&gt;Firmware&lt;&#x2F;h2&gt;
&lt;p&gt;Sprinter&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;Sprinter&quot;&gt;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;Sprinter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kliment&#x2F;Sprinter&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;kliment&#x2F;Sprinter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Changes made to Configuration.h.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; MOTHERBOARD&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 62&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; _AXIS_STEP_PER_UNIT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 75&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;200&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 16&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 700&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; .9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; BAUDRATE&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 250000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; INVERT_Y_DIR &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; INVERT_Z_DIR &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; INVERT_E_DIR &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; X_MAX_LENGTH &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 182&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Y_MAX_LENGTH &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 219&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Z_MAX_LENGTH &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;uploading&quot;&gt;Uploading&lt;&#x2F;h3&gt;
&lt;p&gt;Use stock Arduino v1.0.5 with
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;sanguino&#x2F;downloads&#x2F;list&quot;&gt;sanguino&lt;&#x2F;a&gt; hardware
plugin.&lt;&#x2F;p&gt;
&lt;p&gt;Note: disconnect and reconnect USB before uploading!&lt;&#x2F;p&gt;
&lt;p&gt;Choose &quot;Sanguino Atmega644P&quot; as compile target&lt;&#x2F;p&gt;
&lt;h2 id=&quot;software&quot;&gt;Software&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.openscad.org&#x2F;&quot;&gt;OpenSCAD&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;freecadweb.org&#x2F;&quot;&gt;FreeCAD&lt;&#x2F;a&gt; for modeling.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;slic3r.org&#x2F;&quot;&gt;Slic3r&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.reprap.org&#x2F;wiki&#x2F;Slic3r&quot;&gt;RepRap wiki&lt;&#x2F;a&gt;) for slicing.&lt;&#x2F;p&gt;
&lt;p&gt;TODO: List slic3r settings.&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Check out Cura: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;daid&#x2F;Cura&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;daid&#x2F;Cura&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kliment&#x2F;Printrun&quot;&gt;Printrun&lt;&#x2F;a&gt; (&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.reprap.org&#x2F;wiki&#x2F;Printrun&quot;&gt;RepRap wiki&lt;&#x2F;a&gt;) its &lt;code&gt;pronterface&lt;&#x2F;code&gt; for
printing.&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Check out &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.repetier.com&#x2F;documentation&#x2F;repetier-host&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.repetier.com&#x2F;documentation&#x2F;repetier-host&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;calibration&quot;&gt;Calibration&lt;&#x2F;h2&gt;
&lt;p&gt;The Y-Axis has its bed minimum at 19 and the bed maximum at 219&lt;&#x2F;p&gt;
&lt;p&gt;The X-Axis has its bed minimum at 17 and the mech max at 182.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;log-2015-09-13&quot;&gt;Log 2015-09-13&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;Goal&lt;&#x2F;em&gt;: Fix the leaking of molten PLA between the brass nozzle and the PEEK
insulator.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Method&lt;&#x2F;em&gt;: The extruder was heated to 200°C and run in reverse until the filament
came out. I then cooled down the extruder and removed it from the frame. Then
the J-Head nozzle assembly was removed from the extruder assembly. I heated up
the head to 200°C and used pliers to twisted off the PEEK insulator, which came
off smoothly.&lt;&#x2F;p&gt;
&lt;p&gt;The PTFE liner looked to short. The PEEK insulator with the PTFE liner and was
heated in an oven at 200°C. This loosened the liner so it could be pushed
through the insulator, clearing out some black (ABS?) gunk along the way. This
was repeated several times until no more gunk remained.&lt;&#x2F;p&gt;
&lt;p&gt;The insulator was re-assembled with the liner as low as it could be placed and
not screwed down. The nozzle thread was wrapped in several layers of PTFE tape.
I then screwed the nozzle back on the insulator, pushing the liner up slightly
and squashing the PTFE tape. It was screwed down quite tight. The liner was
screwed down thight from the other end of the PEEK. The extruder was
re-assembled and put back on the frame.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Result&lt;&#x2F;em&gt;: The first print (25mm companion cube with 20% infill). The first ten
layers had significant amounts of black gunk. After that there was an occasional
clog followed by a small piece of gunk. The extruder never leaked.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Conclusion&lt;&#x2F;em&gt;: The leaking issue is solved, there may still be some gunk left
that will flush out.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;log-2015-09-15&quot;&gt;Log 2015-09-15&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;Goal&lt;&#x2F;em&gt;: Recalibrate the printer, in particular the extruder.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Method&lt;&#x2F;em&gt;: Using &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;Triffid_Hunter&amp;#x27;s_Calibration_Guide&quot;&gt;Triffid&#x27;s guider&lt;&#x2F;a&gt;.
The firmware was already at the latest version. The current calibration is:&lt;&#x2F;p&gt;
&lt;p&gt;Axis   Steps per millimetre&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;X      80
Y      75
Z      4000
E      630&lt;&#x2F;p&gt;
&lt;p&gt;The Y axis has a slight tweak. This was originally done because the belt gear had
it&#x27;s teeth filled with plastic, making the effective diameter slightly larger.
This was compensated for by giving the Y axis a tweak. This gear has now been
replaced by a newly printed one and the tweak should be removed.&lt;&#x2F;p&gt;
&lt;p&gt;The X, Y and Z axis use timer belts and stepper motors. For the X and Z it is
a NEMA 17 motor with T2 belt and 20-tooth pulley, the exact steps per millimetre
should be 80. The Z axis is NEMA 17 with standard pitch M5 threaded rod, which
has exactly 4000 steps per millimetre.&lt;&#x2F;p&gt;
&lt;p&gt;The E axis is currently at 630 steps per millimetre. A mark was made on the
filament at the height of top of the frame. The nozzle is heated to 195°C and
the command was given to extrude 50.0mm at 100.0 mm&#x2F;min. A new mark was made at
the same height. The distance between the marks is 45.5 mm ± 1 mm. The corrected
E steps per mm would therefore be &lt;span class=&quot;math math-inline&quot;&gt;630 · \frac{50}{45.5} = 694&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Based on this, the new calibration should be:&lt;&#x2F;p&gt;
&lt;p&gt;Axis   Steps per millimetre&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;X      80
Y      80
Z      4000
E      694&lt;&#x2F;p&gt;
&lt;p&gt;The firmware was updated in &lt;code&gt;Sprinter&#x2F;Configuration.h&lt;&#x2F;code&gt;, compiled and uploaded:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; _AXIS_STEP_PER_UNIT&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 694&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The filament is measured at 2.8 mm. The filament settings in Slic3r are updated
to 2.8 mm and 1.0 as multiplier. Now the steps in &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;reprap.org&#x2F;wiki&#x2F;Triffid_Hunter&amp;#x27;s_Calibration_Guide#E_Steps_Fine_Tuning&quot;&gt;E step fine tuning&lt;&#x2F;a&gt;
are followed.&lt;&#x2F;p&gt;
&lt;p&gt;The first print had the brim being to thin, the Z offset was increased from 0
to .1 mm. The second print had a good brim but came loose due to wrapping. The
temperatures were changed as follows:&lt;&#x2F;p&gt;
&lt;p&gt;Temperature      Previous     New&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Nozzle initial     200 °C   190°C
Nozzle             190 °C   185°C
Bed initial         65 °C    60°C
Bed                  0 °C    60°C&lt;&#x2F;p&gt;
&lt;p&gt;The third print came out okay. The infill has holes, but the top fills are not
solid.&lt;&#x2F;p&gt;
&lt;p&gt;The nozzle gets stuck, increasing temperature:&lt;&#x2F;p&gt;
&lt;p&gt;Temperature      Previous     New&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Nozzle initial     200 °C   195°C
Nozzle             190 °C   190°C
Bed initial         65 °C    60°C
Bed                  0 °C    60°C&lt;&#x2F;p&gt;
&lt;p&gt;Wraps and does not stick, increasing temperature:&lt;&#x2F;p&gt;
&lt;p&gt;Temperature      Previous     New&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Nozzle initial     200 °C   200°C
Nozzle             190 °C   195°C
Bed initial         65 °C    70°C
Bed                  0 °C    65°C&lt;&#x2F;p&gt;
&lt;p&gt;Communication breakdown, decreasing baudrate to 115200. Object still warped and
came loose.&lt;&#x2F;p&gt;
&lt;p&gt;According to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.matterhackers.com&#x2F;articles&#x2F;how-to-succeed-when-printing-in-pla&quot;&gt;http:&#x2F;&#x2F;www.matterhackers.com&#x2F;articles&#x2F;how-to-succeed-when-printing-in-pla&lt;&#x2F;a&gt;
the bed should be 70°C. After much experimentation the cause was found to be a
too low Z offset. The final settings are:&lt;&#x2F;p&gt;
&lt;p&gt;Setting            Value&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Layer height      0.3 mm
First layer      0.35 mm
Infill              20 %
Nozzle initial     200°C
Nozzle             200°C
Bed initial         75°C
Bed                 70°C
Skirt            2 loops
Brim               15 mm
Z offset         0.45 mm
Filament          2.8 mm
Multiplier          1.05&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Extrusion calibration&lt;&#x2F;strong&gt;: The extrusion is re-calibrated. A 50 mm extrusion
delivered 45.5 mm. Perhaps the firmware did not update. The firmware is
recompiled and reflashed. Support for the &lt;code&gt;M503&lt;&#x2F;code&gt; command is added and the
printer now responds to it. A 50 mm extrusion delivered 46.5 mm. E was extended
from 694 to 746. The extruder got stuck. The hobbed bolt was full of plastic and
cleared. The spool holder was loosened.&lt;&#x2F;p&gt;
&lt;p&gt;772    51.6
745    41.0
745    49.0&lt;&#x2F;p&gt;
&lt;p&gt;It is left at the current firmware default of 746. The extrusion is remains
inaccurate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;todo&quot;&gt;TODO&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Replace the extruder gears by herringbone gears: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.thingiverse.com&#x2F;thing:172514&quot;&gt;http:&#x2F;&#x2F;www.thingiverse.com&#x2F;thing:172514&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Print new&#x2F;spare end-stop clamps&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Print a fan construction.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Algebraic attacks on BitCoin</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/algebraic-bitcoin/algebraic-bitcoin/"/>
        <id>https://2π.com/14/algebraic-bitcoin/algebraic-bitcoin/</id>
        
        <content type="html" xml:base="https://2π.com/14/algebraic-bitcoin/algebraic-bitcoin/">&lt;h1 id=&quot;algebraic-attacks-on-bitcoin&quot;&gt;Algebraic attacks on BitCoin&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;algebraic-bitcoin&#x2F;algebraic-bitcoin&#x2F;cnfgen&quot;&gt;cnfgen&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;algebraic-bitcoin&#x2F;algebraic-bitcoin&#x2F;results&quot;&gt;results&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;algebraic-bitcoin&#x2F;algebraic-bitcoin&#x2F;generating-cnf&quot;&gt;generating-cnf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bitcoin-proof-of-work&quot;&gt;BitCoin proof of work&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Block header&lt;&#x2F;p&gt;
&lt;p&gt;Size  Field&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;4 bytes  Version
32 bytes  hashPrevBlock
32 bytes  hashMerkleRoot
4 bytes  Time
4 bytes  Difficulty
4 bytes  Nonce&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; block_header&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;    version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;         &#x2F;&#x2F;  32 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned char&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;   prev_block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  &#x2F;&#x2F; 256 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned char&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;   merkle_root&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; 256 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;    timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       &#x2F;&#x2F;  32 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;    bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F;  32 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;    nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;           &#x2F;&#x2F;  32 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Whenever Nonce overflows (which it does frequently), the extraNonce
portion of the generation transaction is incremented, which changes the
Merkle root.&lt;&#x2F;p&gt;
&lt;p&gt;The block hash is&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;block_header&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The block header is 640 bits of which the last 32 bit can change.&lt;&#x2F;p&gt;
&lt;p&gt;In SHA256 preprocessing the message is split in two chunks.&lt;&#x2F;p&gt;
&lt;p&gt;First chunk 512 bits containing only fixed content.&lt;&#x2F;p&gt;
&lt;p&gt;Second chunk 128 bits + 1 x one + 319 x zero + 0x0000000000000280.&lt;&#x2F;p&gt;
&lt;p&gt;The nonce are bits 96..127 in the second chunk, mapping to w[3] in
sha256.&lt;&#x2F;p&gt;
&lt;p&gt;Result is 256 bit hash.&lt;&#x2F;p&gt;
&lt;p&gt;Second hash only has one chunk: 256 bit hash1 + 1 x one + 191 x zero +
0x0000000000000100&lt;&#x2F;p&gt;
&lt;p&gt;The block header is 640 bits of which the last 32 bit can change.&lt;&#x2F;p&gt;
&lt;p&gt;In SHA256 preprocessing the message is split in two chunks.&lt;&#x2F;p&gt;
&lt;p&gt;First chunk 512 bits containing only fixed content.&lt;&#x2F;p&gt;
&lt;p&gt;Second chunk 128 bits + 1 x one + 319 x zero + 0x0000000000000280.&lt;&#x2F;p&gt;
&lt;p&gt;The nonce are bits 96..127 in the second chunk, mapping to w[3] in
sha256.&lt;&#x2F;p&gt;
&lt;p&gt;Result is 256 bit hash.&lt;&#x2F;p&gt;
&lt;p&gt;Second hash only has one chunk: 256 bit hash1 + 1 x one + 191 x zero +
0x0000000000000100&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;algebraic-bitcoin&#x2F;algebraic-bitcoin&#x2F;cnfgen.py&quot;&gt;cnfgen.py&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CNF generator in Python</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/algebraic-bitcoin/cnfgen/"/>
        <id>https://2π.com/14/algebraic-bitcoin/cnfgen/</id>
        
        <content type="html" xml:base="https://2π.com/14/algebraic-bitcoin/cnfgen/">&lt;h1 id=&quot;cnf-generator-in-python&quot;&gt;CNF generator in Python&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;algebraic-bitcoin&#x2F;cnfgen&#x2F;cnfgen.py&quot;&gt;cnfgen.py&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Generating CNF</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/algebraic-bitcoin/generating-cnf/"/>
        <id>https://2π.com/14/algebraic-bitcoin/generating-cnf/</id>
        
        <content type="html" xml:base="https://2π.com/14/algebraic-bitcoin/generating-cnf/">&lt;h1 id=&quot;generating-cnf&quot;&gt;Generating CNF&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;msoos&#x2F;cryptominisat&#x2F;&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;msoos&#x2F;cryptominisat&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-usage&quot;&gt;Example usage&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; vec_from_hex&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;01000000&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0000000000000000&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;533bff42&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;1900db99&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;________&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; sha256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; rounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; sha256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; rounds&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;vec_equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:],&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; vec_const&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;cnf_solve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;features&quot;&gt;Features&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;sat-solving&quot;&gt;SAT solving&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Special argument detection (&lt;code&gt;cnf_is_special&lt;&#x2F;code&gt;)
&lt;ul&gt;
&lt;li&gt;One of the arguments is constant&lt;&#x2F;li&gt;
&lt;li&gt;Some arguments are identical or negatives&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;boolean-circuits&quot;&gt;Boolean circuits&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Simple boolean operations (&lt;code&gt;cir_and&lt;&#x2F;code&gt;, &lt;code&gt;cir_nand&lt;&#x2F;code&gt;, &lt;code&gt;cir_or&lt;&#x2F;code&gt;, &lt;code&gt;cir_nor&lt;&#x2F;code&gt;)
&lt;ul&gt;
&lt;li&gt;Take a variable number of arguments&lt;&#x2F;li&gt;
&lt;li&gt;Constant propagation False ∧ ⋯ → False&lt;&#x2F;li&gt;
&lt;li&gt;Recognize cases such as A ∧ ¬A ∧ ⋯ → False&lt;&#x2F;li&gt;
&lt;li&gt;Reduce redundant clauses B ∧ B ∧ ⋯ → B ∧ ⋯&lt;&#x2F;li&gt;
&lt;li&gt;Zero overhead when given just one argument&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Complex boolean operations (&lt;code&gt;cir_xor&lt;&#x2F;code&gt;, &lt;code&gt;cir_xnor&lt;&#x2F;code&gt;)
&lt;ul&gt;
&lt;li&gt;Reduce redundant clauses A ⊕ A ⊕ A → A&lt;&#x2F;li&gt;
&lt;li&gt;Reduce redundant clauses A ⊕ ¬A ⊕ ⋯ → True&lt;&#x2F;li&gt;
&lt;li&gt;Propagate constants A ⊕ True → ¬A&lt;&#x2F;li&gt;
&lt;li&gt;No temporary variables introduced, but exponential in the number of arguments&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Full-adder (&lt;code&gt;cir_full_adder&lt;&#x2F;code&gt;)
&lt;ul&gt;
&lt;li&gt;Optimal circuit without temporary variables in common case&lt;&#x2F;li&gt;
&lt;li&gt;Fall-back to Tseitin circuit when arguments are special for better constant propagation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;bit-vectors&quot;&gt;Bit vectors&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Bitvectors from hexadecimal (&lt;code&gt;vec_from_hex&lt;&#x2F;code&gt;)
&lt;ul&gt;
&lt;li&gt;Unlimited length hexadecimal constants, with:&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;_&lt;&#x2F;code&gt; meaning a free nibble, to be solved for&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;x&lt;&#x2F;code&gt; meaning a random nibble&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;integers&quot;&gt;Integers&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Operations on Bitvectors (&lt;code&gt;vec_and&lt;&#x2F;code&gt;, &lt;code&gt;vec_xor&lt;&#x2F;code&gt;, etc..)&lt;&#x2F;li&gt;
&lt;li&gt;Addition of bitvector (&lt;code&gt;vec_add&lt;&#x2F;code&gt;) **&lt;&#x2F;li&gt;
&lt;li&gt;Add do not calculate carry on last bit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;crypto&quot;&gt;Crypto&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;algebraic-bitcoin&#x2F;generating-cnf&#x2F;cnfgen.py&quot;&gt;Full source code&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Algebraic attacks on BitCoin</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/algebraic-bitcoin/results/"/>
        <id>https://2π.com/14/algebraic-bitcoin/results/</id>
        
        <content type="html" xml:base="https://2π.com/14/algebraic-bitcoin/results/">&lt;h1 id=&quot;algebraic-attacks-on-bitcoin&quot;&gt;Algebraic attacks on BitCoin&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;bitcoin-proof-of-work&quot;&gt;BitCoin proof of work&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Block header&lt;&#x2F;p&gt;
&lt;p&gt;Size  Field&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;4 bytes  Version
32 bytes  hashPrevBlock
32 bytes  hashMerkleRoot
4 bytes  Time
4 bytes  Difficulty
4 bytes  Nonce&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; block_header&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;    version&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;         &#x2F;&#x2F;  32 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned char&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;   prev_block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  &#x2F;&#x2F; 256 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned char&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;   merkle_root&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; 256 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;    timestamp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       &#x2F;&#x2F;  32 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;    bits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;            &#x2F;&#x2F;  32 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;    nonce&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;           &#x2F;&#x2F;  32 bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Whenever Nonce overflows (which it does frequently), the extraNonce
portion of the generation transaction is incremented, which changes the
Merkle root.&lt;&#x2F;p&gt;
&lt;p&gt;The block hash is&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SHA256&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;block_header&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The block header is 640 bits of which the last 32 bit can change.&lt;&#x2F;p&gt;
&lt;p&gt;In SHA256 preprocessing the message is split in two chunks.&lt;&#x2F;p&gt;
&lt;p&gt;First chunk 512 bits containing only fixed content.&lt;&#x2F;p&gt;
&lt;p&gt;Second chunk 128 bits + 1 x one + 319 x zero + 0x0000000000000280.&lt;&#x2F;p&gt;
&lt;p&gt;The nonce are bits 96..127 in the second chunk, mapping to w[3] in
sha256.&lt;&#x2F;p&gt;
&lt;p&gt;Result is 256 bit hash.&lt;&#x2F;p&gt;
&lt;p&gt;Second hash only has one chunk: 256 bit hash1 + 1 x one + 191 x zero +
0x0000000000000100&lt;&#x2F;p&gt;
&lt;p&gt;The block header is 640 bits of which the last 32 bit can change.&lt;&#x2F;p&gt;
&lt;p&gt;In SHA256 preprocessing the message is split in two chunks.&lt;&#x2F;p&gt;
&lt;p&gt;First chunk 512 bits containing only fixed content.&lt;&#x2F;p&gt;
&lt;p&gt;Second chunk 128 bits + 1 x one + 319 x zero + 0x0000000000000280.&lt;&#x2F;p&gt;
&lt;p&gt;The nonce are bits 96..127 in the second chunk, mapping to w[3] in
sha256.&lt;&#x2F;p&gt;
&lt;p&gt;Result is 256 bit hash.&lt;&#x2F;p&gt;
&lt;p&gt;Second hash only has one chunk: 256 bit hash1 + 1 x one + 191 x zero +
0x0000000000000100&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;algebraic-bitcoin&#x2F;results&#x2F;cnfgen.py&quot;&gt;cnfgen.py&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Entropy Pool</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/entropy-pool/entropy-pool/"/>
        <id>https://2π.com/14/entropy-pool/entropy-pool/</id>
        
        <content type="html" xml:base="https://2π.com/14/entropy-pool/entropy-pool/">&lt;h1 id=&quot;entropy-pool&quot;&gt;Entropy Pool&lt;&#x2F;h1&gt;
&lt;p&gt;Random number generation is an underestimate challenge in any
cryptographic system. You need it for generating keys and nonces, and
often the security of the entire system depends on it.&lt;&#x2F;p&gt;
&lt;p&gt;For example, Blockchain.info’s late 2014 &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.blockchain.com&#x2F;2014&#x2F;12&#x2F;08&#x2F;blockchain-info-security-disclosure&#x2F;&quot;&gt;security
breach&lt;&#x2F;a&gt;
is caused by using non-random nonces. Even though the breach was fixed
in two and a half hours, it still led to the bitcoins of hunderds of
addresses being stolen. Similarly a lot of Mobile wallets &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;android-developers.blogspot.co.il&#x2F;2013&#x2F;08&#x2F;some-securerandom-thoughts.html&quot;&gt;got
robbed&lt;&#x2F;a&gt;
and the Sony Playstation 3 &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.mydigitallife.info&#x2F;sony-ps3-private-root-keys-leaked-with-demo-homebrew-download&#x2F;&quot;&gt;root
key&lt;&#x2F;a&gt;
got stolen because non-random nonces.&lt;&#x2F;p&gt;
&lt;p&gt;Whenever possible, it’s best to avoid using random numbers altogether.
For example in the digital signature algorithm, instead of using a
random nonce, you can use a hash of the message. This won’t loose you
any security and has been promoted by &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;tools.ietf.org&#x2F;rfc&#x2F;rfc6979.txt&quot;&gt;RFC
6979&lt;&#x2F;a&gt;. If Blockchain and Sony had
implemented this recommendation, there would have never been a breach.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;overall-design&quot;&gt;Overall design&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Entropy sources: These are streams of bits that.&lt;&#x2F;li&gt;
&lt;li&gt;Entropy accumulator&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;entropy-sources&quot;&gt;Entropy sources&lt;&#x2F;h2&gt;
&lt;p&gt;Some program accessible sources of entropy are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rdrand&lt;&#x2F;code&gt; instruction&lt;&#x2F;li&gt;
&lt;li&gt;Screen capture&lt;&#x2F;li&gt;
&lt;li&gt;High resolution clocks&lt;&#x2F;li&gt;
&lt;li&gt;Wall-time clocks&lt;&#x2F;li&gt;
&lt;li&gt;Stored entropy&lt;&#x2F;li&gt;
&lt;li&gt;IO input and timings&lt;&#x2F;li&gt;
&lt;li&gt;Operating system entropy sources&lt;&#x2F;li&gt;
&lt;li&gt;Standard library entropy sources&lt;&#x2F;li&gt;
&lt;li&gt;Microphone &#x2F; webcam input (Just don’t point your your webcam at a
lavalamp or you will need to license &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.google.com&#x2F;patents&#x2F;US5732138&quot;&gt;US
5732138&lt;&#x2F;a&gt; from SGI.)&lt;&#x2F;li&gt;
&lt;li&gt;Hardware random number generators (if available)&lt;&#x2F;li&gt;
&lt;li&gt;Processor internal state
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.irisa.fr&#x2F;caps&#x2F;projects&#x2F;hipsor&#x2F;&quot;&gt;HAVEGE&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;So we have a lot of sources that can provide us with a tiny bit of
security. We would like to combine those into one source that can
provide us with a lot of security. We don’t want to design a system like
a chain, where if one link breaks, the load falls. We want to design the
system like braided rope, all strands need to break before the load is
lost.&lt;&#x2F;p&gt;
&lt;p&gt;Luckily, for random number generators we can create the braided rope.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pseudo-random-number-generators&quot;&gt;Pseudo random number generators&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;void seed(const Bytes bytes); Bytes extract(uint length);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;entropy-accumulator&quot;&gt;Entropy accumulator&lt;&#x2F;h2&gt;
&lt;p&gt;How to Eat Your Entropy and Have it Too
Optimal Recovery Strategies for Compromised RNGs
http:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;167.pdf
Random number generators (RNGs) play a crucial role in many
cryptographic schemes and protocols, but their security proof usually
assumes that their internal state is initialized with truly random seeds
and remains secret at all times. However, in many practical situations
these are unrealistic assumptions: …&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Innovation diffusion models</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/innovation-diffusion-models/"/>
        <id>https://2π.com/14/innovation-diffusion-models/</id>
        
        <content type="html" xml:base="https://2π.com/14/innovation-diffusion-models/">&lt;h1 id=&quot;innovation-diffusion-models&quot;&gt;Innovation diffusion models&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\e{\mathrm e}
\gdef\fd#1#2{\frac{\mathrm{d} #1}{\mathrm{d} #2}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To simplify matters I will take out any time offset and market size
factor, they can be reintroduced by setting:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A&amp;#39;(t) = M_0 + M A(t - t_0)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;super-diffusion-model&quot;&gt;Super diffusion model&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\fd A t = \left( p + q A \right) (1 - A^ν)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bass-diffusion-model&quot;&gt;Bass Diffusion Model&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\fd A t &amp;amp;= \left( p + q A \right) (1 - A) \\
A(t) &amp;amp;= \frac{1 - \e^{-(p + q)t}}{1 + \frac qp \e^{-(p+q)t} }
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;generalised-logistic-function&quot;&gt;Generalised logistic function&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\fd A t &amp;amp;= α ν \left( 1 - \left( \frac A K \right)^{\frac 1 ν} \right) A \\
A(t) &amp;amp;= \frac{1}{(Q + \e^{-B(t-M)} )^{\frac 1 ν}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;gompertz-model&quot;&gt;Gompertz model&lt;&#x2F;h2&gt;
&lt;p&gt;Take the generalised logistic function&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\fd A t = α ν \left( 1 - \left( \frac A K \right)^{\frac 1 ν} \right) A
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and apply the limit &lt;span class=&quot;math math-inline&quot;&gt;ν → ∞&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\lim_{v → ∞} ν \left( 1 - x^{\frac 1 ν} \right) = -\log x
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\fd A t &amp;amp;= - α \log \left( \frac A K \right) A \\
A(t) &amp;amp;= \e^{-b \e^{-c t}} \\
b &amp;amp;= -log(A(0)) \\
\fd A t &amp;amp;= c \log \left( \frac {X(b,c)} A \right) A
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simple-logistic-function&quot;&gt;Simple logistic function&lt;&#x2F;h2&gt;
&lt;p&gt;Take the GLF and set &lt;span class=&quot;math math-inline&quot;&gt;ν = 0&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\fd A t &amp;amp;= A · (1 - A) \\
A(t) &amp;amp;= \frac{M}{1 + \e^{-x}}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
A(t) = \frac{M}{1 + \e^{-x}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Order</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/model/order/"/>
        <id>https://2π.com/14/model/order/</id>
        
        <content type="html" xml:base="https://2π.com/14/model/order/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\set#1{\mathcal{#1}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;order&quot;&gt;Order&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\nE[#1]#2{\nexists_{#1}^{#2}}
\gdef\A[#1]#2{\forall_{#1}^{#2}}
\gdef\set#1{\mathcal #1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a set &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt;. Assume nothing of this set, other than that it may
or may not have elements and that we can check if two elements are the
same.&lt;&#x2F;p&gt;
&lt;p&gt;Think for example of a set of instances of a particular class.&lt;&#x2F;p&gt;
&lt;p&gt;I will now explain what it formally means to have an order between the
instances. What different kinds of order there are and why it matters.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;relations&quot;&gt;Relations&lt;&#x2F;h2&gt;
&lt;p&gt;Suppose we have a function, taking two elements of this set and giving a
boolean in return. We can formally write the type of this function as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f : \set S × \set S → 𝔹
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Such functions, return true or false given two elements, is called a
‘binary relation’. The equality operation on the elements of our set is
an example.&lt;&#x2F;p&gt;
&lt;p&gt;In mathematics the function notation is often replaced with an infix
notation. Sometimes, the relation is even seen as something different
than a function. I disagree with this, I find the function concept very
useful when dealing with programming languages. This whole confusion is
the reason why C++ has weird special functions like &lt;code&gt;operator==&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Other examples of such functions are ‘divides’ on integers, ‘orthogonal’
on vectors and ‘less than’ on numbers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;strict-partial-order&quot;&gt;Strict partial order&lt;&#x2F;h2&gt;
&lt;p&gt;A strict partial order is a binary relation &lt;span class=&quot;math math-inline&quot;&gt;&amp;lt;&lt;&#x2F;span&gt; with the following
properties:&lt;&#x2F;p&gt;
&lt;p&gt;Irreflexivity:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\nE[\set S]x  \left(x &amp;lt; x\right(
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Transitivity:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A[\set S]a\A[\set S]b\A[\set S]c\; \left(a &amp;lt; b\right( ∧ \left(b &amp;lt; c\right( → \left(a &amp;lt; c\right(
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;From this we can derive more properties, for example asymmetry:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A[\set S]a\A[\set S]b\; \left(a &amp;lt; b\right( → ¬\left(b &amp;lt; a\right(
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;PROOF: Take the transitivity property and with
&lt;span class=&quot;math math-inline&quot;&gt;c = a&lt;&#x2F;span&gt;: &lt;span class=&quot;math math-inline&quot;&gt;\A[\set S] a\A[\set S]b\; \left(a &amp;lt; b\right( ∧ \left(b &amp;lt; a\right( → \left(a &amp;lt; a\right(&lt;&#x2F;span&gt;
We can rephrase the irreflexivity as &lt;span class=&quot;math math-inline&quot;&gt;\A[\set S]a\; ¬\left(a &amp;lt; a\right(&lt;&#x2F;span&gt; From
the law of the excluded middle we then have &lt;span class=&quot;math math-inline&quot;&gt;\left(a &amp;lt; a\right( ↔ ⊥&lt;&#x2F;span&gt;, substitute
this: &lt;span class=&quot;math math-inline&quot;&gt;\A[\set S]a\A[\set S]b\; \left(a &amp;lt; b\right( ∧ \left(b &amp;lt; a\right( → ⊥&lt;&#x2F;span&gt;
Which means that: &lt;span class=&quot;math math-inline&quot;&gt;\A[\set S]a\A[\set S]b\; ¬ \left( \left(a &amp;lt; b\right( ∧ \left(b &amp;lt; a\right( \right(&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\A[\set S]a\A[\set S]b\; \left(a &amp;lt; b\right( → ¬ \left(b &amp;lt; a\right(&lt;&#x2F;span&gt; QED.&lt;&#x2F;p&gt;
&lt;p&gt;We can also define a non-strict partial order as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left(a ≤ b\right( ↔ \left(a &amp;lt; b\right( ∨ \left(a = b\right(
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and introduce &lt;span class=&quot;math math-inline&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;≥&lt;&#x2F;span&gt; by flipping the arguments.&lt;&#x2F;p&gt;
&lt;p&gt;It is called a partial order because there can be incomparable objects.
Some comparisons are inconclusive, we can have &lt;span class=&quot;math math-inline&quot;&gt;a ≠ b&lt;&#x2F;span&gt; but &lt;span class=&quot;math math-inline&quot;&gt;a &amp;lt; b&lt;&#x2F;span&gt; and
&lt;span class=&quot;math math-inline&quot;&gt;b &amp;lt; a&lt;&#x2F;span&gt; can still be both false.&lt;&#x2F;p&gt;
&lt;p&gt;The partial order relation defines a directed acyclic graph over the
elements of &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt;. Conversely, any directed acyclic graph can be
turned into a partial order by taking the transitive closure. For
example, the &lt;em&gt;divides&lt;&#x2F;em&gt; relation on integers is a partial order, even
though it might seem to have little to do with an order.&lt;&#x2F;p&gt;
&lt;p&gt;In particular, any tree structure is a partial order with its non-direct
&lt;em&gt;descendant of&lt;&#x2F;em&gt; relation. For example, &lt;em&gt;subset of&lt;&#x2F;em&gt;, &lt;em&gt;substring of&lt;&#x2F;em&gt;, etc…&lt;&#x2F;p&gt;
&lt;h2 id=&quot;strict-total-order&quot;&gt;Strict total order&lt;&#x2F;h2&gt;
&lt;p&gt;A strict total order is a strict partial order with an addition axiom:&lt;&#x2F;p&gt;
&lt;p&gt;Totality:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\A[\set S]a\A[\set S]b\; \left(a ≠ b\right( → \left(a &amp;lt; b\right( ∨ \left(b &amp;lt; a\right(
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That this implies only one of a &amp;lt; b and b &amp;lt; a is true is a consequence
of the asymmetry property we have proven.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;strict-well-order&quot;&gt;Strict well-order&lt;&#x2F;h2&gt;
&lt;p&gt;An order is well-order if for any element there are only a finite number
of elements less than it.&lt;&#x2F;p&gt;
&lt;p&gt;This has a number of interesting mathematical consequences:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Every non-empty subset has a least element&lt;&#x2F;li&gt;
&lt;li&gt;Every strictly decreasing sequence must terminate&lt;&#x2F;li&gt;
&lt;li&gt;Properties can be proven using transfinite induction&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;These orders allow induction over the element in the&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
…,-3,-2,-1,0,1,2,3,…
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;has no lest element, but if we re-arrange it to be:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0,1,2,3,…,-1,-2,-3,…
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;it becomes a well-order of type ω+ω. This order can be easily defined in
pseudo code&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39; b:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ≠ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; abs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; abs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;o-order&quot;&gt;ω-order&lt;&#x2F;h2&gt;
&lt;p&gt;The above example for the integers is still not as natural as I would
like it to be. The problem is, it has two ellipsis (…). If I start
counting from 0, I will never reach the negative numbers. But if we
re-arrange it as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
0, -1, 1, -2, 2, -3, 3, … 
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For example with this function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39; b:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; abs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ≠ &lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;abs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; abs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt; abs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;then it becomes countable!&lt;&#x2F;p&gt;
&lt;p&gt;A ω-order is countable. It can be brought in to one-on-one
correspondence with the natural numbers without rearanging the order. As
a consequence, these orders are perfectly concise Gödel numbering.&lt;&#x2F;p&gt;
&lt;p&gt;This conciseness is used in Google’s &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developers.google.com&#x2F;protocol-buffers&#x2F;docs&#x2F;encoding#types&quot;&gt;Protocol
Buffers&lt;&#x2F;a&gt;
to store signed integers. They call it ZigZag encoding and found an
elegant mapping between the integers and naturals by exploiting the
twos-complement.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;encode n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; signed&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Well-founded strict total order.&lt;&#x2F;p&gt;
&lt;p&gt;See: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.karlin.mff.cuni.cz&#x2F;~jezek&#x2F;120&#x2F;transitive1.pdf&quot;&gt;http:&#x2F;&#x2F;www.karlin.mff.cuni.cz&#x2F;~jezek&#x2F;120&#x2F;transitive1.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>One Plus One</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/oneplusone/oneplusone/"/>
        <id>https://2π.com/14/oneplusone/oneplusone/</id>
        
        <content type="html" xml:base="https://2π.com/14/oneplusone/oneplusone/">&lt;h1 id=&quot;one-plus-one&quot;&gt;One Plus One&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;partitions&quot;&gt;Partitions&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.addictivetips.com&#x2F;mobile&#x2F;android-partitions-explained-boot-system-recovery-data-cache-misc&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.addictivetips.com&#x2F;mobile&#x2F;android-partitions-explained-boot-system-recovery-data-cache-misc&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Unless you have been using your Android phone just for calls, SMS,
browsing and basic apps, you should know that Android uses several
partitions to organize files and folders on the device. Each of these
partitions has a distinct role in the functionality of the device, but
not many Android users know the significance of each partition and its
contents. In this guide, we will take you on a tour of Android
partitions, what they contain and what can be the possible consequences
of modifying their content.&lt;&#x2F;p&gt;
&lt;p&gt;Android Partitions&lt;&#x2F;p&gt;
&lt;p&gt;Let’s start with a list of standard internal memory partitions on
Android phones and tablets. These are:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;boot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;recovery&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;cache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;misc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In addition, there are the SD card partitions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;sdcard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;sd-ext&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that only &#x2F;sdcard is found in all Android devices and the rest are
present only in select devices. Let’s now take a look at the purpose and
contents of each of these partitions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;boot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the partition that enables the phone to boot, as the name
suggests. It includes the kernel and the ramdisk. Without this
partition, the device will simply not be able to boot. Wiping this
partition from recovery should only be done if absolutely required and
once done, the device must NOT be rebooted before installing a new one,
which can be done by installing a ROM that includes a &#x2F;boot partition.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This partition basically contains the entire operating system, other
than the kernel and the ramdisk. This includes the Android user
interface as well as all the system applications that come pre-installed
on the device. Wiping this partition will remove Android from the device
without rendering it unbootable, and you will still be able to put the
phone into recovery or bootloader mode to install a new ROM.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;recovery&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The recovery partition can be considered as an alternative boot
partition that lets you boot the device into a recovery console for
performing advanced recovery and maintenance operations on it. To learn
more about this partition and its contents, see the ‘About Android
Recovery’ section of our guide to ClockworkMod recovery.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Also called userdata, the data partition contains the user’s data – this
is where your contacts, messages, settings and apps that you have
installed go. Wiping this partition essentially performs a factory reset
on your device, restoring it to the way it was when you first booted it,
or the way it was after the last official or custom ROM installation.
When you perform a wipe data&#x2F;factory reset from recovery, it is this
partition that you are wiping.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;cache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the partition where Android stores frequently accessed data and
app components. Wiping the cache doesn’t effect your personal data but
simply gets rid of the existing data there, which gets automatically
rebuilt as you continue using the device.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;misc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This partition contains miscellaneous system settings in form of on&#x2F;off
switches. These settings may include CID (Carrier or Region ID), USB
configuration and certain hardware settings etc. This is an important
partition and if it is corrupt or missing, several of the device’s
features will will not function normally.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;sdcard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is not a partition on the internal memory of the device but rather
the SD card. In terms of usage, this is your storage space to use as you
see fit, to store your media, documents, ROMs etc. on it. Wiping it is
perfectly safe as long as you backup all the data you require from it,
to your computer first. Though several user-installed apps save their
data and settings on the SD card and wiping this partition will make you
lose all that data.&lt;&#x2F;p&gt;
&lt;p&gt;On devices with both an internal and an external SD card – devices like
the Samsung Galaxy S and several tablets – the &#x2F;sdcard partition is
always used to refer to the internal SD card. For the external SD card –
if present – an alternative partition is used, which differs from device
to device. In case of Samsung Galaxy S series devices, it is &#x2F;sdcard&#x2F;sd
while in many other devices, it is &#x2F;sdcard2. Unlike &#x2F;sdcard, no system
or app data whatsoever is stored automatically on this external SD card
and everything present on it has been added there by the user. You can
safely wipe it after backing up any data from it that you need to save.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;sd-ext&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is not a standard Android partition, but has become popular in the
custom ROM scene. It is basically an additional partition on your SD
card that acts as the &#x2F;data partition when used with certain ROMs that
have special features called APP2SD+ or data2ext enabled. It is
especially useful on devices with little internal memory allotted to the
&#x2F;data partition. Thus, users who want to install more programs than the
internal memory allows can make this partition and use it with a custom
ROM that supports this feature, to get additional storage for installing
their apps. Wiping this partition is essentially the same as wiping the
&#x2F;data partition – you lose your contacts, SMS, market apps and settings.&lt;&#x2F;p&gt;
&lt;p&gt;With this, we conclude our tour of Android partitions. Now whenever you
install a ROM or mod that requires you to wipe certain partitions before
the installation, you should be in a better position to know what you’re
losing and what not and thus, you’ll know what to backup and what not.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;commands&quot;&gt;Commands&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash boot boot.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash userdata userdata_64g.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash system system.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash recovery recovery.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash cache cache.img&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash modem NON-HLOS.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash sbl1 sbl1.mbn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash dbi sdi.mbn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash aboot emmc_appsboot.mbn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash rpm rpm.mbn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash tz tz.mbn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fastboot flash LOGO logo.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb sideload&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The ultimate bitcoin paper wallet</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/paper-wallet/paper-wallet/"/>
        <id>https://2π.com/14/paper-wallet/paper-wallet/</id>
        
        <content type="html" xml:base="https://2π.com/14/paper-wallet/paper-wallet/">&lt;h1 id=&quot;the-ultimate-bitcoin-paper-wallet&quot;&gt;The ultimate bitcoin paper wallet&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;relevant-algorithms&quot;&gt;Relevant algorithms&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Random number generation&lt;&#x2F;li&gt;
&lt;li&gt;ECDSA on curve secp256k1&lt;&#x2F;li&gt;
&lt;li&gt;RIPEMD-160&lt;&#x2F;li&gt;
&lt;li&gt;SHA-256&lt;&#x2F;li&gt;
&lt;li&gt;Base58Check&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But really only private key generation and ECDSA public key derivations
need to be done securely, the rest can be done computer assisted.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;top-level-strategy&quot;&gt;Top level strategy&lt;&#x2F;h2&gt;
&lt;p&gt;1 Generate a private key 2 Derive the public key 3 Take the SHA-256 hash
of the public key 4 Take the RIPEMD-160 hash of the SHA-256 5 Prefix the
result with 0x00 6 Base58Check encode the result: 6.1 Take the SHA-256
of (5) 6.2 Take the SHA-356 of (6.1) 6.3 Take the first four bytes of
(6.2) 6.4 Concatenate (5) and (6.3) 6.5 Interpret (6.4) as a big-endian
number, no leading zeros 6.6 Convert to base-58&lt;&#x2F;p&gt;
&lt;p&gt;But really only 1 and 2 have to be done offline.&lt;&#x2F;p&gt;
&lt;p&gt;Consider the prime&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p = 2^{256} - 2^{32} - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and the elliptic curve equation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
y² = x³ + 7 \mod p
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a curve of the form y² = x³ + a x + b with a = 0 and b = 7.&lt;&#x2F;p&gt;
&lt;p&gt;The private key is a 256 bit number modulo p, since p is almost 2^{256}
we can just take a random 256 bit number.&lt;&#x2F;p&gt;
&lt;p&gt;Reduction modulo p can be done to good approximation by subtracting p
until the result is 256 bits.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-derive-the-public-key&quot;&gt;2 Derive the public key&lt;&#x2F;h3&gt;
&lt;p&gt;Start with the point &lt;span class=&quot;math math-inline&quot;&gt;G = (x_G, y_G)&lt;&#x2F;span&gt; with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x_G &amp;amp;=
55 066 263 022 277 343 669 578 718 895 168 534 326 250 603 453 777 594 175 500 187 360 389 116 729 240
\\ y_G &amp;amp;=
32 670 510 020 758 816 978 083 085 130 507 043 184 471 273 380 659 243 275 938 904 335 757 337 482 424
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;and compute &lt;span class=&quot;math math-inline&quot;&gt;k · G&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We need to multiply this point with the private key. One method is
double and add&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;Q ≔ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;P₀ ≔ G&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;…&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;255&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Pᵢ&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; · Pᵢ₋₁&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; bit i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; set&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; the private key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		Q ≔ Q&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Pᵢ&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The points &lt;code&gt;Pᵢ&lt;&#x2F;code&gt; can be precomputed and provided in a table. What remains
is elliptic curve addition. You would need to do on average 128
additions, depending on the private key.&lt;&#x2F;p&gt;
&lt;p&gt;This is 256 pre-computed values. We can go further and pre-compute
groups of bits. Say a nibble, then we have 512 pre-computed values, but
only 32 additions.&lt;&#x2F;p&gt;
&lt;p&gt;bit grouping b&lt;&#x2F;p&gt;
&lt;p&gt;n = 256 &#x2F; b table size = (2^b\ -\ 1)\ *\ n\ approx.\ addition\ =\ (1\ -\ 2^ (-b)) * n&lt;&#x2F;p&gt;
&lt;p&gt;Bit grouping  Table size  Additions&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;1             256         128
2             384         96
3             602         75
4             960         60
5             1612        50
6             2709        42
7             4699        37
&lt;strong&gt;8&lt;&#x2F;strong&gt;         &lt;strong&gt;8160&lt;&#x2F;strong&gt;    &lt;strong&gt;32&lt;&#x2F;strong&gt;
9             14819       29
10            26598       26
11            49128       24
12            90090       22
13            163820      20
14            311277      19
15            589806      18
16            &amp;gt; 10⁶       16&lt;&#x2F;p&gt;
&lt;p&gt;Its best to do as few additions as possible, but there is only limited
table space. Let’s settle on bytes. This will give a manageable 32
tables of 256 entries each.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;elliptic-curve-addition&quot;&gt;Elliptic curve addition&lt;&#x2F;h4&gt;
&lt;p&gt;Given two points &lt;span class=&quot;math math-inline&quot;&gt;P = (x_P, y_P)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q = (x_Q, y_Q)&lt;&#x2F;span&gt; we want to
compute &lt;span class=&quot;math math-inline&quot;&gt;R = P + Q&lt;&#x2F;span&gt;. Let’s write R out as &lt;span class=&quot;math math-inline&quot;&gt;(x_R, y_R)&lt;&#x2F;span&gt;, then:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
λ &amp;amp;= \frac{y_Q - y_P}{x_Q - x_P} \\ x_R &amp;amp;= λ^2 - x_P - x_Q \\ y_R &amp;amp;= λ\left(x_P - x_R\right) - y_P
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The addition and subtraction are laborious, but straightforward in
&lt;span class=&quot;math math-inline&quot;&gt;\mathbb F_p&lt;&#x2F;span&gt;. Squaring and multiplication can probably use some aid,
but the hardest part is likely the division.&lt;&#x2F;p&gt;
&lt;p&gt;The division can be done using an inversion and multiplication.&lt;&#x2F;p&gt;
&lt;p&gt;We need to do about 32 of these operations each of which involves:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;6 Subtractions&lt;&#x2F;li&gt;
&lt;li&gt;1 Square&lt;&#x2F;li&gt;
&lt;li&gt;2 Multiplication&lt;&#x2F;li&gt;
&lt;li&gt;1 Inversion&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;point-doubling&quot;&gt;Point doubling&lt;&#x2F;h4&gt;
&lt;p&gt;Just adding this for completeness, with the pre-computed tables you
don’t need this. The chances of accidentally ending up with two
identical points are insignificant.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
λ &amp;amp;= \frac{3 x_P^2 + a}{2 y_P} \\ x_R &amp;amp;= λ^2 - 2 x_P \\
x_R &amp;amp;= λ\left(x_P - x_R\right) - y_P
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;field-subtraction&quot;&gt;Field subtraction&lt;&#x2F;h4&gt;
&lt;p&gt;Schoolbook.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;field-multiplication&quot;&gt;Field multiplication&lt;&#x2F;h4&gt;
&lt;p&gt;Long multiplication.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;field-squaring&quot;&gt;Field squaring&lt;&#x2F;h4&gt;
&lt;p&gt;Multiply by itself.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;field-inverse&quot;&gt;Field inverse&lt;&#x2F;h4&gt;
&lt;p&gt;Taking the inverse modulo p is the same as exponentiation by p - 2. This
in turn can be done as a square-and-multiply. A fast method uses first
uses the addition chain:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\color{red}{1}, \color{red}{2}, 3, 6, 9, 11, \color{red}{22}, 44,
88, 176, 220, \color{red}{223}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And the proceeds with repeated squaring and multiply.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;field-inverse-using-euclids-algorithm&quot;&gt;Field inverse using Euclids algorithm&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
n · m = r \mod p
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
n · m - g · p = r
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;field-using-logarithms&quot;&gt;Field using logarithms&lt;&#x2F;h4&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; a generator of &lt;span class=&quot;math math-inline&quot;&gt;\mathbb F_p&lt;&#x2F;span&gt;. Private key is &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. Public key is
&lt;span class=&quot;math math-inline&quot;&gt;g^n G&lt;&#x2F;span&gt;. Arithmetic is done in &lt;span class=&quot;math math-inline&quot;&gt;\mathbb F_{p - 1}&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
λ &amp;amp;= (y_Q ⊖ y_P) - (x_Q ⊖ x_P) \\ x_R &amp;amp;= 2 λ ⊖ x_P ⊖ x_Q
\\ y_R &amp;amp;= λ \left(x_P ⊖ x_R\right) ⊖ y_P
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But now ⊖ is a hard operation.&lt;&#x2F;p&gt;
&lt;p&gt;In the one exponentiations need to be done to find the x point of the
public key.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.bitcoin.it&#x2F;wiki&#x2F;Technical_background_of_Bitcoin_addresses&quot;&gt;https:&#x2F;&#x2F;en.bitcoin.it&#x2F;wiki&#x2F;Technical_background_of_Bitcoin_addresses&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.bitcoin.it&#x2F;wiki&#x2F;Private_key&quot;&gt;https:&#x2F;&#x2F;en.bitcoin.it&#x2F;wiki&#x2F;Private_key&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.bitcoin.it&#x2F;wiki&#x2F;Secp256k1&quot;&gt;https:&#x2F;&#x2F;en.bitcoin.it&#x2F;wiki&#x2F;Secp256k1&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;kakaroto.homelinux.net&#x2F;2012&#x2F;01&#x2F;how-the-ecdsa-algorithm-works&#x2F;&quot;&gt;http:&#x2F;&#x2F;kakaroto.homelinux.net&#x2F;2012&#x2F;01&#x2F;how-the-ecdsa-algorithm-works&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.bitcoin.it&#x2F;wiki&#x2F;Paper_wallet&quot;&gt;https:&#x2F;&#x2F;en.bitcoin.it&#x2F;wiki&#x2F;Paper_wallet&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;engineering.purdue.edu&#x2F;kak&#x2F;compsec&#x2F;NewLectures&#x2F;Lecture14.pdf&quot;&gt;https:&#x2F;&#x2F;engineering.purdue.edu&#x2F;kak&#x2F;compsec&#x2F;NewLectures&#x2F;Lecture14.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;link.springer.com&#x2F;article&#x2F;10.1023&#x2F;A%3A1008306223194&quot;&gt;http:&#x2F;&#x2F;link.springer.com&#x2F;article&#x2F;10.1023&#x2F;A%3A1008306223194&lt;&#x2F;a&gt;
(paywall, here is the preprint:
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.hyperelliptic.org&#x2F;tanja&#x2F;preprints&#x2F;preprint.pdf&quot;&gt;http:&#x2F;&#x2F;www.hyperelliptic.org&#x2F;tanja&#x2F;preprints&#x2F;preprint.pdf&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;modular.math.washington.edu&#x2F;edu&#x2F;124&#x2F;misc&#x2F;koblitz_ecc.pdf&quot;&gt;http:&#x2F;&#x2F;modular.math.washington.edu&#x2F;edu&#x2F;124&#x2F;misc&#x2F;koblitz_ecc.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.jucs.org&#x2F;jucs_14_3&#x2F;parallel_formulations_of_scalar&#x2F;jucs_14_3_0481_0504_ahmadi.pdf&quot;&gt;http:&#x2F;&#x2F;www.jucs.org&#x2F;jucs_14_3&#x2F;parallel_formulations_of_scalar&#x2F;jucs_14_3_0481_0504_ahmadi.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Good overview on methods and strategies!&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Most works publishedin this area have strived for reducingthe cost
associated to the double-and-add method by following two main
strategies: reducing the computational complexity of point addition and
point doubling primitives, and reducing the number of times that the
point addition primitive is invoked during the algorithm execution. A
significant improvement in performance can be obtained when the point P
is known in advance by using precomputation (if memory space permits)
and techniques such as the comb method [Hankerson et al. 2004]&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cdn.preterhuman.net&#x2F;texts&#x2F;cryptography&#x2F;Hankerson,%20Menezes,%20Vanstone.%20Guide%20to%20elliptic%20curve%20cryptography%20%28Springer,%202004%29%28ISBN%20038795273X%29%28332s%29_CsCr_.pdf&quot;&gt;http:&#x2F;&#x2F;cdn.preterhuman.net&#x2F;texts&#x2F;cryptography&#x2F;Hankerson,%20Menezes,%20Vanstone.%20Guide%20to%20elliptic%20curve%20cryptography%20%28Springer,%202004%29%28ISBN%20038795273X%29%28332s%29_CsCr_.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;161.pdf&quot;&gt;http:&#x2F;&#x2F;eprint.iacr.org&#x2F;2014&#x2F;161.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;secp256k1&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;bitcoin&#x2F;secp256k1&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt; Include acid-free paper and pen with archival ink. 
*  Include hex-dice&lt;&#x2F;li&gt;
&lt;li&gt; Written note that the dice are unbiased&lt;&#x2F;li&gt;
&lt;li&gt; Separate workbook&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Version dependency datasets</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/phd/dependency-datasets/"/>
        <id>https://2π.com/14/phd/dependency-datasets/</id>
        
        <content type="html" xml:base="https://2π.com/14/phd/dependency-datasets/">&lt;h1 id=&quot;version-dependency-datasets&quot;&gt;Version dependency datasets&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;overview-of-package-databases&quot;&gt;Overview of package databases&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;data.3tu.nl&#x2F;repository&#x2F;uuid:68a0e837-4fda-407a-949e-a159546e67b6&quot;&gt;http:&#x2F;&#x2F;data.3tu.nl&#x2F;repository&#x2F;uuid:68a0e837-4fda-407a-949e-a159546e67b6&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;+--------------------+--------------------+--------------------+--------------------+
| Platform           | Package manager    | Package databases  | Packages           |
+--------------------+--------------------+--------------------+--------------------+
| Gentoo             | Emerge             | Portage            | 60000              |
+--------------------+--------------------+--------------------+--------------------+&lt;&#x2F;p&gt;
&lt;p&gt;Systems with&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Gentoo Portage&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Maven (Java) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;maven.apache.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;maven.apache.org&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;RubyGems &#x2F; Bundler (Ruby) PIP &#x2F; PyPI (Python) Packagist &#x2F; Composer
(PHP) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;packagist.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;packagist.org&#x2F;&lt;&#x2F;a&gt; NPM (Node.JS) Bower (JS, CSS, HTML)
CocoaPods (Objective-C) Maven (Java) Lein (Clojure)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;CPAN (Perl)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;CTAN (TeX)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;CRAN ®&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;CEAN (Erlang) &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cean.process-one.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;cean.process-one.net&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;PEAR &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pear.php.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;pear.php.net&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;IVY &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ant.apache.org&#x2F;ivy&#x2F;&quot;&gt;https:&#x2F;&#x2F;ant.apache.org&#x2F;ivy&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.versioneye.com&#x2F;2014&#x2F;01&#x2F;15&#x2F;which-programming-language-has-the-best-package-manager&#x2F;&quot;&gt;http:&#x2F;&#x2F;blog.versioneye.com&#x2F;2014&#x2F;01&#x2F;15&#x2F;which-programming-language-has-the-best-package-manager&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.versioneye.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.versioneye.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Notes</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/phd/notes/"/>
        <id>https://2π.com/14/phd/notes/</id>
        
        <content type="html" xml:base="https://2π.com/14/phd/notes/">&lt;h1 id=&quot;notes&quot;&gt;Notes&lt;&#x2F;h1&gt;
&lt;p&gt;Disrubting existing industries:&lt;&#x2F;p&gt;
&lt;p&gt;Legos and 3D printing:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;taranvh.com&#x2F;2014&#x2F;08&#x2F;02&#x2F;3d-printing-custom-lego-pieces&quot;&gt;http:&#x2F;&#x2F;taranvh.com&#x2F;2014&#x2F;08&#x2F;02&#x2F;3d-printing-custom-lego-pieces&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.shapeways.com&#x2F;model&#x2F;1907041&#x2F;28z-double-bevel.html?materialId=6&quot;&gt;http:&#x2F;&#x2F;www.shapeways.com&#x2F;model&#x2F;1907041&#x2F;28z-double-bevel.html?materialId=6&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;backchannel&#x2F;diybio-comes-of-age-4a5b15d1131f&quot;&gt;https:&#x2F;&#x2F;medium.com&#x2F;backchannel&#x2F;diybio-comes-of-age-4a5b15d1131f&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kickstarter.com&#x2F;projects&#x2F;932664050&#x2F;opentrons-open-source-rapid-prototyping-for-biolog&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.kickstarter.com&#x2F;projects&#x2F;932664050&#x2F;opentrons-open-source-rapid-prototyping-for-biolog&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Book on open source innovation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;innovation-sources&quot;&gt;Innovation sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Commercial RnD&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Economic goals harm creative freedom&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Governmental&#x2F;Academical RnD&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Budget cuts, result orientation and sick working culture harm
creative freedom.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Budget cuts → NASA&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Result orientation → Need preliminarily results before
funding&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Sick culture → Blind focus on articles and reference counts
in expensive commercial journals.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;DIY RnD&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Unrestricted, but unfunded&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;open-source-communities&quot;&gt;Open source communities&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Space habbitation: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Angelo_Vermeulen&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Angelo_Vermeulen&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;List of open source areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Open_source#Applications&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Open_source#Applications&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;scattered-ideas&quot;&gt;Scattered ideas&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Design open source community around nanotechnology&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Twente has the knowledge and facilities in house&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Apply anthropology to OS communities.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ask David Graeber?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Apply for internship at European Union to get six months of RnD
funding.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Domain Colouring</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/physics/domain-colouring/"/>
        <id>https://2π.com/14/physics/domain-colouring/</id>
        
        <content type="html" xml:base="https://2π.com/14/physics/domain-colouring/">&lt;h1 id=&quot;domain-colouring&quot;&gt;Domain Colouring&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\g#1{\left({#1}\right)}
\gdef\norm#1{\left\vert{#1}\right\vert}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Take &lt;span class=&quot;math math-inline&quot;&gt;r = \log\g{1 + \norm x}&lt;&#x2F;span&gt; then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
H &amp;amp;= \arg z \\
S &amp;amp;= \frac 12 \g{1 + \sin 2 π r} \\
V &amp;amp;= \frac 12 \g{1 + \cos 2 π r}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Noether&#x27;s Theorem</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/physics/noethers-theorem/"/>
        <id>https://2π.com/14/physics/noethers-theorem/</id>
        
        <content type="html" xml:base="https://2π.com/14/physics/noethers-theorem/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\∂{\partial}
\gdef\∫{\int}
\gdef\d{\operatorname{d}\!}
\gdef\g{\mathrm{g}}
\gdef\vec#1{\mathbf #1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To every differentiable symmetry generated by local actions, there
corresponds a conserved current.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;discrete-langrangian-mechanics&quot;&gt;Discrete Langrangian Mechanics&lt;&#x2F;h2&gt;
&lt;p&gt;In Langrangian mechanics a system is described by a set of generalized
parameters &lt;span class=&quot;math math-inline&quot;&gt;\vec x(t)&lt;&#x2F;span&gt;, a time depended vector in the state space of the
system.&lt;&#x2F;p&gt;
&lt;p&gt;The physics of the system is contained in a Lagrangian function:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L(t, \vec x, \vec v): ℝ × \mathrm{T}\mkern2mu X → ℝ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\vec x ∈ X&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\vec v ∈ \mathrm{T}_{\vec x} X&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Hamilton’s principle than states that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
δ \vec x(t) \∫ t L(\vec x(t), (\d t {\vec x}) (t), t) = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;this can be restated as the Euler-Lagrange equations:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\d t \∂ {v_k} L = \∂{x_k} L
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;noether-s-theorem&quot;&gt;Noether’s theorem&lt;&#x2F;h2&gt;
&lt;p&gt;Given a symmetry &lt;span class=&quot;math math-inline&quot;&gt;T_r&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;\vec Q_r&lt;&#x2F;span&gt;, the quantity&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\g{ \∂ {\vec v} L · \vec v - L } T_r - \∂ {\vec v} L · \vec Q_r
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;is conserved.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;in-reality&quot;&gt;In reality&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-standard-model&quot;&gt;The standard model&lt;&#x2F;h3&gt;
&lt;p&gt;Symmetry    Generators  Conserved quantity&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Time shift  1           Energy
Translation 3           Momentum
Rotation    3           Angular Momentum
Boosts      3           ??
Gauge       6           Color charge, Weak isospin, Electric charge, Weak hypercharge
Phase       4           Baryon, electron, muon and tau numbers&lt;&#x2F;p&gt;
&lt;h3 id=&quot;general-relativity&quot;&gt;General Relativity&lt;&#x2F;h3&gt;
&lt;p&gt;The Einstein-Hilbert Langrangian:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
L = \frac{c^4}{16 π G} R_j^j \sqrt{-\det g_{μν}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Killing vector fields are symmetries of the metric tensor.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Notation</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/physics/notation/"/>
        <id>https://2π.com/14/physics/notation/</id>
        
        <content type="html" xml:base="https://2π.com/14/physics/notation/">&lt;h1 id=&quot;notation&quot;&gt;Notation&lt;&#x2F;h1&gt;
&lt;p&gt;TODO: The formatting in this article is currently broken.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\O{\mathcal{O}}
\gdef\L{\mathcal{L}}
\gdef\D{\mathrm{D}}
\gdef\Eu{\exists!}
\gdef\Eust{\exists?}
\gdef\S{\mathrm{S}}
\gdef\δ{\delta}
\gdef\setc#1{\{{#1}\}}
\gdef\∀{\forall}
\gdef\∃{\exists}
\gdef\Σ{\sum}
\gdef\∂{\partial}
\gdef\∫{\int}
\gdef\e{\mathrm e}
\gdef\i{\mathrm i}
\gdef\π{\pi}
\gdef\set#1{\mathcal #1}
\gdef\norm#1{\left\vert{#1}\right\vert}
\gdef\g#1{\left({#1}\right)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;building-sets&quot;&gt;Building sets&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\set S × \set S = \set S^2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;notation-1&quot;&gt;Notation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;binding-operators&quot;&gt;Binding operators&lt;&#x2F;h3&gt;
&lt;p&gt;Binding operators have the generic notation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\O[\set S] x
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{O}&lt;&#x2F;span&gt; denotes the operator to be preformed, &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt; is a set
from which elements &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; will be taken. The operator is right-associative
and hence applied on the expression following it, which may include
references to &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;. The resulting expression will not depend on &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt;, it is
bound by the operator.&lt;&#x2F;p&gt;
&lt;p&gt;Many operators are defined by a fold, for example the summation operator
can be written out using binary addition and zero as
&lt;span class=&quot;math math-inline&quot;&gt;\Σ[ℕ] n f(n) = 0 + f(0) + f(1) + ⋯&lt;&#x2F;span&gt;. The zero in front is important, otherwise the result
would be undefined if an empty set was given. The operators defined in
this way are:&lt;&#x2F;p&gt;
&lt;p&gt;Operator     Join    Base&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∀&lt;&#x2F;span&gt;  &lt;span class=&quot;math math-inline&quot;&gt;∧&lt;&#x2F;span&gt;     &lt;span class=&quot;math math-inline&quot;&gt;⊤&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∃&lt;&#x2F;span&gt;  &lt;span class=&quot;math math-inline&quot;&gt;∨&lt;&#x2F;span&gt;     &lt;span class=&quot;math math-inline&quot;&gt;⊥&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∪&lt;&#x2F;span&gt;  &lt;span class=&quot;math math-inline&quot;&gt;∪&lt;&#x2F;span&gt;     &lt;span class=&quot;math math-inline&quot;&gt;∅&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∩&lt;&#x2F;span&gt;  &lt;span class=&quot;math math-inline&quot;&gt;∩&lt;&#x2F;span&gt;     &lt;span class=&quot;math math-inline&quot;&gt;\set U&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm Σ&lt;&#x2F;span&gt;  &lt;span class=&quot;math math-inline&quot;&gt;+&lt;&#x2F;span&gt;     &lt;span class=&quot;math math-inline&quot;&gt;0&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm Π&lt;&#x2F;span&gt;  &lt;span class=&quot;math math-inline&quot;&gt;\;·\;&lt;&#x2F;span&gt; &lt;span class=&quot;math math-inline&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The expression is a function with &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt; as its domain and a the same
range as the operator expression.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;exceptional-binding-operators&quot;&gt;Exceptional binding operators&lt;&#x2F;h3&gt;
&lt;p&gt;Operator          Interpretation&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∄&lt;&#x2F;span&gt;       not exists
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∃!&lt;&#x2F;span&gt;      unique
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∃?&lt;&#x2F;span&gt;      an element such that
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∃‽&lt;&#x2F;span&gt;      the unique element such that
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm \vert&lt;&#x2F;span&gt;   substitute
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm S&lt;&#x2F;span&gt;       set builder
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm L&lt;&#x2F;span&gt;       limit
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm ∫&lt;&#x2F;span&gt;       integral
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm max&lt;&#x2F;span&gt;     maximum
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm argmax&lt;&#x2F;span&gt;  argument of the maximum&lt;&#x2F;p&gt;
&lt;p&gt;The substitute operator takes &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt; as a singleton set, in fact, we
can forgo the set notation &lt;span class=&quot;math math-inline&quot;&gt;\setc{x}&lt;&#x2F;span&gt; and write x directly. The set
builder takes a boolean expressions, but gives a subset of &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt; as
result. In limits the set &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt; is a directed set.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\L[ℕ]n \frac{1}{n} = 0
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The limit is defined using a generalization of the &lt;span class=&quot;math math-inline&quot;&gt;(ε, δ)&lt;&#x2F;span&gt; definition:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\L[\set S]x f(x) = l ⇔ \∀[\set U(l)]U \∃[\set S]α \∀[\set S ≥ α]β f(β) ∈ U
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\L[\set S]x = \Eust l \∀[\set U(l)]ε \∃[\set S]δ \∀[\set S ≥ δ]x ε ∋
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\set U(l)&lt;&#x2F;span&gt; is the set of all neighborhoods around &lt;span class=&quot;math math-inline&quot;&gt;l&lt;&#x2F;span&gt; and
&lt;span class=&quot;math math-inline&quot;&gt;\set S ≥ α&lt;&#x2F;span&gt; is defined as &lt;span class=&quot;math math-inline&quot;&gt;\S[\set S] β β≥ α&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A Riemann integral is defined as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\∫[{[0,1]}]x f(x) = \L[ℕ]n \frac 1 n \Σ[{[0,n-1]}]i f\g{\frac i n}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using the substitute operator this can be written concisely as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\∫[{[0,1]}]x = \L[ℕ]n \frac 1 n \Σ[{[0,n-1]}]i \|[\frac i n]{x}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The fundamental theorem of calculus can be written as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\∫[{[a,b]}]x = \g{ \|[b]x - \|[a]x } \D[-1]x
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;non-binding-operators&quot;&gt;Non binding operators&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
&amp;amp;\∃[\set S]x P(x) &amp;amp;&amp;amp;⇔&amp;amp; \S[\set S]x P(x) &amp;amp;≠ ∅ \\
&amp;amp;\Eu[\set S]x P(x) &amp;amp;&amp;amp;⇔&amp;amp; \norm{\S[\set S]x P(x)} &amp;amp;= 1
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;r(\set S)&lt;&#x2F;span&gt; arbitrary element from &lt;span class=&quot;math math-inline&quot;&gt;\set S&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;integral-transforms&quot;&gt;Integral transforms&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;\e&lt;&#x2F;span&gt; &lt;span class=&quot;math math-inline&quot;&gt;\i&lt;&#x2F;span&gt; &lt;span class=&quot;math math-inline&quot;&gt;\π&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat f(ω) = \∫[ℝ]t \e^{-2 \π \i ω t} f(t)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathcal F_ω^t = \∫[ℝ]t \e^{-2 \π \i ω t}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathcal L_s^t = \∫[{[0,∞)}]t \e^{-s t}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat f(ω) = \mathcal F_ω^t f(t)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Integral_transform&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Integral_transform&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Generalized:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathcal T(K, \set D)_u^t = \∫[\set D]t K(u, t)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;extended-real-numbers&quot;&gt;Extended real numbers&lt;&#x2F;h2&gt;
&lt;p&gt;The extended real numbers,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\overline ℝ = \setc{-∞, +∞} ∪ ℝ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;set-building&quot;&gt;Set building&lt;&#x2F;h2&gt;
&lt;p&gt;Given a proposition &lt;span class=&quot;math math-inline&quot;&gt;P : \set S → 𝔹&lt;&#x2F;span&gt; we can the set builder operator is
defined by:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\set Q = \S[\set S] x P(x) ⇔ \∀[\set S] x x ∈ \set Q ↔ P (x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\∀[ℝ→ℝ] f \∃[ℝ] y \∫[{[0,2,4,…]}] x f(x) = \Σ[ℝ] x f(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\∫ x f(x) =
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
123 \∂ z 2 \D y \δ x f(x)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Laplacian operator:&lt;&#x2F;p&gt;
&lt;p&gt;For some rectalinear basis &lt;span class=&quot;math math-inline&quot;&gt;\set B&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\vec ∇ &amp;amp;= \Σ[\set B]{\vec x} \vec x \∂{\vec x} \\
Δ &amp;amp;= {\vec ∇}^2 = \Σ[\set B]{\vec x} \∂[2]{\vec x}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Word clouds</title>
        <published>2015-08-26T00:00:00+00:00</published>
        <updated>2015-08-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/word-cloud/word-cloud/"/>
        <id>https://2π.com/14/word-cloud/word-cloud/</id>
        
        <content type="html" xml:base="https://2π.com/14/word-cloud/word-cloud/">&lt;h1 id=&quot;word-clouds&quot;&gt;Word clouds&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;word-cloud&#x2F;word-cloud&#x2F;word-cloud.png&quot; alt=&quot;This word cloud is generated from the SU GIC NL competition entries.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-and-weighing-keywords&quot;&gt;Finding and weighing keywords&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text = Import[&amp;quot;~&#x2F;text.txt&amp;quot;] &#x2F;&#x2F; ToLowerCase;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;text = StringReplace[text, {&amp;quot;educational&amp;quot; → &amp;quot;education&amp;quot;,&amp;quot;teachers&amp;quot; → &amp;quot;teacher&amp;quot;,&amp;quot;learner&amp;quot; → &amp;quot;student&amp;quot;,&amp;quot;technologies&amp;quot; → &amp;quot;technology&amp;quot;,&amp;quot;learning&amp;quot; → &amp;quot;learn&amp;quot;,&amp;quot;leerling&amp;quot; → &amp;quot;student&amp;quot;,&amp;quot;studenten&amp;quot; → &amp;quot;student&amp;quot;,&amp;quot;students&amp;quot; → &amp;quot;student&amp;quot;,&amp;quot;questions&amp;quot; → &amp;quot;question&amp;quot;,&amp;quot;levels&amp;quot; → &amp;quot;level&amp;quot;}];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tally = Tally@Cases[StringSplit[text,Except@LetterCharacter],_?(StringLength@#&amp;gt;4&amp;amp;)];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tally = Cases[tally,_?(Last@#&amp;gt;15&amp;amp;)];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tally = Reverse@SortBy[tally,Last];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;range = {Min@(Last&#x2F;@tally),Max@(Last&#x2F;@tally)};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;common = {&amp;quot;the&amp;quot;,&amp;quot;of&amp;quot;,&amp;quot;and&amp;quot;,&amp;quot;to&amp;quot;,&amp;quot;in&amp;quot;,&amp;quot;I&amp;quot;,&amp;quot;that&amp;quot;,&amp;quot;was&amp;quot;,&amp;quot;his&amp;quot;,&amp;quot;he&amp;quot;,&amp;quot;it&amp;quot;,&amp;quot;with&amp;quot;,&amp;quot;is&amp;quot;,&amp;quot;for&amp;quot;,&amp;quot;as&amp;quot;,&amp;quot;had&amp;quot;,&amp;quot;you&amp;quot;,&amp;quot;not&amp;quot;,&amp;quot;be&amp;quot;,&amp;quot;her&amp;quot;,&amp;quot;on&amp;quot;,&amp;quot;at&amp;quot;,&amp;quot;by&amp;quot;,&amp;quot;which&amp;quot;,&amp;quot;have&amp;quot;,&amp;quot;or&amp;quot;,&amp;quot;from&amp;quot;,&amp;quot;this&amp;quot;,&amp;quot;him&amp;quot;,&amp;quot;but&amp;quot;,&amp;quot;all&amp;quot;,&amp;quot;she&amp;quot;,&amp;quot;they&amp;quot;,&amp;quot;were&amp;quot;,&amp;quot;my&amp;quot;,&amp;quot;are&amp;quot;,&amp;quot;me&amp;quot;,&amp;quot;one&amp;quot;,&amp;quot;their&amp;quot;,&amp;quot;so&amp;quot;,&amp;quot;an&amp;quot;,&amp;quot;said&amp;quot;,&amp;quot;them&amp;quot;,&amp;quot;we&amp;quot;,&amp;quot;who&amp;quot;,&amp;quot;would&amp;quot;,&amp;quot;been&amp;quot;,&amp;quot;will&amp;quot;,&amp;quot;no&amp;quot;,&amp;quot;when&amp;quot;,&amp;quot;there&amp;quot;,&amp;quot;if&amp;quot;,&amp;quot;more&amp;quot;,&amp;quot;out&amp;quot;,&amp;quot;up&amp;quot;,&amp;quot;into&amp;quot;,&amp;quot;do&amp;quot;,&amp;quot;any&amp;quot;,&amp;quot;your&amp;quot;,&amp;quot;what&amp;quot;,&amp;quot;has&amp;quot;,&amp;quot;man&amp;quot;,&amp;quot;could&amp;quot;,&amp;quot;other&amp;quot;,&amp;quot;than&amp;quot;,&amp;quot;our&amp;quot;,&amp;quot;some&amp;quot;,&amp;quot;very&amp;quot;,&amp;quot;time&amp;quot;,&amp;quot;upon&amp;quot;,&amp;quot;about&amp;quot;,&amp;quot;may&amp;quot;,&amp;quot;its&amp;quot;,&amp;quot;only&amp;quot;,&amp;quot;now&amp;quot;,&amp;quot;like&amp;quot;,&amp;quot;little&amp;quot;,&amp;quot;then&amp;quot;,&amp;quot;can&amp;quot;,&amp;quot;should&amp;quot;,&amp;quot;made&amp;quot;,&amp;quot;did&amp;quot;,&amp;quot;us&amp;quot;,&amp;quot;such&amp;quot;,&amp;quot;a&amp;quot;,&amp;quot;great&amp;quot;,&amp;quot;before&amp;quot;,&amp;quot;must&amp;quot;,&amp;quot;two&amp;quot;,&amp;quot;these&amp;quot;,&amp;quot;see&amp;quot;,&amp;quot;know&amp;quot;,&amp;quot;over&amp;quot;,&amp;quot;much&amp;quot;,&amp;quot;down&amp;quot;,&amp;quot;after&amp;quot;,&amp;quot;first&amp;quot;,&amp;quot;mr&amp;quot;,&amp;quot;good&amp;quot;,&amp;quot;men&amp;quot;,&amp;quot;worden&amp;quot;,&amp;quot;around&amp;quot;,&amp;quot;based&amp;quot;,&amp;quot;where&amp;quot;,&amp;quot;current&amp;quot;,&amp;quot;because&amp;quot;,&amp;quot;become&amp;quot;,&amp;quot;means&amp;quot;,&amp;quot;already&amp;quot;,&amp;quot;possible&amp;quot;,&amp;quot;through&amp;quot;,&amp;quot;every&amp;quot;,&amp;quot;using&amp;quot;,&amp;quot;kunnen&amp;quot;,&amp;quot;within&amp;quot;,&amp;quot;wordt&amp;quot;,&amp;quot;first&amp;quot;,&amp;quot;second&amp;quot;,&amp;quot;binnen&amp;quot;,&amp;quot;while&amp;quot;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tally = DeleteCases[tally, w_&#x2F;; MemberQ[common,w[[1]]]];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;adding-color-and-rotation&quot;&gt;Adding color and rotation&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;words = Style[First@#, FontFamily -&amp;gt; &amp;quot;Times&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     FontColor -&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      Hue[RandomReal[], RandomReal[{.5, 1}], RandomReal[{.5, 1}]],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     FontSize -&amp;gt; (Last@Rescale[#, range, {12, 150}])] &amp;amp; &#x2F;@ tally;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wordsimg =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ImagePad[#, -3 -&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      BorderDimensions[#]] &amp;amp; &#x2F;@ (Image[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       Graphics[Text[Framed[#, FrameMargins -&amp;gt; 2]]]] &amp;amp; &#x2F;@ words);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;angles = Join[{0, 0, 0}, RandomReal[{-Pi&#x2F;4, Pi&#x2F;4}, 5],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   RandomReal[{-Pi&#x2F;2, Pi&#x2F;2}, Length[wordsimg] - 3 - 5]];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wordsimgRot =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ImageRotate[##, Background -&amp;gt; White] &amp;amp; @@@&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Transpose[{wordsimg, angles}];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;tightly-packing-objects&quot;&gt;Tightly packing objects&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iteration2[img1_, w_, fun_: (Norm[#1 - #2] &amp;amp;)] :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Module[{imdil, centre, diff, dimw, padding, padded1, minpos},&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  dimw = ImageDimensions[w];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  padded1 = ImagePad[img1, {dimw[[1]] {1, 1}, dimw[[2]] {1, 1}}, 1];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  imdil =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Binarize[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ImageCorrelate[Binarize[ColorNegate[padded1], 0.05],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     Dilation[Binarize[ColorNegate[w], 0.05], 5]]];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  centre = ImageDimensions[padded1]&#x2F;2;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  minpos =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Reverse@Nearest[Position[Reverse[ImageData[imdil]], 0],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      Reverse[centre], DistanceFunction -&amp;gt; fun][[1]];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Sow[minpos - centre];(*for creating vector plot*)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  diff = ImageDimensions[imdil] - dimw;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  padding[pos_] := Transpose[{#, diff - #} &amp;amp;@Round[pos - dimw&#x2F;2]];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ImagePad[#, (-Min[#] {1, 1}) &amp;amp; &#x2F;@ BorderDimensions[#]] &amp;amp;@&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   ImageMultiply[padded1, ImagePad[w, padding[minpos], 1]]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;poslist =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; Reap[img = Fold[iteration2, wordsimgRot[[1]], Rest[wordsimgRot]];][[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  2, 1]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The crux of the algorithm is a call to &lt;code&gt;ImageCorrelate&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;converting-back-to-vector&quot;&gt;Converting back to vector&lt;&#x2F;h2&gt;
&lt;p&gt;We now have coordinates for the bitmap images. We re-use these
coordinates to create new &lt;code&gt;Text&lt;&#x2F;code&gt; entries. This is to convert it back to
a vector image.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Graphics[MapThread[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Text[#1, Offset[#2, {0, 0}], {0, 0}, {Cos[#3], Sin[#3]}] &amp;amp;, {words,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Prepend[poslist, {0, 0}], angles}]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mathematica.stackexchange.com&#x2F;questions&#x2F;2334&#x2F;how-to-create-word-clouds&quot;&gt;https:&#x2F;&#x2F;mathematica.stackexchange.com&#x2F;questions&#x2F;2334&#x2F;how-to-create-word-clouds&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>White paper on Coblue&#x27;s Mesh Network</title>
        <published>2015-07-01T00:00:00+00:00</published>
        <updated>2015-07-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/15/coblue-mesh-network/"/>
        <id>https://2π.com/15/coblue-mesh-network/</id>
        
        <content type="html" xml:base="https://2π.com/15/coblue-mesh-network/">&lt;h1 id=&quot;white-paper-on-coblue-s-mesh-network&quot;&gt;White paper on Coblue&#x27;s Mesh Network&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;aphyr.com&#x2F;posts&#x2F;313-strong-consistency-models&lt;&#x2F;li&gt;
&lt;li&gt;http:&#x2F;&#x2F;www.ics.forth.gr&#x2F;tech-reports&#x2F;2013&#x2F;2013.TR439_Survey_on_Consistency_Conditions.pdf&lt;&#x2F;li&gt;
&lt;li&gt;http:&#x2F;&#x2F;www.bailis.org&#x2F;papers&#x2F;hat-hotos2013.pdf&lt;&#x2F;li&gt;
&lt;li&gt;http:&#x2F;&#x2F;lcamtuf.coredump.cx&#x2F;afl&#x2F;README.txt&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Mutation_testing&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.cloudflare.com&#x2F;dns-parser-meet-go-fuzzer&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Goal&lt;&#x2F;strong&gt;: Get close to theoretical goodput on a 10s round trip time 90% loss connection.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal&lt;&#x2F;strong&gt;: Low latency.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal&lt;&#x2F;strong&gt;: Low overhead.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal&lt;&#x2F;strong&gt;: High security.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal&lt;&#x2F;strong&gt;: Thwart &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Deep_packet_inspection&quot;&gt;deep packet inspection&lt;&#x2F;a&gt;. The protocol should be sufficiently obfuscated that conventional tools do not recognize the traffic.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Goal&lt;&#x2F;strong&gt;: Work in third world scenarios: http:&#x2F;&#x2F;www.spice-center.org&#x2F;files&#x2F;publications&#x2F;LEDBAT_Performance_in_Sub-packet_Regimes.pdf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sockets&quot;&gt;Sockets&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;udp&quot;&gt;UDP&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;tcp&quot;&gt;TCP&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;http&quot;&gt;HTTP&lt;&#x2F;h3&gt;
&lt;p&gt;The HTTP socket is the fall back option. It&#x27;s goal is to work under any
circumstance that HTTP requests are made, potentially through badly functioning
proxy servers. It will work on the simplest proxy server that will cache every
request in full, before replying to the client. As such, it does not use
techniques like response chunking or WebSockets. It does use http pipelining, if
available.&lt;&#x2F;p&gt;
&lt;p&gt;Requests are encoded as BMP formatted images and send using a POST request to
a unique one time URL. The server delays response until it has data to send.
On idle, the http connections has three requests &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Push_technology#Long_polling&quot;&gt;long-polling&lt;&#x2F;a&gt; on the server, and
three slots available on the client.&lt;&#x2F;p&gt;
&lt;p&gt;To offset the large per-packet overhead and the lack of TCP congestion control if a TCP session is initiated per request (i.e. no pipelining), the packet size is set to 100 kilobytes.&lt;&#x2F;p&gt;
&lt;p&gt;The technique used is similar to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;xmpp.org&#x2F;extensions&#x2F;xep-0124.html&quot;&gt;BOSH&lt;&#x2F;a&gt;.
Where BOSH has at most two connections open, we have a limit of six. The steady state being three
at the server and three at the client. Where BOSH is limited to at most one push
per RTT, ours can do three.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;handshake&quot;&gt;Handshake&lt;&#x2F;h2&gt;
&lt;p&gt;Given a datagram based &lt;em&gt;Socket&lt;&#x2F;em&gt; with the following operations:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint maxMessageSize();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;void send(ByteArray message);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ByteArray read();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Handshake:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A → B: AE ‖ msg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A ← B: BE ‖ enc[seed ‖ be AE, nonce₁](B) ‖ nonce ‖ enc[be AE ‖ b AE, nonce](msg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A ⇉ B: enc[seed ‖ ae BE ‖ ae B, nonce₃](A) ‖ *secure channel*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A ⇆ B: *secure channel*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Secure channel:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A ⇇ B: nonce ‖ enc[ae BE ‖ ae B ‖ a BE ‖ AE, nonce](msg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;A ⇇ B: nonce ‖ enc[ae BE ‖ ae B ‖ a BE ‖ BE, nonce](msg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;seed = &amp;quot;\360\334\010\310\147\152\250\245\333\337\277\104\050\023\230\321&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       &amp;quot;\074\177\107\002\317\143\241\334\367\337\171\142\303\256\046\027&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nonce₁ = &amp;quot;\102\353\364\202\222\060\342\221\166\114\273\343\207\031\143\330&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         &amp;quot;\331\262\214\115\322\255\311\372\362\316\164\330\346\322\352\206&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nonce₃ = &amp;quot;\125\246\262\144\224\211\063\372\027\051\375\265\037\374\053\141&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;         &amp;quot;\042\004\166\157\053\321\145\133\156\110\014\003\212\050\152\304&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Repeated reception of the same AE.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Other handshake packets are tied to the first one by the ephemeral key.&lt;&#x2F;p&gt;
&lt;p&gt;uint8 nonce, uint16 send&lt;&#x2F;p&gt;
&lt;p&gt;uint8 nonce, uint16 send, uint8 origNonce, uint16 received&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Initiator:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Send AE and repeat until a correct response is received.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Responder:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Receive AE.&lt;&#x2F;li&gt;
&lt;li&gt;Send response.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;strong&gt;Proposal&lt;&#x2F;strong&gt;: If the RTT is very large, do a&lt;&#x2F;p&gt;
&lt;p&gt;B sends a recent PeerInfo as it&#x27;s first message. B can not have a send buffer at
this point.&lt;&#x2F;p&gt;
&lt;p&gt;A sends a recent PeerInfo, followed by anything from it&#x27;s send buffer.&lt;&#x2F;p&gt;
&lt;p&gt;A secure channel has established authentication between two publick keys representing the two endpoints. The endpoints can then bidirectionally exchange datagrams.&lt;&#x2F;p&gt;
&lt;p&gt;It can signal &lt;em&gt;readable&lt;&#x2F;em&gt; if it has one or more messages in its receive buffer.&lt;&#x2F;p&gt;
&lt;p&gt;It can signal &lt;em&gt;writeable&lt;&#x2F;em&gt; if it has room in its send buffer for one or more messages.&lt;&#x2F;p&gt;
&lt;p&gt;The API returns the maximum size of a datagram. Write calls on larger datagrams will fail.&lt;&#x2F;p&gt;
&lt;p&gt;When writing a datagram, the API returns a sequence number. This is the number of datagrams written before it.&lt;&#x2F;p&gt;
&lt;p&gt;When reading datagrams, the API returns a sequence number. This is the same as the sequence number the write call on the remote end returned.&lt;&#x2F;p&gt;
&lt;p&gt;Although the sequence numbers correspond, read calls do not receive the datagrams in order.&lt;&#x2F;p&gt;
&lt;p&gt;Datagrams may fail to be delivered. Neither end gets notified of this. The reading end can discovered a failed transmission by a missing sequence number.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;handshake-flow-control&quot;&gt;Handshake Flow Control&lt;&#x2F;h3&gt;
&lt;p&gt;The handshake is critical and all packets are necessary. By protocol, a handshake packet must be received before the reply can be constructed. The protocol necessarily happens in lock-step. A natural solution is to keep broadcasting the packet until the correct response is received.&lt;&#x2F;p&gt;
&lt;p&gt;Every packet in the handshake can contain a message. The first message will have no security guarantees whatsoever. The second will have all the security guarantees, except the receiver is not authenticated. The third and last message is fully secure and can carry application data. Since it is send by the initiator, it likely contains the request the initiator wants to make to the other peer.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every internet module must be able to forward a datagram of 68 octets without further fragmentation.  This is because an internet header may be up to 60 octets, and the minimum fragment is 8 octets.&lt;&#x2F;p&gt;
&lt;p&gt;Every internet destination must be able to receive a datagram of 576 octets either in one piece or in fragments to be reassembled.&lt;&#x2F;p&gt;
&lt;p&gt;— &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc791#page-25&quot;&gt;RFC 796&lt;&#x2F;a&gt; “Internet Protocol” page 25, September 1981.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;IPv6 requires that every link in the internet have an MTU of 1280 octets or greater.  On any link that cannot convey a 1280-octet packet in one piece, link-specific fragmentation and reassembly must be provided at a layer below IPv6.&lt;&#x2F;p&gt;
&lt;p&gt;— &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc2460#page-24&quot;&gt;RFC 2460&lt;&#x2F;a&gt; “Internet Protocol, Version 6 (IPv6)” section 5, December 1998.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;We have to decide on an MTU for the handshake. The 68 byte value is too conservative: after subtracting the minimal 28 bytes for IPV4&#x2F;UDP headers only 40 bytes are left. The largest message during the handshake is 128 bytes. To prevent fragmenting handshake messages we choose a fixed 576 byte MTU during the handshake. We rely on IP fragmentation and reassembly to handle extremely small MTUs during the handshake.&lt;&#x2F;p&gt;
&lt;p&gt;Initial flow control measurements happen during the handshake. All handshake messages include a 16 bit unique random cookie, a 16 bit time stamp in milliseconds and optionally a 16 bit cookie echo. On reception of a handshake packet the cookie will be echoed in the reply. The cookie allows the the connection to measure package loss and the round-trip-time. The time stamp allows the nodes to measure clock skew.&lt;&#x2F;p&gt;
&lt;p&gt;Only the initial flow control message is in clear text, but it reveals nothing. The first cookies is entirely random. For every connection a random offset is generated and consistently added to the clock. For the first message it acts as a one-time-pad encryption.&lt;&#x2F;p&gt;
&lt;p&gt;Retransmission follows an exponential back off. The first re-transmission happens after 20 milliseconds, subsequent retransmission intervals increase by 10% to a maximum of 500 ms. If a round trip time has been measured, twice the measured round trip time is used as the initial value instead of 20 milliseconds. This transmission strategy sends out 19 packages in the first second. After 5 seconds and 36 packets it stabilizes on the 500 ms interval. After 37 seconds and 100 packets it aborts. Retransmission continues until reception is confirmed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;: Check if public keys are close enough to being uniformly random.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;: Although all bytes are indistinguishable from random noise, the packet lengths and timings may still reveal information. We could pad the handshake packets with random bits. We could introduce jitter.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;path-maximum-transmission-size-discovery&quot;&gt;Path Maximum Transmission Size Discovery&lt;&#x2F;h2&gt;
&lt;p&gt;Packetization Layer Path MTU Discovery&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc4821&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Congestion Control Principles&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc2914&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Byte and Packet Congestion Notification&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc7141&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;acknowledgement&quot;&gt;Acknowledgement&lt;&#x2F;h2&gt;
&lt;p&gt;The acknowledgement scheme is similar to NR-SACK. Selective acknowledgement without re-negging. In addition, retransmissions get new sequence numbers. Sequence numbers correspond to one exact send.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 timestamp, uint8 number [ uint16 seqno, uint16 timestamp ]*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A packet with data always get&#x27;s ACKed.&lt;&#x2F;p&gt;
&lt;p&gt;A packet with only ACKs gets ACKed if its ACKs have ACKed data.&lt;&#x2F;p&gt;
&lt;p&gt;Other packages do not get ACKed.&lt;&#x2F;p&gt;
&lt;p&gt;The sender retransmits package contents after 2 round trip times.&lt;&#x2F;p&gt;
&lt;p&gt;Receiving data &lt;em&gt;must&lt;&#x2F;em&gt; be idempotent.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;congestion-control&quot;&gt;Congestion control&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;jacobson-karels-algorithm&quot;&gt;Jacobson &#x2F; Karels algorithm&lt;&#x2F;h3&gt;
&lt;p&gt;We give every transmitted package a unique sequence number, even on retransmit. Round-trip time measurements are therefore not influenced by retransmit. We also include the remotes reception timestamps. This allows the remote to delay sending the ACK without influencing the round trip time estimate. However, if the round-trip time changes during the time an ACK is delay, the measured RTT will be an average of the old and new RTT.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Karn&#x2F;Patridge algorithm&lt;&#x2F;strong&gt; Algorithm The RTT estimator &lt;span class=&quot;math math-inline&quot;&gt;\hat R&lt;&#x2F;span&gt; is updated with RTT samples &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; using:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\hat R_{i + 1} = (1 - α) \hat Rᵢ + α Rᵢ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with  suggests &lt;span class=&quot;math math-inline&quot;&gt;α = .1 … .2&lt;&#x2F;span&gt;. The retransmission timeout &lt;span class=&quot;math math-inline&quot;&gt;T&lt;&#x2F;span&gt; is defined as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
T_{i+1} = \begin{cases}
   2 Tᵢ &amp;amp; \text{on retransmit} \\
	\min (T_{\text{min}},\max(β \hat Rᵢ , T_{\text{max}})) &amp;amp; \text{otherwise}
\end{cases}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with &lt;span class=&quot;math math-inline&quot;&gt;β = 1.3 … 2.0&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;T_{\text{min}} = 1\,\text{s}&lt;&#x2F;span&gt; second and &lt;span class=&quot;math math-inline&quot;&gt;T_{\text{max}} = 60\,\text{s}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc793#page-41&quot;&gt;RFC 793&lt;&#x2F;a&gt; “Transmission Control Protocol”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc1122#page-95&quot;&gt;RFC1122&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Jacobson&#x2F;Karels algorithm&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
Δᵢ &amp;amp;= Rᵢ - \hat Rᵢ \\
\hat R_{i + 1} &amp;amp;= \hat Rᵢ + δ Δᵢ \\
σ_{i+1} &amp;amp;= σᵢ + δ( |Δᵢ| - σᵢ) \\
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Tᵢ = μ \hat Rᵢ + φ σᵢ
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;with &lt;span class=&quot;math math-inline&quot;&gt;μ = 1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;φ = 4&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;http:&#x2F;&#x2F;ee.lbl.gov&#x2F;papers&#x2F;congavoid.pdf&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;LEDBAT&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;http:&#x2F;&#x2F;www.perso.telecom-paristech.fr&#x2F;~drossi&#x2F;paper&#x2F;rossi10icccn.pdf&lt;&#x2F;li&gt;
&lt;li&gt;http:&#x2F;&#x2F;tma2012.ftw.at&#x2F;TMA&#x2F;pres&#x2F;TMA2012-talk7.pdf&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.internetsociety.org&#x2F;sites&#x2F;default&#x2F;files&#x2F;pdf&#x2F;accepted&#x2F;17_delay_cc_pos-v2.pdf&lt;&#x2F;li&gt;
&lt;li&gt;http:&#x2F;&#x2F;citeseerx.ist.psu.edu&#x2F;viewdoc&#x2F;download?doi=10.1.1.296.6350&amp;amp;rep=rep1&amp;amp;type=pdf&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;http:&#x2F;&#x2F;netlab.caltech.edu&#x2F;publications&#x2F;CJindelay_ccw03.pdf&lt;&#x2F;p&gt;
&lt;h2 id=&quot;network-model&quot;&gt;Network model&lt;&#x2F;h2&gt;
&lt;p&gt;The transit time of a packet is&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
   \text{delay} + \frac{\text{packet size } + \text{ queue size}}{\text{bandwidth}}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
R = d + \frac{Q}{b} + \frac{1}{b} m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Delay-dominated&lt;&#x2F;em&gt;: delay is the primary source of RTT.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Bandwidth-dominated&lt;&#x2F;em&gt;: the time to transmit a single packet dominates the RTT.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Congested&lt;&#x2F;em&gt;: the queue of other packages dominates the RTT.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We assume delay and bandwidth to be fixed. The queue size has two components, our own queued packages and other packages. The queue size contribution of other packages is modeled as a random walk.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Transients&lt;&#x2F;strong&gt;: Rerouting can suddenly change delay and bandwidth. Any algorithm should quickly recover and converge to the new parameters.&lt;&#x2F;p&gt;
&lt;p&gt;Some simplifications: package corruption is treated the same as package loss, package order is ignored.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ledbat&quot;&gt;LEDBAT&lt;&#x2F;h2&gt;
&lt;p&gt;(RFC 6817)[https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc6817] “Low Extra Delay Background Transport (LEDBAT)”&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;http:&#x2F;&#x2F;bittorrent.org&#x2F;beps&#x2F;bep_0029.html&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;kalman-filter&quot;&gt;Kalman filter&lt;&#x2F;h2&gt;
&lt;p&gt;Network state:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Base delay&lt;&#x2F;li&gt;
&lt;li&gt;Bandwidth&lt;&#x2F;li&gt;
&lt;li&gt;Loss model (Gilbert-Elliot loss model, 4 parameters)&lt;&#x2F;li&gt;
&lt;li&gt;Path maximum transmission unit&lt;&#x2F;li&gt;
&lt;li&gt;Queue size&lt;&#x2F;li&gt;
&lt;li&gt;Current loss state (good &#x2F; bad)&lt;&#x2F;li&gt;
&lt;li&gt;Queue fill (and hence Queue full)&lt;&#x2F;li&gt;
&lt;li&gt;Competing transmissions&lt;&#x2F;li&gt;
&lt;li&gt;Clock offset&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Observables:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Delay&lt;&#x2F;li&gt;
&lt;li&gt;Loss&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Controls:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;asd&quot;&gt;asd&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;645115&#x2F;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;http:&#x2F;&#x2F;caia.swin.edu.au&#x2F;cv&#x2F;dahayes&#x2F;content&#x2F;networking2011-cdg-preprint.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;http:&#x2F;&#x2F;www.wseas.us&#x2F;journals&#x2F;cc&#x2F;cc-27.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;http:&#x2F;&#x2F;www.appexnetworks.com&#x2F;white-papers&#x2F;ZetaTCP.pdf&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Rules&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;There is no ACK for packages without data.&lt;&#x2F;li&gt;
&lt;li&gt;A seqno stays in the ACK list until a CMP has been received.&lt;&#x2F;li&gt;
&lt;li&gt;A CMP is generated for entry in the ACK list.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Idea: The above can be optimized, the CMP only needs to ACK the packet containing ACKs.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;There is no ACK for packages that ACK ACKs.&lt;&#x2F;li&gt;
&lt;li&gt;A seqno stays in the ACK list until a packet containing it has been ACKed.&lt;&#x2F;li&gt;
&lt;li&gt;A CMP is generated for entry in the ACK list.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When to ACK: When the expected cost of a retransmit would be greater. This cost is a function of the retransmission probability and the delay and bandwidth of the retransmit.&lt;&#x2F;p&gt;
&lt;p&gt;The sender can flag a packet as to be ACKed. Any such packet will be ACKed.&lt;&#x2F;p&gt;
&lt;p&gt;Packages with data get a 0.
Packages ACKing those get a 1.
Packages ACKing those get a 2.
Packages with a 2 are not ACKed.&lt;&#x2F;p&gt;
&lt;p&gt;0 Request two way ACK.
1 Request one way ACK.
2 No ACK required.
3&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;No ACK required&lt;&#x2F;li&gt;
&lt;li&gt;Request ACK&lt;&#x2F;li&gt;
&lt;li&gt;Request immediate ACK&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Delayed ACK versus immediate ACK?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc2581#section-4.2&quot;&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc2581#section-4.2&lt;&#x2F;a&gt; TCP Delayed Acknowledgement&lt;&#x2F;p&gt;
&lt;p&gt;Packet 1 data 0 →
Packet 2 data 0 →
Packet 3 data 0 →&lt;&#x2F;p&gt;
&lt;p&gt;← Packet 1: 1 Ack 1,2,3&lt;&#x2F;p&gt;
&lt;p&gt;→ Packet 4 0 data + Ack 1
→ Packet 5 0 data
→ Packet 6 0 data&lt;&#x2F;p&gt;
&lt;p&gt;← Packet 2: 1 Ack 4,5,6&lt;&#x2F;p&gt;
&lt;p&gt;→ Packet 7: 2 Ack 2&lt;&#x2F;p&gt;
&lt;p&gt;← Packet 3: 1 Ack 4,5,6&lt;&#x2F;p&gt;
&lt;p&gt;→ Packet 8: 2 Ack 2,3&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;NOTE: Repeating until ACK is not a viable strategy. We could transmit the ACK 1—n times. For 10% loss, two transmissions are sufficient for &amp;gt;99% reception. For 10% transmission success 7 repeats are needed to get &amp;gt;50% chance of reception. This however assumes loss is uncorrelated, which is unlikely.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;NOTE: For a given loss rate, say 10%, there will be the retransmission of the 10% plus the retransmission of the 10% of which the ACKs where lost. This works cumulatively.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;retransmission occurs if either the packet itself or it&#x27;s ACK is dropped. This roughly doubles&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;How long to wait for package re-order before considering a package drop?
How to retransmit segments lost in dropped packages?
What if the packet is lost due to being too large? (Retransmit won&#x27;t work)&lt;&#x2F;p&gt;
&lt;p&gt;Idea 1: Retransmit the entire package using the same sequence number. Easiest to implement. Might retransmit packages that do not require it (streaming protocols). (NOTE: this blocks the line retransmitting old data while more important new data might be in the send buffer)&lt;&#x2F;p&gt;
&lt;p&gt;Idea 2: Same as idea 1, except we remove all droppable segments. (ERROR: The packet would be encrypted with the same key. It needs to be identical or it will reveal the xor of the old and new content.)&lt;&#x2F;p&gt;
&lt;p&gt;Idea 3: The freed up space is filled with new segments. (ERROR: This doesn&#x27;t work, if we then receive an ACK for the seqno. we do not know if it was for the old or new set of segments. (This is not a problem if we fill using other dropable segments))&lt;&#x2F;p&gt;
&lt;p&gt;Idea 3: Drop the seqno entirely and put the non-droppable chunks back on the send queue. (NOTE: The client might still receive the old package, and thus double receive the segments. The old and new transmission can be received in any order. Receiving chunks must be idempotent.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;No renegging&lt;&#x2F;strong&gt;: If a sequence number is acknowledged it will remain acknowledged. No renegging. Since entire datagrams are lost, a lost sequence number means loss of all segments in that sequence. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.eecis.udel.edu&#x2F;~amer&#x2F;PEL&#x2F;poc&#x2F;pdf&#x2F;ICNP2008-natarajanNonRenegableSacks.pdf&quot;&gt;http:&#x2F;&#x2F;www.eecis.udel.edu&#x2F;~amer&#x2F;PEL&#x2F;poc&#x2F;pdf&#x2F;ICNP2008-natarajanNonRenegableSacks.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;No retransmission&lt;&#x2F;strong&gt;: Is a sequence number is lost it will not be used again. Sequence numbers emited from the sender are strictly sequentially increasing.&lt;&#x2F;p&gt;
&lt;p&gt;The sender retransmits the segment data that was lost.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Detecting Reorder versus Loss&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;research.microsoft.com&#x2F;en-us&#x2F;people&#x2F;lguohan&#x2F;reorder-icoin04.pdf&quot;&gt;http:&#x2F;&#x2F;research.microsoft.com&#x2F;en-us&#x2F;people&#x2F;lguohan&#x2F;reorder-icoin04.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;on average 8 of the 50 packets were identified as being out of order&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;We analyze 208 thousand
connections with totally 3.3 million data pack
ets, and observe that about 3.2% of all
the packets are reordered.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Figure 5 shows the packet lag of reordering and retransmission. 86.5% of reor-
dered packets left behind only 1 packet and 95.3% of reordered packets left behind
within 2 packets. Packet lag of retransmission has a dispersed distribution and larger
average. About 78.8% of retransmitted packets left behind with a lag of 3 or more
packets&quot;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;The common portion of packets affected
by reordering is in the order of 0.01 % to 1.65 %, or 1 %
to 1.5 %&quot;&lt;&#x2F;p&gt;
&lt;p&gt;So re-ordering happens to about max 5% of packets and 95% is re-ordered within 3 packets.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc5236&quot;&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc5236&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Long Fat Networks&lt;&#x2F;strong&gt;: 10 Gbit&#x2F;s, 50 ms RTT = 59.6 MB.&lt;&#x2F;p&gt;
&lt;p&gt;Configuration        Bandwidth       Round-trip time&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Long fat network                10 Gbit&#x2F;s           50 ms    64  MB
Satellite connection           512 kbit&#x2F;s          900 ms    58  kB
Voyager Deep Space Network     115.2 kbit&#x2F;s         36 h     1.8 GB&lt;&#x2F;p&gt;
&lt;p&gt;Assuming packets of at least 1200 bytes a 64 MB bandwidth-delay product means 55924 packets unACKed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc3393&quot;&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc3393&lt;&#x2F;a&gt; IP Packet Delay Variation Metric for IP Performance Metrics (IPPM)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;header&quot;&gt;Header&lt;&#x2F;h3&gt;
&lt;p&gt;5-n byte header&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 miliseconds;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 counter;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint8 nacks;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint8[] rle_acks;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;multiplexed-sub-channels&quot;&gt;Multiplexed Sub-channels&lt;&#x2F;h2&gt;
&lt;p&gt;The multiplexer transmits datagrams of arbitrary size. Datagrams are prioritized and can have optional delivery guarantees.&lt;&#x2F;p&gt;
&lt;p&gt;When the socket is writeable the multiplexer takes datagrams that need to be sent in order of priority.&lt;&#x2F;p&gt;
&lt;p&gt;It turns the datagrams into arbitrarily sized segments and constructs a maximum datagram size datagram out of them for the lower layer.&lt;&#x2F;p&gt;
&lt;p&gt;For each segment of guaranteed-delivery datagrams it stores the sequence number it was included in.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Segmentation&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 channel;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint32 datagram_size;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint32 datagram_offset;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 segment_size; &#x2F;&#x2F; in multiples of 8 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint8[] data;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A datagram to be send is transfered in chunks.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 channel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 datagram_no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 offset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 length&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 channel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 datagram_no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 offset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 length&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note: Due to packet loss and changes in available room, the ACKed information of a datagram can be complex.&lt;&#x2F;p&gt;
&lt;p&gt;Given a secure channel that provides us with out-of-order unrepeated delivery of datagrams. This means send messages can be delivered in any order, or not at all but are never repeated.&lt;&#x2F;p&gt;
&lt;p&gt;The sequence number is available to higher levels of the stack.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Bundling&lt;&#x2F;strong&gt;: The Channel does not send every datagram immediately. It waits until the event loop is idle.
This is useful if efficiency is more important than latency.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Selective Acknowledgement&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Low-latency unreliable unordered delivery&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are 2¹⁶ channels numbered from zero. The zeroth channel is opened on connection establishment and speaks the control protocol.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Immediate Selective Acknowledge&lt;&#x2F;li&gt;
&lt;li&gt;Unordered (but can still be fragmented)&lt;&#x2F;li&gt;
&lt;li&gt;First fragment&lt;&#x2F;li&gt;
&lt;li&gt;Last fragment&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;A channel is configured by setting the protocolId&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;CONFIGURE(protocolId, channel options)&lt;&#x2F;li&gt;
&lt;li&gt;CONFIGURE-ACK(protocolId, channel options)&lt;&#x2F;li&gt;
&lt;li&gt;CONFIGURE-COMPLETE&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;ALC operates on datagrams&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Request-response&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Bi-directional Unreliable Low-Latency Datagram Stream&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Publish-subscribe&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Push-pull&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Channel has:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Priority.&lt;&#x2F;li&gt;
&lt;li&gt;Reliable&#x2F;unreliable delivery.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation:&lt;&#x2F;h2&gt;
&lt;p&gt;For every external Peer there is a PriorityQueue.&lt;&#x2F;p&gt;
&lt;p&gt;For incoming messages there is a PriorityQueue.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Max one connection per peer.&lt;&#x2F;li&gt;
&lt;li&gt;Max one thread per core.&lt;&#x2F;li&gt;
&lt;li&gt;Each thread handles multiple connections.&lt;&#x2F;li&gt;
&lt;li&gt;Only async IO.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;comparison-with-alternatives&quot;&gt;Comparison with alternatives&lt;&#x2F;h2&gt;
&lt;p&gt;See: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Transport_layer#COMPARISON1&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SCTP_packet_structure&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CurveCP&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;∅MQ&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;SCTP&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;SST &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;pdos.csail.mit.edu&#x2F;uia&#x2F;sst&#x2F;&quot;&gt;http:&#x2F;&#x2F;pdos.csail.mit.edu&#x2F;uia&#x2F;sst&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;MUX&#x2F;SMUX &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;Protocols&#x2F;MUX&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;Protocols&#x2F;MUX&#x2F;&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.w3.org&#x2F;TR&#x2F;WD-mux&quot;&gt;http:&#x2F;&#x2F;www.w3.org&#x2F;TR&#x2F;WD-mux&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;SCP &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ibiblio.org&#x2F;ses&#x2F;scp.html&quot;&gt;http:&#x2F;&#x2F;www.ibiblio.org&#x2F;ses&#x2F;scp.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc2488 Enhancing TCP Over Satellite Channels&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc2018 TCP Selective Acknowledgment Options&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc1323 TCP Extensions for High Performance&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc4960 Stream Control Transmission Protocol&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;appendix-clocks-and-time-synchronization&quot;&gt;Appendix: Clocks and time synchronization&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Round Trip Time Clock&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint32 timestamp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc1323#page-11&quot;&gt;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc1323#page-11&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Jacobson&#x2F;Karels_algorithm&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Jacobson&#x2F;Karels_algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note: TCP seems to maintain a lot of state on the wire in stead of in the ends. Sending the timestamp for the purpose of RTT estimation is unnecessary. The remote end can&#x27;t interpret the numbers anyway.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hybrid Logical Clock&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint32 seconds;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 fractional;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint16 counter;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.muratbuffalo.blogspot.com&#x2F;2014_07_01_archive.html&quot;&gt;http:&#x2F;&#x2F;www.muratbuffalo.blogspot.com&#x2F;2014_07_01_archive.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cse.buffalo.edu&#x2F;tech-reports&#x2F;2014-04.pdf&quot;&gt;http:&#x2F;&#x2F;www.cse.buffalo.edu&#x2F;tech-reports&#x2F;2014-04.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Network Time Protocol&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint32 seconds;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint32 fractional;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Proposed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint64 seconds;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uint64 fractional;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;NTP over internet has about 10 ms resolution. Under the best circumstances it can be 1 ms. Under less advantageous circumstances it can be 100 ms.&lt;&#x2F;p&gt;
&lt;p&gt;It seems that 1 ms is the maximum reasonable resolution.&lt;&#x2F;p&gt;
&lt;p&gt;If we assume an inferior clock synchronization algorithm that is able to determine the clock delta between two peers up to 10 second resolution.&lt;&#x2F;p&gt;
&lt;p&gt;The client can then sent an uint16 clock representing the least significant bits of the true time in milliseconds. This has a range of more than a minute with ms resolution.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Combined Clock and Seqno&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&quot;TCP timestamps (RFC 1323) play a double role: they avoid ambiguities due to the 32-bit sequence number field wrapping around, and they allow more precise RTT estimation in the presence of multiple losses per RTT. With those improvements, it becomes reasonable to increase the TCP window beyond 64 kB, which can be done using the window scaling option (RFC 1323).&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendix-deep-packet-inspectors&quot;&gt;Appendix: Deep Packet Inspectors&lt;&#x2F;h2&gt;
&lt;p&gt;We look at the implementation of several hard to detect protocols. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;vbn.aau.dk&#x2F;files&#x2F;78068418&#x2F;report.pdf&quot;&gt;Comparison study&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;PACE&lt;&#x2F;strong&gt;: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ipoque.com&#x2F;products&#x2F;pace&quot;&gt;PACE&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;nDPI&lt;&#x2F;strong&gt;: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ntop.org&#x2F;products&#x2F;deep-packet-inspection&#x2F;ndpi&#x2F;&quot;&gt;nDPI&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ntop&#x2F;nDPI&quot;&gt;github&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ntop&#x2F;nDPI&#x2F;blob&#x2F;dev&#x2F;src&#x2F;lib&#x2F;protocols&#x2F;tor.c&quot;&gt;Tor&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ntop&#x2F;nDPI&#x2F;blob&#x2F;dev&#x2F;src&#x2F;lib&#x2F;protocols&#x2F;skype.c&quot;&gt;Skype&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ntop&#x2F;nDPI&#x2F;blob&#x2F;dev&#x2F;src&#x2F;lib&#x2F;protocols&#x2F;bittorrent.c&quot;&gt;BitTorrent&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;libprotoident&lt;&#x2F;strong&gt;: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;research.wand.net.nz&#x2F;software&#x2F;libprotoident.php&quot;&gt;libprotoident&lt;&#x2F;a&gt; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;wanduow&#x2F;libprotoident&quot;&gt;github&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;wanduow&#x2F;libprotoident&#x2F;blob&#x2F;master&#x2F;lib&#x2F;tcp&#x2F;lpi_tor.cc&quot;&gt;Tor&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;wanduow&#x2F;libprotoident&#x2F;blob&#x2F;master&#x2F;lib&#x2F;udp&#x2F;lpi_skype.cc&quot;&gt;Skype&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;appendix-overhead-calculation&quot;&gt;Appendix: Overhead calculation&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;First handshake message: 56 byte public key + 2 byte cookie + 2 byte timestamp = 60 bytes&lt;&#x2F;li&gt;
&lt;li&gt;Second handshake message: 2 * 56 byte public key + 16 byte tag + 2 byte cookie + 2 byte timestamp + 2 byte reply = 134 bytes&lt;&#x2F;li&gt;
&lt;li&gt;Third handshake message: 56 byte public key + 16 byte tag + 6 byte cookie&#x2F;reply - 13 byte saved channel overhead = 65 bytes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Total handshake overhead: 259 bytes. Likely more in practice due to early retransmissions of the first handshake message until an accurate round trip time is known.&lt;&#x2F;p&gt;
&lt;p&gt;Per packet overhead: 2 byte seqno + 8 byte tag + 3 byte header + 4 byte ack = 17 bytes.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Not included yet: hybrid logical clocks.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CHE-1</title>
        <published>2014-09-21T00:00:00+00:00</published>
        <updated>2015-04-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/che/che/"/>
        <id>https://2π.com/14/che/che/</id>
        
        <content type="html" xml:base="https://2π.com/14/che/che/">&lt;h1 id=&quot;che-1&quot;&gt;CHE-1&lt;&#x2F;h1&gt;
&lt;p&gt;I took a deep dive into my own history. The quest was to find the old manuals of my first computer. I found it &#x27;under&#x27; my mom&#x27;s house. Not kidding! Equipped with a torch I went through two basements into the crawling space under the living room. There I confronted a heavy wall of boxes crammed with books. Buried deep under that wall I found a dusty grey ring binder inscribed with &#x27;THT&#x27;, an ancient acronym for the local university. But it was worth it! Turns out my first computer was a cool homebrewn
Apple IIe clone. This is what they looked like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;full.jpeg&quot; alt=&quot;The CHE-1 with the CaCHE enclosure and TOuCHE keyboard. Source: http:&#x2F;&#x2F;www.applefritter.com&#x2F;node&#x2F;193 © 2004 Tom Owad, Gerard Goorden.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;They where hand build, so all looked slightly different. I think mine
was rougher.&lt;&#x2F;p&gt;
&lt;p&gt;I must have been 7 or 8 years old when I had this machine, so it was
around &#x27;94. The machine was well obsolete by then, which explains why it
ended up in my bedroom. It was the first of more than a dozen or so
obsolete computers that somehow ended up in my room.&lt;&#x2F;p&gt;
&lt;p&gt;This one is a rather special. In many ways it represents the Silicon
Valley spirit brought to the Netherlands.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;manual.jpeg&quot; alt=&quot;The manual comes with schematics, blueprints and even masks. © 1981 Computer Hobbyvereniging Eindhoven&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Early in the 80’s a group of Natlab employees (Philips Research Center
in Eindhoven), came together and worked on a computer in their spare
time. It would be an Apple IIe clone, but one that you could build
yourself. The group organized as the “Computer Hobbyclub Eindhoven”, or
CHE for short. It had some similarities to the famous &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Homebrew_Computer_Club&quot;&gt;Homebrew Computer
Club&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;motherboard-photomask.jpeg&quot; alt=&quot;The 6052 processor is in the upper left corner.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I remember how over the years computer manuals started including less
and less technical details. An early VGA graphics card I used came with
a manual that included a full specification of all its registers. This
sort og openness allows hackers to push the boundaries. Here’s one
creative genius that managed to go beyond what was possible:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;When I was 11, I won 50 pounds in a competition for writing this
program that made sound on a ZX81. You couldn’t make sound on a ZX81,
but I played around with machine code and found some codes that retuned
the TV signal so that it made this really weird noise when you turned
the volume up.&lt;&#x2F;p&gt;
&lt;p&gt;— Richard James (better known as Aphex Twin) (&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.aphextwin.nu&#x2F;learn&#x2F;100771194880071.shtml&quot;&gt;source&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Today, this sort of detailed technical information is a trade secret.
You can only find the register mappings of AMD&#x2F;ATI and Nvidia products
by reverse engineering. This set open source graphics and games back a
lot.&lt;&#x2F;p&gt;
&lt;p&gt;The clubs first and only computer is the CHE-1. When you joined the
club, you could order the parts and the club would help you build your
own computer. It was also a free exchange of ideas on how to extend the
capabilities of the CHE-1. Over the years they developed extensions such
as printers, floppy drives and colour graphics. They went beyond the
original Apple II design. But they also made sure they used standard
components and had good documentation so anyone could build it. These
documents and schematics fill my grey binder. Approximately 1300 CHE-1
motherboards are build. The club went dormant after five years
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.applefritter.com&#x2F;node&#x2F;193&quot;&gt;source&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;motherboard-populated.jpeg&quot; alt=&quot;The motherboard populated. With seven expansion slots the CHE-1 was build for extension. The community developed many: full colour graphics, RAM disks, serial ports and tape drive interfaces. Source: http:&#x2F;&#x2F;www.hansotten.com&#x2F;index.php?page=apple-ii-clones. © 2004 Hans Otten. (CC BY-NC 2.5 NL)[https:&#x2F;&#x2F;creativecommons.org&#x2F;licenses&#x2F;by-nc&#x2F;2.5&#x2F;nl&#x2F;]&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;internals.jpeg&quot; alt=&quot;The motherboard and periphals in the spacious enclosure. Source: http:&#x2F;&#x2F;www.applefritter.com&#x2F;node&#x2F;193 © 2004 Tom Owad, Gerard Goorden.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The EPROMs containing the firmware where not officially part of the DIY
package. The manual does not describe the firmware. I assume this is
because they where unauthorized copies of Apple’s own firmware. In the
introduction to chapter 5, the manual just assumes that you somehow
managed to get Applesoft BASIC on your system! (Apple-Soft, by the way,
was what Micro-Soft called the Apple II port of its BASIC).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;diskdrive.jpeg&quot; alt=&quot;Remember the days when you installed a diskdrive with hammer and chisel? © 1981 Computer Hobbyvereniging Eindhoven.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I never needed a hammer and chisel, but I remember resoldering the
keyboard connections every so many keystrokes. It was a wide ribbon
cable hand-soldered to a big D-sub connector without strain relief. Good
times. This was way before USB, PS&#x2F;2 and even PC&#x2F;AT keyboard connectors.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;scintilla.jpeg&quot; alt=&quot;Scintilla&amp;#39;s introduction into soldering. © 1983 E.T.S.V. Scintilla.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Scintilla, the student student society for electrical engineers in
Twente constructed my machine. They contributed back to the project with
a nice introduction into soldering. Almost two decades later I would
become a member of Scintilla to use their electronic component store.
It’s one of those funny loops in fate.&lt;&#x2F;p&gt;
&lt;p&gt;Besides the grey binder I also found two manuals on Apple II
programming:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;apple-handboek.jpeg&quot; alt=&quot;“Apple handbook”. © 1981 Uitgeverij Wolfkamp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;machinetaal.jpeg&quot; alt=&quot;“Assembly language programming”. © 1982 Uitgeverij Wolfkamp&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;wozniak.jpeg&quot; alt=&quot;Wozniak&amp;#39;s floating point routines. Dr. Dobb&amp;#39;s Journal published the floating-point routines. They allowed the Apple II to calculate addition, subtraction, multiplication, division and logarithms.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Steve_Wozniak&quot;&gt;Woz&lt;&#x2F;a&gt;! He
single-handedly designed the Apple II. When he wrote these routines he
was 27. That is my current age! Will someone read my code forty years
from now?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;che&#x2F;che&#x2F;nibbles.jpeg&quot; alt=&quot;Introduction to binary&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I remember this. That little worm thought me about bits, nibbles, bytes,
words, hex and binary.&lt;&#x2F;p&gt;
&lt;p&gt;In fact, thanks to the CHE-1 and Applesoft BASIC I think I learned
programming in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Critical_period_hypothesis#Effects_of_aging&quot;&gt;critical
period&lt;&#x2F;a&gt;
where you learn your native languages: when children under nine learn
languages, the early exposure to different languages activates a reflex
in the brain allowing them to switch between languages without confusion
or having to internally translate them into another native language
(Penfield, 1964).&lt;&#x2F;p&gt;
&lt;p&gt;Programming definitely feels like a native language to me.&lt;&#x2F;p&gt;
&lt;p&gt;I spend many nights just typing in the example code from these books,
then I would change something and see what happens. In the beginning I
did this without understanding what happened. All that experimentation
thought me computer internals and the BASIC programming language. By the
time I had my first English classes (around age 10) my vocabulary was
&lt;code&gt;input&lt;&#x2F;code&gt;, &lt;code&gt;print&lt;&#x2F;code&gt;, &lt;code&gt;if&lt;&#x2F;code&gt;, &lt;code&gt;then&lt;&#x2F;code&gt;, &lt;code&gt;for&lt;&#x2F;code&gt; and &lt;code&gt;next&lt;&#x2F;code&gt;. I’m still at odds with
&lt;code&gt;goto&lt;&#x2F;code&gt; being two words!&lt;&#x2F;p&gt;
&lt;p&gt;Also surprising are the beautiful little loops this machines has created
in my life:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;It was designed by Philips Natlab associates, I would later get an exclusive tour there.&lt;&#x2F;li&gt;
&lt;li&gt;It was build by Scintilla, which I would later join myself.&lt;&#x2F;li&gt;
&lt;li&gt;It has Silicon Valley spirit, which I would later experience first hand at Singularity University.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I’m sure it set me up for this!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Open Source Innovation</title>
        <published>2014-09-17T00:00:00+00:00</published>
        <updated>2014-09-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/phd/proposal/"/>
        <id>https://2π.com/14/phd/proposal/</id>
        
        <content type="html" xml:base="https://2π.com/14/phd/proposal/">&lt;h1 id=&quot;open-source-innovation&quot;&gt;Open Source Innovation&lt;&#x2F;h1&gt;
&lt;p&gt;PhD Candidate
:   Remco Bloemen MSc. MASt. &amp;lt;&lt;a href=&quot;mailto:remco@coblue.eu&quot;&gt;remco@coblue.eu&lt;&#x2F;a&gt;&amp;gt;&lt;&#x2F;p&gt;
&lt;p&gt;Supervisor
:   Dr. Chintan Amrit &amp;lt;&lt;a href=&quot;mailto:c.amrit@utwente.nl&quot;&gt;c.amrit@utwente.nl&lt;&#x2F;a&gt;&amp;gt;&lt;&#x2F;p&gt;
&lt;p&gt;Supervisor
:   Prof. Dr. Jos van Hillegersberg &amp;lt;&lt;a href=&quot;mailto:j.vanhillegersberg@utwente.nl&quot;&gt;j.vanhillegersberg@utwente.nl&lt;&#x2F;a&gt;&amp;gt;&lt;&#x2F;p&gt;
&lt;p&gt;Department
:   Department of Information Systems and Change Management&lt;&#x2F;p&gt;
&lt;p&gt;Research Title
:   Open Source Innovation&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;There is little doubt about the importance of technology for human
prosperity. From spear-hunting to space exploration, technology has
allowed us to transcend our roots as hairless primates. Fast forward to
our current state of a 7.5 billion population keeping the Maltusian
catastrophe at bay using ever advancing technology. There are signs that
we are now close to (or already beyond?) the carrying capacity of our
planet. We now find ourselves at the mercy of this &lt;em&gt;force of advancing
technology&lt;&#x2F;em&gt;. So far, technology appears merciful: Moore’s law seems to
hold in a wide range of areas and bring us increasingly better lives. It
has come so far that thinkers&#x2F;futurists&#x2F;prophets are warning about the
impeding &lt;em&gt;singularity&lt;&#x2F;em&gt;, the point where technology will outpass its
creator. I will not speculate on this for now, and instead focus on the
process itself.&lt;&#x2F;p&gt;
&lt;p&gt;So what really is this force of advancing technology? Economists have
called the increase in societies technological prowess &lt;em&gt;innovation&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The control over innovation is a source of geopolitical struggle.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Intellectual property law is a major factor in that&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;NL generates income on tax free royalties&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;US patent system is a big mess&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Kodak - Instagram&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Intellectual property protection is &lt;em&gt;not&lt;&#x2F;em&gt; a product of rational
economics.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Innovation research has a blind spot&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;research-goals-and-questions&quot;&gt;Research goals and questions&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Goals&lt;&#x2F;strong&gt;: In order to fully understand innovation we need an
overarching theory of open source innovation.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;What is the economic value of open source innovation?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;literature-review&quot;&gt;Literature review&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Capitalism, Socialism and Democracy — Joseph Schumpeter&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Schumpeter got &lt;em&gt;creative destruction&lt;&#x2F;em&gt; out of Marx his works.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The Austrian-American economist and political scientist
Schumpeter&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;— Henry Chesbrough&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The Cathedral and the Bazaar — Eric S. Raymond&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Wikinomics: How Mass Collaboration Changes Everything — Don
Tapscott, Anthony D. Williams&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Open-source-appropriate_technology&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Open-source-appropriate_technology&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Appropedia&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Appropedia&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Appropriate_technology&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Appropriate_technology&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sustainable_development&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sustainable_development&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;“Design for the Other 90%”&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;aims-and-objectives&quot;&gt;Aims and objectives&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;methodology&quot;&gt;Methodology&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Theory&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Data&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;ethical-considerations&quot;&gt;Ethical Considerations&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;budget-and-funding&quot;&gt;Budget and funding&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;timeline&quot;&gt;Timeline&lt;&#x2F;h2&gt;
&lt;p&gt;+--------------------+--------------------+--------------------+--------------------+
| Period             | Planning           | Deliverables       |
+====================+====================+====================+====================+
| 2014               | Q1                 |                    | Short papers       |
|                    |                    |                    | Gentoo portage     |
|                    |                    |                    | data set and       |
|                    |                    |                    | Bass-Diffusion for |
|                    |                    |                    | MSR                |
+--------------------+--------------------+--------------------+--------------------+
| Q2                 |                    | Random sample      |
|                    |                    | based hypothesis   |
|                    |                    | testing            |
+--------------------+--------------------+--------------------+--------------------+
| Q3                 |                    | Article            |
|                    |                    | Bass-Diffusion for |
|                    |                    | EMSE, PhD proposal |
+--------------------+--------------------+--------------------+--------------------+
| Q4                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| 2015               | Q1                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q2                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q3                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q4                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| 2016               | Q1                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q2                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q3                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q4                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| 2017               | Q1                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q2                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q3                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+
| Q4                 |                    |                    |
+--------------------+--------------------+--------------------+--------------------+&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Mostly open-ended explorative&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Could be final publication in book form, or just articles&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.utwente.nl&#x2F;igs&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.utwente.nl&#x2F;igs&#x2F;&lt;&#x2F;a&gt; Institute for Innovation and Governance
Studies&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.utwente.nl&#x2F;mb&#x2F;cstm&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.utwente.nl&#x2F;mb&#x2F;cstm&#x2F;&lt;&#x2F;a&gt; Department of Governance and
Technology for Sustainability (CSTM)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.utwente.nl&#x2F;mb&#x2F;cheps&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.utwente.nl&#x2F;mb&#x2F;cheps&#x2F;&lt;&#x2F;a&gt; Center for Higher Education Policy
Studies&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.utwente.nl&#x2F;mb&#x2F;steps&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.utwente.nl&#x2F;mb&#x2F;steps&#x2F;&lt;&#x2F;a&gt; Welcome to the Department of
Science, Technology, and Policy Studies (STəPS)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.utwente.nl&#x2F;mb&#x2F;nikos&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.utwente.nl&#x2F;mb&#x2F;nikos&#x2F;&lt;&#x2F;a&gt; Knowledge intensive
entrepreneurship&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.utwente.nl&#x2F;igs&#x2F;lseb&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.utwente.nl&#x2F;igs&#x2F;lseb&#x2F;&lt;&#x2F;a&gt; The Laboratory for Social
Interactions and Economic Behavior (LSEB) is a newly established
group of economists within the Institute for Innovation and
Governance Studies (IGS) and hosted at The Faculty of
Geo-Information Science and Earth Observation (ITC) of the
University of Twente.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.academia.edu&#x2F;2320432&#x2F;The_Case_for_Intellectual_Property&quot;&gt;http:&#x2F;&#x2F;www.academia.edu&#x2F;2320432&#x2F;The_Case_for_Intellectual_Property&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.academia.edu&#x2F;457330&#x2F;Derivative_Works_Original_Value&quot;&gt;http:&#x2F;&#x2F;www.academia.edu&#x2F;457330&#x2F;Derivative_Works_Original_Value&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;David_Graeber&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;David_Graeber&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;15 October — One page proposal&lt;&#x2F;p&gt;
&lt;p&gt;Utwente Tech 4 People.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Visualising complex functions</title>
        <published>2014-08-30T00:00:00+00:00</published>
        <updated>2014-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/visualising-complex-functions/visualising-complex-functions/"/>
        <id>https://2π.com/14/visualising-complex-functions/visualising-complex-functions/</id>
        
        <content type="html" xml:base="https://2π.com/14/visualising-complex-functions/visualising-complex-functions/">&lt;h1 id=&quot;visualising-complex-functions&quot;&gt;Visualising complex functions&lt;&#x2F;h1&gt;
&lt;!-- ![](example.jpg) --&gt;
&lt;p&gt;The CIE HCL colorspace is a fascinating humane-centric way of calculating with colors. This became clear to me when I saw the “less-angry  rainbow”, and here I have applied it to domain coloring in an interactive demo.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;demo&quot;&gt;Demo&lt;&#x2F;h3&gt;
&lt;script src=&quot;&#x2F;&#x2F;cdnjs.cloudflare.com&#x2F;ajax&#x2F;libs&#x2F;jquery&#x2F;2.1.4&#x2F;jquery.min.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;script src=&quot;&#x2F;&#x2F;cdnjs.cloudflare.com&#x2F;ajax&#x2F;libs&#x2F;d3&#x2F;3.5.5&#x2F;d3.min.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;script src=&quot;&#x2F;&#x2F;cdnjs.cloudflare.com&#x2F;ajax&#x2F;libs&#x2F;mathjs&#x2F;0.27.0&#x2F;math.min.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;&lt;label class=&quot;control-label&quot; for=&quot;function&quot;&gt;&lt;span class=&quot;math math-inline&quot;&gt;{f(z) = }&lt;&#x2F;span&gt;&lt;&#x2F;label&gt;
&lt;input class=&quot;form-control&quot; id=&quot;function&quot; value=&quot;((z^2-1)(z-2-i)^2)&#x2F;(z^2+2+2i)&quot; type=&quot;text&quot;&gt;
&lt;button class=&quot;btn dropdown-toggle&quot; data-toggle=&quot;dropdown&quot;&gt;
Examples
&lt;span class=&quot;caret&quot;&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;button&gt;&lt;&#x2F;p&gt;
&lt;ul class=&quot;dropdown-menu&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#&quot; id=&quot;dropdown&quot;&gt;z&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;z^2&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;z^3&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;z^(-1)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;z^(1+i)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;z^(3+4i)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;2^(1&#x2F;z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;i^z&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;i^sin(z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;e^z&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;log(z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;sin(z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;tan(z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;log(z^3)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;sin(z)^i&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;cos(z)^cos(z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;cos(z)^sin(z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;sin(z)^(1&#x2F;z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;e^(10&#x2F;z)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;(z^2-1)(z-2-i)^2&#x2F;(z^2+2+2i)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;label class=&quot;control-label&quot; for=&quot;domainmapping&quot;&gt;Domain map&lt;&#x2F;label&gt;
&lt;label class=&quot;radio inline&quot; for=&quot;domainmapping-0&quot;&gt;
&lt;input name=&quot;domainmapping&quot; id=&quot;domainmapping-0&quot; value=&quot;arctan&quot; type=&quot;radio&quot;&gt;
Arctangens
&lt;&#x2F;label&gt;
&lt;label class=&quot;radio inline&quot; for=&quot;domainmapping-1&quot;&gt;
&lt;input name=&quot;domainmapping&quot; id=&quot;domainmapping-1&quot; value=&quot;rocchini&quot; checked=&quot;checked&quot; type=&quot;radio&quot;&gt;
Rocchini&#x27;s
&lt;&#x2F;label&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;label class=&quot;control-label&quot; for=&quot;colorspace&quot;&gt;Color space&lt;&#x2F;label&gt;
&lt;label class=&quot;radio inline&quot; for=&quot;colorspace-0&quot;&gt;
&lt;input name=&quot;colorspace&quot; id=&quot;colorspace-0&quot; value=&quot;human&quot; checked=&quot;checked&quot; type=&quot;radio&quot;&gt;
Human
&lt;&#x2F;label&gt;
&lt;label class=&quot;radio inline&quot; for=&quot;colorspace-1&quot;&gt;
&lt;input name=&quot;colorspace&quot; id=&quot;colorspace-1&quot; value=&quot;computer&quot; type=&quot;radio&quot;&gt;
Computer
&lt;&#x2F;label&gt;
&lt;label class=&quot;radio inline&quot; for=&quot;colorspace-2&quot;&gt;
&lt;input name=&quot;colorspace&quot; id=&quot;colorspace-2&quot; value=&quot;cubehelix&quot; type=&quot;radio&quot;&gt;
Cubehelix
&lt;&#x2F;label&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;canvas id=&quot;canvas&quot; width=&quot;400&quot; height=&quot;400&quot;&gt;Canvas not supported&lt;&#x2F;canvas&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;button id=&quot;render&quot; name=&quot;render&quot; class=&quot;btn btn-primary&quot;&gt;Render&lt;&#x2F;button&gt;
← Click here!&lt;&#x2F;p&gt;
&lt;script&gt;
	$(&#x27;ul.dropdown-menu li a&#x27;).each(function(i) {
		var text = $(this).text();
		$(this).click(function(e){
			$(&#x27;#function&#x27;).val(text);
			e.preventDefault(); &#x2F;&#x2F; prevent the default anchor functionality
		});
	});
&lt;&#x2F;script&gt;
&lt;h3 id=&quot;why&quot;&gt;Why?&lt;&#x2F;h3&gt;
&lt;p&gt;When I saw by Mike Bostock&#x27;s
“http:&#x2F;&#x2F;bl.ocks.org&#x2F;mbostock&#x2F;310c99e53880faec2434[A Less-Angry Rainbow]”
I was inspired and thought about applying it to
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Domain_coloring[Domain coloring]
.&lt;&#x2F;p&gt;
&lt;p&gt;Then today I saw https:&#x2F;&#x2F;imgur.com&#x2F;eIk5kM9[some]
https:&#x2F;&#x2F;imgur.com&#x2F;a&#x2F;LVAfw[beautiful complex plots]
on
http:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;mathpics[&#x2F;r&#x2F;mathpics]
and just had to build this. I took all of the examples from the plots on the
various pages I just linked.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;perceptual-uniform-color-maps&quot;&gt;Perceptual uniform color maps&lt;&#x2F;h3&gt;
&lt;p&gt;The basis of most domain colored graphs is the &lt;span class=&quot;math math-inline&quot;&gt;HSL&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;HSV&lt;&#x2F;span&gt; color map:&lt;&#x2F;p&gt;
&lt;center&gt;
&lt;canvas id=&quot;canvashslspace&quot; width=&quot;427&quot; height=&quot;240&quot;&gt;Canvas not supported&lt;&#x2F;canvas&gt;
&lt;&#x2F;center&gt;
&lt;p&gt;This doesn&#x27;t look smooth to me. I can see bright yellow, cyan and purple hills
in the center.&lt;&#x2F;p&gt;
&lt;p&gt;The
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;International_Commission_on_Illumination[CIE] has
been researching human color perception since 1913. Decades of precise
measurements on human subjects have resulted in very accurate models of how
colors are perceived. If we use their landmark model &lt;span class=&quot;math math-inline&quot;&gt;L^*a^*b^*&lt;&#x2F;span&gt; model from 1971 and
plot the perceived &#x27;luminance&#x27; of the above graph, we get this:&lt;&#x2F;p&gt;
&lt;center&gt;
&lt;canvas id=&quot;canvashsluminance&quot; width=&quot;427&quot; height=&quot;240&quot;&gt;Canvas not supported&lt;&#x2F;canvas&gt;
&lt;&#x2F;center&gt;
&lt;p&gt;This confirms exactly what I thought I saw.&lt;&#x2F;p&gt;
&lt;p&gt;We don&#x27;t want colors that are smooth for computers, we want colors that are
smooth for humans. This has also been studied by the CIE and the solution is the
https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;CIELUV#Cylindrical_representation[ &lt;span class=&quot;math math-inline&quot;&gt;LCh_{uv}&lt;&#x2F;span&gt;] colorspace:&lt;&#x2F;p&gt;
&lt;center&gt;
&lt;canvas id=&quot;canvashcl&quot; width=&quot;427&quot; height=&quot;240&quot;&gt;Canvas not supported&lt;&#x2F;canvas&gt;
&lt;&#x2F;center&gt;
&lt;p&gt;Much smoother! But, try moving your head up and down and looking at this graph
from steep above or steep below.&lt;&#x2F;p&gt;
&lt;p&gt;Exactly.&lt;&#x2F;p&gt;
&lt;p&gt;You probably see some sinoidal curved lines. These are not part of the color
space, but are caused by limitations of your monitor. You can try adjusting your
monitors brightness, contrast, and gamma. Properly calibrated monitors should
present a smooth image.&lt;&#x2F;p&gt;
&lt;p&gt;I have already tuned the saturation down by two-thirds to make the colors easier
for monitors. If I where to saturate the colors more, a lot of them will be
outside of what monitors are capable off.&lt;&#x2F;p&gt;
&lt;p&gt;Technical difficulties aside, its luminance is what we expect:&lt;&#x2F;p&gt;
&lt;center&gt;
&lt;canvas id=&quot;canvashclluminance&quot; width=&quot;427&quot; height=&quot;240&quot;&gt;Canvas not supported&lt;&#x2F;canvas&gt;
&lt;&#x2F;center&gt;
&lt;p&gt;And this produced nice plots like:&lt;&#x2F;p&gt;
&lt;p&gt;image::example.jpg[width=&quot;50%&quot;,title=&quot;Human-centric domain coloring.&quot;,alt=&quot;Domain coloring plot of the function &lt;span class=&quot;math math-inline&quot;&gt;{f(z) =((z^2-1)(z-2-i)^2)&#x2F;(z^2+2+2i)}&lt;&#x2F;span&gt;. It is the same example as on the Wikipedia page, but rendered in the human oriented HCL colorspace.&quot;]&lt;&#x2F;p&gt;
&lt;script&gt;
!function(){function t(t){return function(e,i){e=d3.hsl(e),i=d3.hsl(i);var r=(e.h+120)*a,h=(i.h+120)*a-r,s=e.s,l=i.s-s,o=e.l,u=i.l-o;return isNaN(l)&amp;&amp;(l=0,s=isNaN(s)?i.s:s),isNaN(h)&amp;&amp;(h=0,r=isNaN(r)?i.h:r),function(a){var e=r+h*a,i=Math.pow(o+u*a,t),c=(s+l*a)*i*(1-i);return&quot;#&quot;+n(i+c*(-.14861*Math.cos(e)+1.78277*Math.sin(e)))+n(i+c*(-.29227*Math.cos(e)-.90649*Math.sin(e)))+n(i+c*1.97294*Math.cos(e))}}}function n(t){var n=(t=0&gt;=t?0:t&gt;=1?255:0|255*t).toString(16);return 16&gt;t?&quot;0&quot;+n:n}var a=Math.PI&#x2F;180;d3.scale.cubehelix=function(){return d3.scale.linear().range([d3.hsl(300,.5,0),d3.hsl(-240,.5,1)]).interpolate(d3.interpolateCubehelix)},d3.interpolateCubehelix=t(1),d3.interpolateCubehelix.gamma=t}();
&lt;&#x2F;script&gt;
&lt;script&gt;

function plot(canvas, colorfunc) {
	var canvas = document.getElementById(canvas);
	var context = canvas.getContext(&quot;2d&quot;);
	var image = context.createImageData(canvas.width, canvas.height);
	var pointer = 0;
	
	var step = function(y) {
		if(y &gt;= canvas.height)
			return;
		var v = 1.0 - (y &#x2F; canvas.height);
		for(var x = 0; x &lt; canvas.width; ++x) {
			var u = x &#x2F; canvas.width;
			var c = colorfunc(u, v);
			image.data[pointer++] = c.r; &#x2F;&#x2F; R
			image.data[pointer++] = c.g; &#x2F;&#x2F; G
			image.data[pointer++] = c.b; &#x2F;&#x2F; B
			image.data[pointer++] = 255; &#x2F;&#x2F; A
		}
		context.putImageData(image, 0, 0);
		setTimeout(function(){ step(y + 1); }, 1);
	}
	step(0);
}

function hsv(h, sat, val) {
	&#x2F;&#x2F; Convert HSV to HSL
	var l = val * (2 - sat) &#x2F; 2;
	var s = val * sat &#x2F; (1 - Math.abs(2 * l - 1));
	return d3.hsl(h * 360, s, l).rgb();
}

function hslcolormap(u, v) {
	return d3.hsl(u * 360, 1, v).rgb();
}

function hclcolormap(u, v) {
	return d3.hcl(u * 360, 200&#x2F;3, v * 130 - 10).rgb();
}

function cm_computer(u, k) {
	var sat = k;
	sat = 1 - Math.pow(1 - sat, 3);
	sat = 0.4 + sat * 0.6;
	
	var val = k;
	val = 1 - val;
	val = 1 - Math.pow(1 - val, 3);
	val = 0.6 + val * 0.4;
	
	return hsv(u, sat, val);
}

function cm_human(u, k) {
	var sat = k;
	sat = 1 - Math.pow(1 - sat, 3);
	sat = 0.4 + sat * 0.6;
	
	var val = k;
	val = 1 - val;
	val = 1 - Math.pow(1 - val, 3);
	val = 0.6 + val * 0.4;
	
	var l = val * (2 - sat) &#x2F; 2;
	&#x2F;&#x2F; var s = val * sat &#x2F; (1 - Math.abs(2 * l - 1));
		
	return d3.hcl(u * 360, 80, l * 110 + 10).rgb();
}

var rainbow = d3.scale.cubehelix()
	.domain([0, .5, 1])
	.range([
		d3.hsl(-100, 0.75, 0.35),
		d3.hsl(  80, 1.50, 0.80),
		d3.hsl( 260, 0.75, 0.35)
	]);

function cm_cubehelix(u, k) {
	var c = d3.hcl(rainbow(u));
	
	var sat = k;
	sat = 1 - Math.pow(1 - sat, 3);
	sat = 0.4 + sat * 0.6;
	
	var val = k;
	val = 1 - val;
	val = 1 - Math.pow(1 - val, 3);
	val = 0.6 + val * 0.4;
	
	var l = val * (2 - sat) &#x2F; 2;
	&#x2F;&#x2F; var s = val * sat &#x2F; (1 - Math.abs(2 * l - 1));
	
	
	return d3.hcl(c.h, c.c, c.l + l * 110 -60 ).rgb();
}

plot(&quot;canvashslspace&quot;, hslcolormap);
plot(&quot;canvashsluminance&quot;, function(u, v) {
	return d3.lab(d3.lab(hslcolormap(u, v)).l, 0, 0).rgb();
});
plot(&quot;canvashcl&quot;, hclcolormap);
plot(&quot;canvashclluminance&quot;, function(u, v) {
	return d3.lab(d3.lab(hclcolormap(u, v)).l, 0, 0).rgb();
});

function dm_arctan(colormap) {
	return function(z) {
		var z = z.toPolar();
		var u = z.phi &#x2F; (2.0 * Math.PI);
		var v = 2.0 * Math.atan(z.r) &#x2F; Math.PI;
		return colormap(u, v);
	}
}

function dm_rocchini(colormap) {
	return function(z) {
		var z = z.toPolar();
		var u = z.phi &#x2F; (2.0 * Math.PI);
		while(u &lt; 0)
			u += 1;
		while(u &gt; 1)
			u -= 1;
		var ranges = 0;
		var rangee = 1;
		while(z.r &gt; rangee) {
			ranges = rangee;
			rangee *= Math.E;
		}
		var k = (z.r - ranges) &#x2F; (rangee - ranges);
		var v = k &lt; 0.5 ? k * 2 : 1 - (k - 0.5) * 2;
		return colormap(u, v);
	}
}

function complexplot(canvas, domaincoloring, f) {
	plot(canvas, function(u, v) {
		var z = math.complex(6 * u - 3, 6 * v - 3);
		return domaincoloring(f(z));
	});
}

$(&#x27;#render&#x27;).click(function() {
	var code = math.compile($(&#x27;#function&#x27;).val());
	function func(zx) {
		return code.eval({
			z: zx
		});
	};
	
	var domainmap = {
		arctan: dm_arctan,
		rocchini: dm_rocchini,
	}[$(&#x27;input:radio[name=domainmapping]:checked&#x27;).val()];
	var colormap = {
		computer: cm_computer,
		human: cm_human,
		cubehelix: cm_cubehelix,
	}[$(&#x27;input:radio[name=colorspace]:checked&#x27;).val()];
	
	complexplot(&quot;canvas&quot;, domainmap(colormap), func);
});

$(&#x27;#render&#x27;).click();

&lt;&#x2F;script&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Diferential equations</title>
        <published>2014-07-25T00:00:00+00:00</published>
        <updated>2014-07-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/difeq/difeq/"/>
        <id>https://2π.com/14/difeq/difeq/</id>
        
        <content type="html" xml:base="https://2π.com/14/difeq/difeq/">&lt;h1 id=&quot;diferential-equations&quot;&gt;Diferential equations&lt;&#x2F;h1&gt;
&lt;!-- ![](yp-y-sin-x-xp-y.png)  --&gt;
&lt;p&gt;Inspired by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;math&#x2F;comments&#x2F;2blp2p&#x2F;whats_your_favorite_differential_equation_plot&#x2F;&quot;&gt;this&lt;&#x2F;a&gt; post on &#x2F;r&#x2F;maths I made a Runga-Kutta 4-5 integrator. It is interactive, click and drag in the black square below.&lt;&#x2F;p&gt;
&lt;div id=&quot;graph&quot; style=&quot;width:100%;&quot;&gt;
&lt;canvas id=&quot;view&quot;&gt;&lt;&#x2F;canvas&gt;
&lt;&#x2F;div&gt;
&lt;div id=&quot;error&quot;&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;canvas id=&quot;sprites&quot; width=&quot;100&quot; height=&quot;10&quot;&gt;&lt;&#x2F;canvas&gt;&lt;&#x2F;p&gt;
&lt;script&gt;window.on(&quot;load&quot;, function() {

var xformula = location.get(&#x27;xprime&#x27;) || &quot;1&quot;;
var yformula = location.get(&#x27;yprime&#x27;) || &quot;1&quot;;
document.title = &quot;x&#x27; = &quot; + xformula + &quot; : y&#x27; = &quot; + yformula;
&#x2F;&#x2F; export the Math functions
&quot;sin cos tan log exp abs pow min max PI&quot;.split(&quot; &quot;).forEach(function (f) {
	window[f] = Math[f];
});
console.log(xformula);
console.log(yformula);
try {
	var x = 0, y = 0;
	eval(xformula);
	eval(yformula);
} catch (e) {
	$(&#x27;#error&#x27;).innerHTML = &quot;Error with formula: &quot; + e;
}

console.log($(&#x27;#graph&#x27;))

var w = $(&#x27;#graph&#x27;)[0].offsetWidth;
var h = w &#x2F; 1.62;

var height = w;
var width =  h;
var canvas = $(&#x27;#view&#x27;)[0];
var sprites = $(&#x27;#sprites&#x27;)[0];
sprites.width = 100;
sprites.height = 10;
var blobArray = [];
var mouse = {x: 0, y: 0};
canvas.mouseIsOver = false;
   canvas.onmouseover = function()   {
      this.mouseIsOver = true;
   };
   canvas.onmouseout = function()   {
      this.mouseIsOver = false;
   }
var width = canvas.width = w;
var height = canvas.height = h;
	c = canvas.getContext(&#x27;2d&#x27;),
	cs = sprites.getContext(&#x27;2d&#x27;);
function randomRange(min, max){
	return Math.random()*(max-min) + min;
}

var mouseDown = 0;
canvas.on(&quot;mousedown&quot;, function() {
	mouseDown=true;
});
canvas.on(&quot;mouseup&quot;, function() {
	mouseDown=false;
});
var rect = canvas.getBoundingClientRect();
canvas.on(&quot;mousemove&quot;, function(e){
	mouse.x = (e.pageX-rect.left)&#x2F;(rect.right-rect.left)*canvas.width;
	mouse.y = (e.pageY-rect.top)&#x2F;(rect.bottom-rect.top)*canvas.height;
}, false);

c.fillStyle = &#x27;black&#x27;;
c.fillRect(0,0,width,height);
c.fillStyle = &#x27;white&#x27;;
c.fillRect(width&#x2F;2-1,0,1,height);
c.fillRect(0,height&#x2F;2-1,width,1);
&#x2F;&#x2F;cs.fillStyle = &#x27;black&#x27;;
&#x2F;&#x2F;cs.fillRect(0,0,100,10);

[&#x27;aqua&#x27;, &#x27;blue&#x27;, &#x27;fuchsia&#x27;, &#x27;green&#x27;,&#x27;lime&#x27;,&#x27;maroon&#x27;,&#x27;olive&#x27;,&#x27;orange&#x27;,&#x27;purple&#x27;].forEach(function(c,i) {
	cs.globalAlpha = 0.5;
	cs.beginPath();
	cs.arc(i * 10 + 5, 5, 5&#x2F;2, 0, 2 * Math.PI, false);
	cs.fillStyle = c;
	cs.fill();
	cs.lineWidth = 0;
});

function drawSprite(index, x, y) {
	c.drawImage(sprites, 10 * index, 0, 10, 10, x - 5, y - 5, 10, 10);
}


var divWidth = width&#x2F;10;
var divHeight = height&#x2F;10;
function draw(){

	if(mouseDown){
		var sprite = Math.floor(Math.random() * 9);
		var blob = {
			x : mouse.x,
			y : mouse.y,
			xSpeed : 0,
			ySpeed : 0,
			sprite: sprite,
			lastPos : [],
			direction : 1
		};
		blobArray.push(blob);
		var blob = {x : mouse.x,
				y : mouse.y,
				xSpeed : 0,
				ySpeed : 0,
				sprite: sprite,
				lastPos : [],
				direction : -1
			};
		blobArray.push(blob);
	}
	&#x2F;&#x2F;c.clearRect(0,0,width,height);
	var length = blobArray.length;
	for(var i = 0; i &lt; length; i++){
		blob = blobArray[i];
		
		if(blob.x &lt; 0 || blob.y &lt; -0 || blob.x &gt; width || blob.y &gt; height){
			if(blob.x &lt; -500 || blob.y &lt; -500 || blob.x &gt; width+500 || blob.y &gt; height+500){
				blobArray.splice(i,1);
			}
		} else {
			drawSprite(blob.sprite, blob.x, blob.y);
		}
		
		vec = getSlope((blob.x-width&#x2F;2)&#x2F;(divWidth), (blob.y-height&#x2F;2)&#x2F;100, 5 * blob.direction);
		
		var epsilon = .1;
		if(Math.abs(vec[0]) &lt; epsilon &amp;&amp; Math.abs(vec[1]) &lt; epsilon) {
			blobArray.splice(i,1);
		}
		
		blob.x += vec[0];
		blob.y += vec[1];
	}
}

function getSlope(x, y, delta){
	x = +x;
	y = +y;
	delta = +delta;
	var oldX = +x;
	var oldY = +y;
	
	xk1 = delta * (+eval(xformula));
	yk1 = delta * (+eval(yformula));
	x = oldX + (xk1 &#x2F; 2) &#x2F; (+divWidth);
	y = oldY + (yk1 &#x2F; 2) &#x2F; 100;
	
	xk2 = delta * (+eval(xformula));
	yk2 = delta * (+eval(yformula));
	x = oldX + (xk2 &#x2F; 2) &#x2F; (divWidth);
	y = oldY + (yk2 &#x2F; 2) &#x2F; 100;
	
	xk3 = delta * eval(xformula);
	yk3 = delta * eval(yformula);
	x = oldX + xk3 &#x2F; (+divWidth);
	y = oldY + yk3 &#x2F; 100;
	
	xk4 = delta * (+eval(xformula));
	yk4 = delta * (+eval(yformula));
	
	dx = (xk1 + 2 * xk2 + 2 * xk3 + xk4) &#x2F; 6;
	dy = (yk1 + 2 * yk2 + 2 * yk3 + yk4) &#x2F; 6;
	
	return [dx, dy];
}

setInterval(draw,30);

})&lt;&#x2F;script&gt;
&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x&amp;#39; &amp;amp;= \cos y \\
y&amp;#39; &amp;amp;= \sin x
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;difeq&#x2F;difeq&#x2F;xp-cos-y-yp-sin-x.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;difeq&#x2F;difeq&#x2F;difeq?xprime=sin%28y%29&amp;amp;yprime=sin%28x%29&quot;&gt;view here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
x&amp;#39; &amp;amp;= 1.5 y \\
y&amp;#39; &amp;amp;= -y - \sin (1.5 x) + 0.7
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;difeq&#x2F;difeq&#x2F;yp-y-sin-x-xp-y.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;difeq&#x2F;difeq&#x2F;difeq?yprime=-y-sin%281.5*x%29%2B0.7&amp;amp;xprime=1.5*y&quot;&gt;view here&lt;&#x2F;a&gt;.
Suggested by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;user&#x2F;qwertz_guy&quot;&gt;&#x2F;u&#x2F;qwertz_guy&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Runge%E2%80%93Kutta_methods&quot;&gt;Runge-Kutta&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>BackgroundRunner</title>
        <published>2014-06-12T00:00:00+00:00</published>
        <updated>2014-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/backgroundrunner/backgroundrunner/"/>
        <id>https://2π.com/14/backgroundrunner/backgroundrunner/</id>
        
        <content type="html" xml:base="https://2π.com/14/backgroundrunner/backgroundrunner/">&lt;h1 id=&quot;backgroundrunner&quot;&gt;BackgroundRunner&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h2&gt;
&lt;p&gt;The usage is much like
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;qt-project.org&#x2F;doc&#x2F;qt-5&#x2F;qtconcurrentrun.html&quot;&gt;&lt;code&gt;QtConcurrent::run&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
except you return what I call a &lt;em&gt;Joiner&lt;&#x2F;em&gt;; a function that integrates the
result back into the calling thread:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;BackgroundRunner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;run&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; &amp;lt;Background task&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; &amp;lt;Joiner&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Lambda’s returning lambda’s; welcome to the world of higher-order
programming!&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;em&gt;Background task&lt;&#x2F;em&gt; will be run a background thread using
&lt;code&gt;QtConcurrent::run&lt;&#x2F;code&gt;. You have full access to the variables from the
enclosing scope, notable the &lt;code&gt;this&lt;&#x2F;code&gt; pointer, but very aware of thread
safety, because everything will be run in parallel!&lt;&#x2F;p&gt;
&lt;p&gt;When it is finished it returns the &lt;em&gt;Joiner&lt;&#x2F;em&gt;, which is queued for the
event loop of the calling thread. Again you have access to the &lt;code&gt;this&lt;&#x2F;code&gt;
pointer, but this time we are back in the objects &lt;em&gt;own&lt;&#x2F;em&gt; thread, it is as
safe to use the &lt;code&gt;this&lt;&#x2F;code&gt; pointer as in any &lt;code&gt;slot&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Below is an real-world example of function in a &lt;code&gt;QAbstractItemModel&lt;&#x2F;code&gt;
that uses the &lt;code&gt;BackgroundRunner&lt;&#x2F;code&gt; to calculate UI content on demand,
without blocking the UI.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;QString&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-function z-definition z-cpp&quot;&gt; DataModel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; rowId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;contains&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;rowId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;rowId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Get the row data to calculate the message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Let&amp;#39;s do it here to avoid concurrency issues&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; RowData rowData &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; dataForRow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;rowId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Calculate the message in the background&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;	BackgroundRunner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;run&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;([&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Code here will be run in a background thread.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; We can now use rowData, it will be a copy of the one defined on line 8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;		const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; QString message &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; expensiveCalculateMessage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;rowData&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Add the messge to the cache and inform the model&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Code here can safely access both (copies of) the result from the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; background task, and the DataModel object. It can even emit signals!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			_cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;rowId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;			emit&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; refresh&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;rowId&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Show ellipsis while we are waiting for the message to be done.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;…&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;source&quot;&gt;Source&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;backgroundrunner&#x2F;backgroundrunner&#x2F;BackgroundRunner.h&quot;&gt;BackgroundRunner.h&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Secure memory</title>
        <published>2014-05-28T00:00:00+00:00</published>
        <updated>2014-06-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/secure-memory/secure-memory/"/>
        <id>https://2π.com/14/secure-memory/secure-memory/</id>
        
        <content type="html" xml:base="https://2π.com/14/secure-memory/secure-memory/">&lt;h1 id=&quot;secure-memory&quot;&gt;Secure memory&lt;&#x2F;h1&gt;
&lt;!-- ![](memory_5.jpg) --&gt;
&lt;p&gt;How can you make this harder in software?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sensitive-information&quot;&gt;Sensitive information&lt;&#x2F;h2&gt;
&lt;p&gt;(Section is work in progress)&lt;&#x2F;p&gt;
&lt;p&gt;What kind of sensitive information can there be stored in memory?&lt;&#x2F;p&gt;
&lt;p&gt;Passphrases, private keys, session keys. Crypto algorithm state.
Decrypted content.&lt;&#x2F;p&gt;
&lt;p&gt;Keys and passphrases are small, on the order of 32 bytes. Crypto
algorithm states can be a lot larger.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;How&lt;&#x2F;em&gt; you get those sensitive passphrases securely into the computer’s
memory is beyond the scope of this article.&lt;&#x2F;p&gt;
&lt;p&gt;TODO&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stealing-sensitive-information&quot;&gt;Stealing sensitive information&lt;&#x2F;h2&gt;
&lt;p&gt;Is it ‘stealing’ when the attacker merely copies a key? Well, the
attacker gained something of value to him and the original owner is left
with a key that is now worthless. Attacker gains, owner looses, so you
could argue that it is indeed stealing.&lt;&#x2F;p&gt;
&lt;p&gt;Suppose you have sensitive information, say credit card records in a
database. I’ll assume you did not store it unencrypted on the disk, but
at some point the information needs to be stored unencrypted in the
computers working memory (RAM). What are the different ways in which an
attacker can steal this information when it is in the working memory?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Social engineering&lt;&#x2F;strong&gt;: Probably the easiest way to get sensitive
information is by just asking for it, possibly under a false pre-text.
There are many different tricks that can be employed, from phishing by
mail to carefully crafted and personalized attacks. This is an important
subject, but in this article I am going to focus on the low-level
software engineering aspects of securing sensitive information, whereas
this is more in the equally important realm of user interaction design.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Software bugs&lt;&#x2F;strong&gt;: There are many ways in which an application itself
can contain bugs that allow an attacker to read out its sensitive
information. I will not try to list all the different kind of bugs here;
software bugs range from bad implementations that store or transmits the
sensitive information unencrypted, to buffer overrun bugs such as
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;heartbleed.com&#x2F;&quot;&gt;Heartbleed&lt;&#x2F;a&gt;, to more subtle things such as
leaking information from secured heap to the less secure stack due to
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Register_allocation#Spilling&quot;&gt;register
spilling&lt;&#x2F;a&gt;.
There are techniques that can drastically reduce the impact of bugs,
many of which will be explained in the next section of this article.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Operating system bugs&lt;&#x2F;strong&gt;: Modern computer processors have memory
protection that prevent different processes from accessing each others
memory. Setting up those access rights requires privileged instructions
that are only available to the operating system and drivers. In
particularly drivers of poor quality may contain bugs that can allow one
process to gain access to another process&#x27; memory.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;secure-memory&#x2F;secure-memory&#x2F;resized_mobile-attack.jpg&quot; alt=&quot;We have used a mobile phone to acoustically extract keys from a laptop. By just listening to the high-pitched thermal-acoustic noise of a computer doing RSA decryptions, the researchers where able to extract the full 4096 bit keys from a laptop within an hour. Source: http:&#x2F;&#x2F;www.cs.tau.ac.il&#x2F;~tromer&#x2F;acoustic&#x2F;. © Daniel Genkin, Adi Shamir &amp;amp; Eran Tromer.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Timing attacks&lt;&#x2F;strong&gt;: The amount of time a computer spends on something
can reveal a bit about what it is doing. In ‘&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.daemonology.net&#x2F;papers&#x2F;htt.pdf&quot;&gt;cache missing for fun and
profit&lt;&#x2F;a&gt;’ the author
demonstrates how an attacking process can deduce how a target process is
accessing its memory and consequentially what it’s RSA private keys are.
Timing attacks have also been applied to AES
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cr.yp.to&#x2F;antiforgery&#x2F;cachetiming-20050414.pdf&quot;&gt;paper&lt;&#x2F;a&gt;) and
remotely by measuring how long it takes a server to respond
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.daemonology.net&#x2F;papers&#x2F;htt.pdf&quot;&gt;paper&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;EM&#x2F;power&#x2F;acoustic attacks&lt;&#x2F;strong&gt;: In a wonderful study done by Daniel
Genkin et al. (&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cs.tau.ac.il&#x2F;~tromer&#x2F;acoustic&#x2F;&quot;&gt;source&lt;&#x2F;a&gt;), the
researchers explored different methods of extracting sensitive
information by listening to emitted noise in electromagnetic and
acoustic fields. They set up a normal laptop and encryption software,
and made it decrypt specially selected data. The 4096 bit private key
was then stolen using: a smartphone microphone at 30 cm, a sensitive lab
microphone at 4m, through high level Tempest shielding, and by measuring
the electrical noise on the far end of a 10m ethernet cable. Together
with the timing attacks these are also known as side channel attacks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hibernate files&lt;&#x2F;strong&gt;: When the computer goes to a deep sleep, it likes to
turn off power to the memory. Before it can do this, it needs to store
the contents somewhere else, that is, on the hard disk. When the
computer goes out of sleep, it will restore the memory contents and
continue where it left. This is a common and useful trick in battery
operated devices, but in the process it writes all the sensitive
information to the hard disk. The sensitive information can then be read
out through physical access or special software.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Swapping&lt;&#x2F;strong&gt;: Much like hibernation, when the operating systems wants to
free up some memory, it will move some of the memory contents to disk,
to be reloaded when it is needed again. In modern operating systems this
will happen even when the memory is not entirely full. The consequences
are the same as with hibernation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Debuggers&lt;&#x2F;strong&gt;: The system calls
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man2&#x2F;ptrace.2.html&quot;&gt;&lt;code&gt;ptrace&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;windows&#x2F;desktop&#x2F;ms680553%28v=vs.85%29.aspx&quot;&gt;&lt;code&gt;ReadProcessMemory&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
allow one process to inspect another process&#x27; memory. These system calls
are meant for debugging and should require special privileges over the
process being observed. But bad security practices, such working under
and administrator account, can result in all processes having this debug
privilege.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Core dumps&lt;&#x2F;strong&gt;: Most modern operating systems produces a crash report
when an application fails. The report usually includes the point of
failure, the state of the processor, a stacktrace, and sometimes a dump
of the memory. All of these can contain sensitive information. Crash
reports should be considered as confidential as the content in the
application. Automatically uploading crash reports to the application
developers can hand over sensitive information to a third party, and if
not sufficiently secured, anyone eavesdropping.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Virtualization&lt;&#x2F;strong&gt;: A
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hypervisor&quot;&gt;hypervisor&lt;&#x2F;a&gt; is a piece of
software that creates virtual machines. The hypervisor has full access
to the virtual machines memory, unbounded by the guest’s protected
memory restrictions. This is used to store the machine’s state to disk,
much like a hibernation file and with the same implications. Even if the
virtualization software itself is not malicious, it can contain
exploitable bugs. A notable example is the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.blackhat.com&#x2F;presentations&#x2F;bh-usa-09&#x2F;ORTEGA&#x2F;BHUSA09-Ortega-DeactivateRootkit-PAPER.pdf&quot;&gt;Computrace&lt;&#x2F;a&gt;
anti theft service, which comes factory installed on “most notebooks
sold since 2005”. The hypervisor is embedded in the BIOS and can not be
removed. It has a design weakness that can allow an attacker to install
a rootkit.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Rootkit&lt;&#x2F;strong&gt;: Rootkits are malicious hypervisors, using the powerful
position a hypervisor has to attack the virtualized system. A rootkit
like &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;theinvisiblethings.blogspot.nl&#x2F;2006&#x2F;06&#x2F;introducing-blue-pill.html&quot;&gt;Blue
pill&lt;&#x2F;a&gt;
or &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.stoned-vienna.com&#x2F;&quot;&gt;Stoned&lt;&#x2F;a&gt; will, when executed, install
itself as a hypervisor and move the system to a virtual machine. From
here the system is unaware that it has been moved to a virtual machine
or that Blue pill is running in the background. Once installed, the
rootkit has full control, it can connect to the internet, steal disk
encryption keys and log keystrokes.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;secure-memory&#x2F;secure-memory&#x2F;memory_5.jpg&quot; alt=&quot;Cold boot attack. One way of stealing sensitive information from memory is by stealing the memory itself. RAM modules will retain their information for a couple of seconds without power. But when cooled to -50°C, it will keep the information for minutes. This gives an attacker enough time to transplant the memory to an extraction machine or reboot the machine into a special extraction operating system. Source: https:&#x2F;&#x2F;citp.princeton.edu&#x2F;research&#x2F;memory&#x2F;. © Center for Information Technology Policy. CC-BY https:&#x2F;&#x2F;creativecommons.org&#x2F;licenses&#x2F;by&#x2F;3.0&#x2F;us&#x2F; &quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;DMA attacks&lt;&#x2F;strong&gt;: Direct memory access (DMA) allows computer hardware to
access memory directly, bypassing the processor. This frees the
processor up to do other work while big memory transfers happen in the
background. It is used by internal devices such as hard drives, network
cards and graphics cards, and external ports such as Firewire,
ExpressCard and Thunderbolt. eSATA and USB make use of DMA too, but
restrict what a device can do to a safe subset. Once a device has
unrestricted DMA access, it can bypass all of the memory protections
build in the operating system and read out the entire memory.
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.breaknenter.org&#x2F;projects&#x2F;inception&#x2F;&quot;&gt;Inception&lt;&#x2F;a&gt; is a free
tool to extract memory contents over Firewire and search for disk
encryption keys.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Cold boot attacks&lt;&#x2F;strong&gt;: In a cold boot attack the attacker quickly
restarts the machine into a state where he can read out the memory
contents. This works because the contents of the memory are not cleared
during a restart and will retain sensitive information for seconds while
the power is off. The Center for Information Technology Policy provides
free &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;citp.princeton.edu&#x2F;research&#x2F;memory&#x2F;code&#x2F;&quot;&gt;tools&lt;&#x2F;a&gt; to boot
into a special operating system and find RSA and AES keys.
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www1.cs.fau.de&#x2F;frost&quot;&gt;Frost&lt;&#x2F;a&gt; is a similar tool for Android
devices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Bus sniffing&lt;&#x2F;strong&gt;: While getting a bit ridiculous, it is possible to
physically open a running computer, attach wires on the motherboard at
strategic places and simply eavesdrop on the communications to and from
the memory. The bus clock speed for DDR3 RAM is about one GHz, which is
within the range of the good logic analyzers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;protecting-sensitive-information&quot;&gt;Protecting sensitive information&lt;&#x2F;h2&gt;
&lt;p&gt;(Section is work in progress)&lt;&#x2F;p&gt;
&lt;p&gt;First two general tricks that will become handy later when using some
more advanced techniques. Both these tricks assume it is possible to
generate keys securely.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Reducing the size of the information&lt;&#x2F;strong&gt;: If you want to store several
megabytes of sensitive information securely, the size will preclude some
of the tricks below. Yet you may still want to benefit from their added
security. To do this you generate a new key, and authenticated-encrypt
the information with this key. The encrypted information can be stored
in non secure memory, even on disk. Only the tiny encryption key needs
to be stored in a secure location. The downside is that you need to
decrypt and encrypt every time you read or modify the information. You
also still need a secure place to store it while accessing, but for much
shorter time frames and possibly just a subset of the information.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Combining two locations&lt;&#x2F;strong&gt;: Suppose you have two different locations
where you can store something relatively securely. You would like to
combine the strengths of both. However, this is not trivial. If you
would simply store half the sensitive information in one location and
half in the other, then you did make it harder to get the full sensitive
information (it would require stealing both locations) but you made it
easier to obtain some information (it would require stealing either one
of two locations). To really combine the strengths of the two locations
you generate a key, authenticated-encrypt the sensitive information with
the key, store the key in one place and the encrypted data in the other.
You now need both pieces to gain access to the original data. A common
implementation uses a xor based one time pad, which does not provide
integrity guarantees and still allows an attacker to change the
information given access to one location, even if he can’t read it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;API Design&lt;&#x2F;strong&gt;: First and foremost a good API design with proper
abstractions can make a world of difference. Create one interface that
is responsible for all the logistics of sensitive information. All of
the alloc&#x2F;free&#x2F;zero logic should be contained here. Many of the
mitigations below can simply be implemented in the
constructors&#x2F;destructors of this class and will then be effective
everywhere. Casting between secure and unsecure memory should be
explicit, or perhaps even disallowed.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Software bugs, and makes all the other mitigations more
effective.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Clear the memory&lt;&#x2F;strong&gt;: Memory should be cleared as soon as possible and
definitely before it is released (See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.securecoding.cert.org&#x2F;confluence&#x2F;display&#x2F;seccode&#x2F;MEM03-C.+Clear+sensitive+information+stored+in+reusable+resources&quot;&gt;CERT
MEM03-C&lt;&#x2F;a&gt;
). Having the sensitive information in memory for the minimal amount of
time reduces the exposure to many attacks, and clearing it before
release prevents accidental leakage when the memory is reused. Note that
a simple call to &lt;code&gt;std::fill&lt;&#x2F;code&gt; is not sufficient. The compiler might
optimize this away, especially when the memory is freed immediately
after. To prevent this the pointer can be declared &lt;code&gt;volatile&lt;&#x2F;code&gt; or, under
windows,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;windows&#x2F;desktop&#x2F;aa366877%28v=vs.85%29.aspx&quot;&gt;&lt;code&gt;SecureZeroMemory&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
can be used. (See &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.securecoding.cert.org&#x2F;confluence&#x2F;display&#x2F;seccode&#x2F;MSC06-C.+Beware+of+compiler+optimizations&quot;&gt;CERT
MSC06-C&lt;&#x2F;a&gt;
)&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Software bugs, and reduces chances of other attacks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;No sensitive indexing&lt;&#x2F;strong&gt;: Memory access patterns that depend on
sensitive information should be avoided since these open opportunities
for side-channel attacks. Take lookup-tables for example, they can be
redesigned by, always looking up all entries and selectively multiplying
the entries by zero or one. You should be careful about compiler
optimizations and the performance impact. If access patterns can not be
made secure, they can be mitigated a bit by simply prefetching all the
sensitive information in the caches before usage.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Timing attacks, EM&#x2F;power&#x2F;acoustic attacks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;No sensitive branches&lt;&#x2F;strong&gt;: Do not have control flow depend on sensitive
information. A good example is &lt;code&gt;memcmp&lt;&#x2F;code&gt;, this function will return on
the first difference it finds between two byte arrays. Its timing
therefore reveals the length of the common prefix. Just like with
indexing, you have to be careful about compiler optimizations when
working around sensitive branching.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Timing attacks, EM&#x2F;power&#x2F;acoustic attacks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Canaries&lt;&#x2F;strong&gt;: Out of bounds writes can sometimes be detected using
canaries. These are constants placed before and after the buffer. If the
application overwrites these with different values, this will be
detected later on. It should be hard for an attacker to predict the
canary values. They are very useful in finding and mitigating buffer
overflow bugs.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Software bugs.&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Explain pages. 64k size.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Guard pages&lt;&#x2F;strong&gt;: Guard pages are like super canaries, they are placed
before and after the data and will detect unauthorized or accidental
writes beyond the buffer. Unlike canaries, guard pages can also detect
reads and do not rely on unguessable values. However, guard pages must
be page aligned and can’t always be placed directly before or after the
data, leaving a gap in the protection. Guard page are implemented at a
very low level in the operating systems virtual memory manager, and can
therefore catch a wider range of bugs.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Software bugs, operating system bugs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Pages access&lt;&#x2F;strong&gt;: Processes can get fine grained control over the access
rights to particular sections of memory using
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man2&#x2F;mprotect.2.html&quot;&gt;&lt;code&gt;mprotect&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; in
Posix and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;windows&#x2F;desktop&#x2F;aa366898%28v=vs.85%29.aspx&quot;&gt;&lt;code&gt;VirtualProtect&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
in windows. Pages can be marked as inaccessible, read only or read-write
(amongst others). For example, guard pages can be created by marking a
page as inaccessible. In addition, on Posix systems
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man2&#x2F;madvise.2.html&quot;&gt;&lt;code&gt;madvise&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; can be
called with the options &lt;code&gt;MADV_DONTDUMP&lt;&#x2F;code&gt; and &lt;code&gt;MADV_DONTFORK&lt;&#x2F;code&gt; to prevent
specific pages from ending up in core dumps and child processes
respectively.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Software bugs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Locked pages&lt;&#x2F;strong&gt;: Pages can be protected from &lt;code&gt;mlock&lt;&#x2F;code&gt; in Posix and
&lt;code&gt;VirtualLock&lt;&#x2F;code&gt; in windows.
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blogs.msdn.com&#x2F;b&#x2F;oldnewthing&#x2F;archive&#x2F;2007&#x2F;11&#x2F;06&#x2F;5924058.aspx&quot;&gt;http:&#x2F;&#x2F;blogs.msdn.com&#x2F;b&#x2F;oldnewthing&#x2F;archive&#x2F;2007&#x2F;11&#x2F;06&#x2F;5924058.aspx&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Swapping and sometimes hibernate files.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Operating System encryption&lt;&#x2F;strong&gt;: Windows provides two functions
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;windows&#x2F;desktop&#x2F;aa380262%28v=vs.85%29.aspx&quot;&gt;&lt;code&gt;CryptProtectMemory&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;windows&#x2F;desktop&#x2F;aa380890%28v=vs.85%29.aspx&quot;&gt;&lt;code&gt;CryptUnprotectMemory&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
that encrypt&#x2F;decrypt a block of memory using what appears to be an
process specific encryption key hosted in the operating system. The
functions are specifically designed for information that should not be
written in plaintext to the disk when hibernating or swapping. The Linux
equivalents are
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man2&#x2F;add_key.2.html&quot;&gt;&lt;code&gt;add_key&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man3&#x2F;keyctl_update.3.html&quot;&gt;&lt;code&gt;kectl_update&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man3&#x2F;keyctl_read.3.html&quot;&gt;&lt;code&gt;keyctl_read&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man3&#x2F;keyctl_clear.3.html&quot;&gt;&lt;code&gt;keyctl_clear&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man3&#x2F;keyctl_invalidate.3.html&quot;&gt;&lt;code&gt;keyctl_invalidate&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;15555691&#x2F;confusion-on-the-usage-of-add-key-linux-key-management-interface&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;15555691&#x2F;confusion-on-the-usage-of-add-key-linux-key-management-interface&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Software bugs, swapping, hibernate files, core dumps and
possibly more depending on the operating system implementation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Disable debuggers&lt;&#x2F;strong&gt;: Under Linux a process can disable core dumps and
debugging by disabling &lt;code&gt;PR_SET_DUMPABLE&lt;&#x2F;code&gt; using the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man2&#x2F;prctl.2.html&quot;&gt;&lt;code&gt;prctl&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; call. A
similar thing can be done Mac OS and iOS using the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.apple.com&#x2F;library&#x2F;mac&#x2F;documentation&#x2F;Darwin&#x2F;Reference&#x2F;ManPages&#x2F;man2&#x2F;ptrace.2.html&quot;&gt;&lt;code&gt;PT_DENY_ATTACH&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
option to &lt;code&gt;ptrace&lt;&#x2F;code&gt;. Under Windows it is possible to find the presence of
debuggers using
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;windows&#x2F;desktop&#x2F;ms680345%28v=vs.85%29.aspx&quot;&gt;&lt;code&gt;IsDebuggerPresent&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
and prevent them from being created using
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;msdn.microsoft.com&#x2F;en-us&#x2F;library&#x2F;windows&#x2F;desktop&#x2F;ms682425%28v=vs.85%29.aspx&quot;&gt;&lt;code&gt;CreateProcess&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
with the appropriate access rights.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Debuggers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Disable core dumps&lt;&#x2F;strong&gt;: Under Posix operating systems, core dumps can be
disabled by setting &lt;code&gt;RLIMIT_CORE&lt;&#x2F;code&gt; to zero with a call to
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man2&#x2F;setrlimit.2.html&quot;&gt;&lt;code&gt;setrlimit&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.
There is no Windows equivalent of this call as Windows does not have
core dumps.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Core dumps.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Case intrusion detection&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Bus sniffing, some cold boot and rootkit attacks.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hypervisor detection&lt;&#x2F;strong&gt;: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20070911024318&#x2F;http:&#x2F;&#x2F;invisiblethings.org&#x2F;papers&#x2F;redpill.html&quot;&gt;Red
pill&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;northsecuritylabs.blogspot.nl&#x2F;2008&#x2F;06&#x2F;catching-blue-pill.html&quot;&gt;http:&#x2F;&#x2F;northsecuritylabs.blogspot.nl&#x2F;2008&#x2F;06&#x2F;catching-blue-pill.html&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.zdnet.com&#x2F;blog&#x2F;security&#x2F;rutkowska-faces-100-undetectable-malware-challenge&#x2F;334&quot;&gt;http:&#x2F;&#x2F;www.zdnet.com&#x2F;blog&#x2F;security&#x2F;rutkowska-faces-100-undetectable-malware-challenge&#x2F;334&lt;&#x2F;a&gt;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.invisiblethingslab.com&#x2F;resources&#x2F;bh07&#x2F;IsGameOver.pdf&quot;&gt;http:&#x2F;&#x2F;www.invisiblethingslab.com&#x2F;resources&#x2F;bh07&#x2F;IsGameOver.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Hypervisors.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Anti-rootkits&lt;&#x2F;strong&gt;:
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;research.microsoft.com&#x2F;en-us&#x2F;um&#x2F;people&#x2F;wdcui&#x2F;papers&#x2F;hooksafe-ccs09.pdf&quot;&gt;Hooksafe&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Root kits.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Shielding&lt;&#x2F;strong&gt;:
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tempest_%28codename%29&quot;&gt;Tempest&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: EM&#x2F;power&#x2F;acoustic attacks. Requires special hardware.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Crypto hardware&lt;&#x2F;strong&gt;: Such as a &lt;em&gt;Trusted platform module&lt;&#x2F;em&gt;, a crypto token
or x509 card. TPM does not work against cold boot. These are basically
tiny computers, moving the problem from the original computer to a tiny
external computer, that is designed from the ground up to be secure.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Depends on the quality of the hardware and the
trustworthiness of the supplier. Requires special hardware.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Not using memory&lt;&#x2F;strong&gt;:
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www1.informatik.uni-erlangen.de&#x2F;tresor&quot;&gt;Tresor&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;frozencache.blogspot.com&#x2F;&quot;&gt;Frozen
Cache&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linuxrocks123.livejournal.com&#x2F;93919.html&quot;&gt;Loop-Amnesia&lt;&#x2F;a&gt; avoid
the problems of sensitive information in memory by not having it in
memory at all. Instead the information is stored in the processor’s
registers or in the processor’s cache, which is then prevented from
flushing to memory. While interesting, this requires highly privileged
instructions that need special operating system support. In virtual
machines the instructions are likely emulated, and the host system will
retain full access to the sensitive information. Practically, the
register based solution barely has room for one key and the cache based
option effectively disables the L1 cache of a single physical CPU core,
which will ruin its performance. Also hibernate and sleep modes will
wipe the processor’s registers and caches, so the sensitive information
must be moved to another secure location before this can happen. For
servers, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;privatecore.com&#x2F;&quot;&gt;PrivateCore&lt;&#x2F;a&gt;&#x27;s vCage uses the cache
techniques to run a hypervisor in the processor’s cache. This hypervisor
transparently encrypts and decrypts all memory access by the guest
operating systems.&lt;&#x2F;p&gt;
&lt;p&gt;Mitigates: Hibernate files, swapping, core dumps, DMA access, cold boot
attacks, and bus sniffing. Requires ring-0 instructions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;practice-at-coblue&quot;&gt;Practice at Coblue&lt;&#x2F;h2&gt;
&lt;p&gt;At Coblue we developed a &lt;code&gt;SecureByteArray&lt;&#x2F;code&gt; class that implements many of
the strategies presented above.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;SecureByteArray&lt;&#x2F;code&gt; class provides only provides methods for
construction, destruction and assignment. The size is fixed on
allocation and can only be changed through assignment by another
&lt;code&gt;SecureByteArray&lt;&#x2F;code&gt;. Semantically, it represents a piece of sensitive
information stored in memory. It does not provide any API for accessing
this information, not even a comparison operator. Instead, this is all
done through the classes &lt;code&gt;ReadAccess&lt;&#x2F;code&gt; and &lt;code&gt;ReadWriteAccess&lt;&#x2F;code&gt;. These can
only be stack allocated and hence they force the developer to use the
RAII pattern and explicitly declare the kind of access he needs in a
particular scope.&lt;&#x2F;p&gt;
&lt;!-- TODO PDF SVG
![The data (green) is protected by canaries (orange) and guard pages
(red). The data and canaries are padded (gray) to a page boundary. The
canaries detect any small under- and overflows while writing to the
data. The guard pages will make the application halt as soon as they are
accessed for reading or writing.](layout.svg)
--&gt;
&lt;p&gt;Internally the memory is layed out&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Flush+Reload attack &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;448.pdf&quot;&gt;http:&#x2F;&#x2F;eprint.iacr.org&#x2F;2013&#x2F;448.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>NSA Suite B and OpenSSL</title>
        <published>2014-05-12T00:00:00+00:00</published>
        <updated>2014-05-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/nsa-suite-b-openssl/nsa-suite-b-openssl/"/>
        <id>https://2π.com/14/nsa-suite-b-openssl/nsa-suite-b-openssl/</id>
        
        <content type="html" xml:base="https://2π.com/14/nsa-suite-b-openssl/nsa-suite-b-openssl/">&lt;h1 id=&quot;nsa-suite-b-and-openssl&quot;&gt;NSA Suite B and OpenSSL&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;the-good&quot;&gt;The Good&lt;&#x2F;h2&gt;
&lt;p&gt;At Coblue we use &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.nsa.gov&#x2F;ia&#x2F;programs&#x2F;suiteb_cryptography&#x2F;&quot;&gt;NSA Suite B&lt;&#x2F;a&gt; as implemented
in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.openssl.org&#x2F;&quot;&gt;OpenSSL&lt;&#x2F;a&gt; as our library for cryptography.
Suite B has two security levels which, in proper intelligence agency
fashion, are named &lt;em&gt;SECRET&lt;&#x2F;em&gt; and &lt;em&gt;TOP SECRET&lt;&#x2F;em&gt;. Since the we value
security more than a slight performance difference, we use the strongest
set. This implies using the following four primitives:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Encryption: 256 bit AES-GCM&lt;&#x2F;li&gt;
&lt;li&gt;Key exchange: 384 bit ECDH over curve p384&lt;&#x2F;li&gt;
&lt;li&gt;Signatures: 384 bit ECDSA over curve p384&lt;&#x2F;li&gt;
&lt;li&gt;Hashing: 384 bit SHA 2&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;nsa-suite-b-openssl&#x2F;nsa-suite-b-openssl&#x2F;NSOC-2012.jpg&quot; alt=&quot;Inside the NSA&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Suite B also involves specific requirements on how to implement and use
them. This is written down in various RFC, NIST and FIPS publications,
most of which are about implementation details, but I recommend reading
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;publications&#x2F;nistpubs&#x2F;800-38D&#x2F;SP-800-38D.pdf&quot;&gt;NIST SP 800 38D&lt;&#x2F;a&gt;
chapter 8, as it sets safety limits on the length of messages, the
number of messages and IV generation for AES-GCM.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;openssl&quot;&gt;OpenSSL&lt;&#x2F;h3&gt;
&lt;p&gt;The choice for the OpenSSL library was made because it supports all the
algorithms in Suite B. It is open source and used by the majority of web
servers for their cryptography. The project is developed by both
European and U.S. based developers and has received NIST FIPS 140
certification. This makes it a reliable, if not the default, choice.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;above-and-beyond&quot;&gt;Above and beyond&lt;&#x2F;h3&gt;
&lt;p&gt;Secure web servers (for https) require at least TLS version 1.2 to
support this set of algorithms. Since support was not common at the
time, we maintained patches to OpenSSL, Apache and Qt in order to be
among the first to support a full Suite B implementation on our web
servers and in our software.&lt;&#x2F;p&gt;
&lt;p&gt;To go above and beyond &lt;em&gt;TOP SECRET&lt;&#x2F;em&gt; security we added the Scrypt as a
key derivation algorithm, pinned our certificates and developed a simple
secure socket protocol that bypassed the complexities of TLS. All of
this is packaged in a statically linked native client.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-bad&quot;&gt;The Bad&lt;&#x2F;h2&gt;
&lt;p&gt;These choices turned out to be foresightful and have saved us and our
users from being affected by many high-impact security breaches:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;MD5&lt;&#x2F;em&gt; and &lt;em&gt;SHA 1&lt;&#x2F;em&gt;: Marc Steven’s attack has made it feasible to
break signatures using these hashing algorithms, to proof his
concept he created a server with a roque certificate which was
accepted by all browsers. Evidence from
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cwi.nl&#x2F;news&#x2F;2012&#x2F;cwi-cryptanalist-discovers-new-cryptographic-attack-variant-in-flame-spy-malware&quot;&gt;Flame&lt;&#x2F;a&gt;
suggests that intelligence agencies knew about it for longer. Coblue
was saved by using SHA 2 and pinning our certificates instead of
relying on certificate chains and authorities.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;DigiNotar&lt;&#x2F;em&gt;: This certificate authority was completely compromised
allowing the issuing of false certificates. Coblue was again saved
by having its certificates pinned.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;BEAST&lt;&#x2F;em&gt; and &lt;em&gt;Lucky 13&lt;&#x2F;em&gt;: These are attacks on the CBC block cipher
mode, stream ciphers like AES-GCM were not affected. As a response
many servers switched to the RC4 stream cipher. Coblue never used
the CBC mode.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;RC4&lt;&#x2F;em&gt;: This stream cipher has already been broken in 2001, which
resulted in widespread cracking of WEP keys. Despite this, it is
still used (sometimes in slightly modified form) as part of WPA,
SSL, BitTorrent, Skype, PDF. According to one source, 50% of the
webservers are using RC4 in early 2014. Coblue never used RC4.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;CRIME&lt;&#x2F;em&gt; and &lt;em&gt;BREACH&lt;&#x2F;em&gt;: Like BEAST it allows an attacker to guess
bytes of the plaintext by abusing the TLS compression mode. Coblue
never&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;HeartBleed&lt;&#x2F;em&gt;: This is a severe bug in OpenSSL’s TLS implementation
that allowed an attacker to read out arbitrary. Coblue was
unaffected because we stopped using TLS for client-server
communication.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This list doesn’t include the numerous vulnerabilities that have been
found in browsers, browser plugins and web applications. None of these
are relevant for Coblue since our applications are not web-based.&lt;&#x2F;p&gt;
&lt;!-- TODO: SVG in PDF
![OpenSSL doesn&#x27;t have a logo, but its bugs have!](Heartbleed.svg)
--&gt;
&lt;h2 id=&quot;the-ugly&quot;&gt;The Ugly&lt;&#x2F;h2&gt;
&lt;p&gt;The Snowden revelations have shown that it is not unreasonable to
consider the whole of the PKI infrastructure to be compromised. Man in
the middle attacks are&lt;&#x2F;p&gt;
&lt;p&gt;However,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;OpenSSL code quality is not nearly up to our standards&lt;&#x2F;li&gt;
&lt;li&gt;The code base is too large&lt;&#x2F;li&gt;
&lt;li&gt;OpenSSL is vulnerable to side-channel attacks&lt;&#x2F;li&gt;
&lt;li&gt;OpenSSL has bad memory protection&lt;&#x2F;li&gt;
&lt;li&gt;TLS is overly complex&lt;&#x2F;li&gt;
&lt;li&gt;Suite B requires many primitives: AES, GHASH, SHA256, HMAC, PBKDF2, ECDH, ECDSA&lt;&#x2F;li&gt;
&lt;li&gt;SHA length extension, requiring workarounds in HMAC and PBKDF2.&lt;&#x2F;li&gt;
&lt;li&gt;NSA is known to manipulate standards (EC-DRNG)&lt;&#x2F;li&gt;
&lt;li&gt;NIST EC p384 is suspect of NSA manipulatation *&lt;&#x2F;li&gt;
&lt;li&gt;To get good security we had to forgo TLS and implement a much simpler ECDHAES-GCM protocol.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sponge based cryptography</title>
        <published>2014-05-11T00:00:00+00:00</published>
        <updated>2014-05-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/sponge-crypto/sponge-crypto/"/>
        <id>https://2π.com/14/sponge-crypto/sponge-crypto/</id>
        
        <content type="html" xml:base="https://2π.com/14/sponge-crypto/sponge-crypto/">&lt;h1 id=&quot;sponge-based-cryptography&quot;&gt;Sponge based cryptography&lt;&#x2F;h1&gt;
&lt;!-- ![](cycles-per-byte.svg) --&gt;
&lt;h2 id=&quot;nsa-suite-b-and-openssl&quot;&gt;NSA Suite B and OpenSSL&lt;&#x2F;h2&gt;
&lt;p&gt;At Coblue we use &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.nsa.gov&#x2F;ia&#x2F;programs&#x2F;suiteb_cryptography&#x2F;&quot;&gt;NSA Suite B&lt;&#x2F;a&gt; as implemented
in &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.openssl.org&#x2F;&quot;&gt;OpenSSL&lt;&#x2F;a&gt; as our library for cryptography.
Suite B has two security levels which, in proper intelligence agency
fashion, are named &lt;em&gt;SECRET&lt;&#x2F;em&gt; and &lt;em&gt;TOP SECRET&lt;&#x2F;em&gt;. Since the we value
security more than a slight performance difference, we use the strongest
set. This implies using the following four primitives:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Encryption: 256 bit AES-GCM&lt;&#x2F;li&gt;
&lt;li&gt;Key exchange: 384 bit ECDH over curve p384&lt;&#x2F;li&gt;
&lt;li&gt;Signatures: 384 bit ECDSA over curve p384&lt;&#x2F;li&gt;
&lt;li&gt;Hashing: 384 bit SHA 2&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Suite B also involves specific requirements on how to implement and use
them. This is written down in various RFC, NIST and FIPS publications,
most of which are about implementation details, but I recommend reading
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;csrc.nist.gov&#x2F;publications&#x2F;nistpubs&#x2F;800-38D&#x2F;SP-800-38D.pdf&quot;&gt;NIST SP 800 38D&lt;&#x2F;a&gt;
chapter 8, as it sets safety limits on the length of messages, the
number of messages and IV generation for AES-GCM.&lt;&#x2F;p&gt;
&lt;p&gt;The choice for the OpenSSL library was made because it supports all the
algorithms in Suite B. It is open source and used by the majority of web
servers for their cryptography. The project is developed by both
European and U.S. based developers and has received NIST FIPS 140
certification. This makes it a reliable, if not the default, choice.&lt;&#x2F;p&gt;
&lt;p&gt;Secure web servers (for https) require at least TLS version 1.2 to
support this set of algorithms. Since support was not common at the
time, we maintained patches to OpenSSL, Apache and Qt in order to be
among the first to support a full Suite B implementation on our web
servers and in our software.&lt;&#x2F;p&gt;
&lt;p&gt;To go above and beyond &lt;em&gt;TOP SECRET&lt;&#x2F;em&gt; security we added the Scrypt as a
key derivation algorithm, pinned our certificates and developed a simple
secure socket protocol that bypassed the complexities of TLS. All of
this is packaged in a statically linked native client.&lt;&#x2F;p&gt;
&lt;p&gt;These choices turned out to be foresightful and have saved us and our
users from being affected by many high-impact security breaches:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;MD5&lt;&#x2F;em&gt; and &lt;em&gt;SHA 1&lt;&#x2F;em&gt;: Marc Steven’s attack has made it feasible to
break signatures using these hashing algorithms, to proof his
concept he created a server with a roque certificate which was
accepted by all browsers. Evidence from
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cwi.nl&#x2F;news&#x2F;2012&#x2F;cwi-cryptanalist-discovers-new-cryptographic-attack-variant-in-flame-spy-malware&quot;&gt;Flame&lt;&#x2F;a&gt;
suggests that intelligence agencies knew about it for longer. Coblue
was saved by using SHA 2 and pinning our certificates instead of
relying on certificate chains and authorities.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;DigiNotar&lt;&#x2F;em&gt;: This certificate authority was completely compromised
allowing the issuing of false certificates. Coblue was again saved
by having its certificates pinned.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;BEAST&lt;&#x2F;em&gt; and &lt;em&gt;Lucky 13&lt;&#x2F;em&gt;: These are attacks on the CBC block cipher
mode, stream ciphers like AES-GCM were not affected. As a response
many servers switched to the RC4 stream cipher. Coblue never used
the CBC mode.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;RC4&lt;&#x2F;em&gt;: This stream cipher has already been broken in 2001, which
resulted in widespread cracking of WEP keys. Despite this, it is
still used (sometimes in slightly modified form) as part of WPA,
SSL, BitTorrent, Skype, PDF. Coblue never used RC4. BEAST many web
servers (50% according to one source) are using RC4.&lt;&#x2F;li&gt;
&lt;li&gt;CRIME and BREACH: Like BEAST it allows an attacker to learn about the&lt;&#x2F;li&gt;
&lt;li&gt;Numerous web browser exploits.&lt;&#x2F;li&gt;
&lt;li&gt;HeartBleed: This is a bug in OpenSSL’s TLS implementation.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;limitations&quot;&gt;Limitations&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;OpenSSL code quality is not nearly up to our standards&lt;&#x2F;li&gt;
&lt;li&gt;Many primitives: AES, GHASH, SHA256, HMAC, PBKDF2, ECDH, ECDSA&lt;&#x2F;li&gt;
&lt;li&gt;SHA length extension, requiring workarounds in HMAC and PBKDF2.&lt;&#x2F;li&gt;
&lt;li&gt;Development of side-channel attacks&lt;&#x2F;li&gt;
&lt;li&gt;NSA is known to manipulate standards and P-384 is suspect&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;comparison&quot;&gt;Comparison&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;security&quot;&gt;Security&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;implementation-maturity&quot;&gt;Implementation maturity&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;lines-of-code&quot;&gt;Lines of code&lt;&#x2F;h3&gt;
&lt;p&gt;OpenSSL itself has about 4 hundred thousand lines of code in total, most
of these are not used in our&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sloccount crypto&#x2F;modes&#x2F;{ctr128,gcm128,ghash-x86_64}.* &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crypto&#x2F;aes&#x2F;aes_{ctr,misc}.c crypto&#x2F;aes&#x2F;aes_{core,ctr,misc,wrap}.* &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crypto&#x2F;aes&#x2F;*.s crypto&#x2F;aes&#x2F;asm&#x2F;*aes-x86_64.pl crypto&#x2F;aes&#x2F;asm&#x2F;aesni-x86_64.pl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sloccount crypto&#x2F;sha&#x2F;sha{,256,256-x86_64,256t,_dgst}.* &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crypto&#x2F;sha&#x2F;asm&#x2F;sha512-x86_64.pl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The OpenSSL code consists of Ansi C, Assebler and Perl scripts to
produce the assembler.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;performance&quot;&gt;Performance&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;benchmarking&quot;&gt;Benchmarking&lt;&#x2F;h4&gt;
&lt;!-- TODO: SVG images in latex
![](setup-cost.svg)

![](cycles-per-byte.svg)
--&gt;
&lt;h3 id=&quot;results&quot;&gt;Results&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;var labels = [&amp;#39;SHA 256&amp;#39;, &amp;#39;Keccak&amp;#39;, &amp;#39;AES-GCM&amp;#39;, &amp;#39;SpongeWrap&amp;#39;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;columnChart(labels, [2700, 3500, 14000, 31000]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;columnChart(labels, [13.0, 13.7, 2.5, 3.8]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Algorithm  LoC    Setup cost  Cycles per byte&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;SHA 256    2285   2700        13.0
Keccak     429⁽¹⁾ 3500        13.7
AES-GCM    21560  14000       2.5
SpongeWrap 554⁽¹⁾ 31000       3.8&lt;&#x2F;p&gt;
&lt;p&gt;(1): 308 lines of code are shared between these implementations. These
lines represent the Keccak permutation function and the core of both
algorithms.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cryptograhics file system</title>
        <published>2014-05-07T00:00:00+00:00</published>
        <updated>2014-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/cryptographic-file-system/"/>
        <id>https://2π.com/14/cryptographic-file-system/</id>
        
        <content type="html" xml:base="https://2π.com/14/cryptographic-file-system/">&lt;h1 id=&quot;cryptograhics-file-system&quot;&gt;Cryptograhics file system&lt;&#x2F;h1&gt;
&lt;p&gt;The only difficult right is reading. Any mutable operation can be
implemented by a function&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; isValidChange&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Change&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; change&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Authorization&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; auth&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where &lt;code&gt;change&lt;&#x2F;code&gt; represents the operation to be applied (for example a
file delete) and &lt;code&gt;auth&lt;&#x2F;code&gt; is any collection of signatures or other data to
proof the authorization for that change.&lt;&#x2F;p&gt;
&lt;p&gt;The function &lt;code&gt;isValidChange&lt;&#x2F;code&gt; returns &lt;code&gt;true&lt;&#x2F;code&gt; when the change conforms to
all the rules.&lt;&#x2F;p&gt;
&lt;p&gt;This is similar to how the BitCoin blockchain validates transactions.
Here every outgoing entry in a transaction contains a small script in a
domain specific non Turing complete programming language. Give some
authorization information, the script will return either &lt;code&gt;true&lt;&#x2F;code&gt; or
&lt;code&gt;false&lt;&#x2F;code&gt; indicating if the authorization allows the money to be spend or
not. This system has allowed BitCoin to be flexible beyond its original
scope, but still there are uses for an even more flexible Turing
complete language. This has some safety concerns however.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;some-concepts&quot;&gt;Some concepts&lt;&#x2F;h2&gt;
&lt;p&gt;Once someone has a received the keys to access a file for reading, it is
difficult to revoke.&lt;&#x2F;p&gt;
&lt;p&gt;If the user had access to the plaintext they could have made an
out-of-system copy of the file’s plaintext. This is outside the scope of
the system, unless it would implement draconian measures as scanning all
the users systems for copies of possibly revoked files. The problem gets
even more complicated by removable and read-only media such as optical
disks or simply printed paper.&lt;&#x2F;p&gt;
&lt;p&gt;Assuming the user did not store the plaintext.&lt;&#x2F;p&gt;
&lt;p&gt;The&lt;&#x2F;p&gt;
&lt;h3 id=&quot;lazy-revocation&quot;&gt;Lazy revocation&lt;&#x2F;h3&gt;
&lt;p&gt;In lazy revocation the file’s key is updated the next time the file is
changed. The old key will remain valid for the old file, but can not be
used anymore for new changes, which will be encrypted with a new key.&lt;&#x2F;p&gt;
&lt;p&gt;The old key is marked &lt;em&gt;dirty&lt;&#x2F;em&gt; and the process of decrypting with the old
key and reencrypting with the new key is called &lt;em&gt;cleaning&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-rotation&quot;&gt;Key Rotation&lt;&#x2F;h3&gt;
&lt;p&gt;Plutus: Scalable secure file sharing on untrusted storage Kallahalla,
Riedel, Swaminathan, Wang and Fu&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
K_{n+1} &amp;amp;= E_{private}(K_n) &amp;amp; K_{n-1} &amp;amp;= E_{public}(K_n)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-regression&quot;&gt;Key regression&lt;&#x2F;h3&gt;
&lt;p&gt;Suppose key &lt;span class=&quot;math math-inline&quot;&gt;K_1&lt;&#x2F;span&gt; is updated to &lt;span class=&quot;math math-inline&quot;&gt;K_2&lt;&#x2F;span&gt;, but some files are still dirty and
encrypted with &lt;span class=&quot;math math-inline&quot;&gt;K_1&lt;&#x2F;span&gt;. &lt;em&gt;Key regression&lt;&#x2F;em&gt; allows the &lt;span class=&quot;math math-inline&quot;&gt;K_1&lt;&#x2F;span&gt; to be derived from
&lt;span class=&quot;math math-inline&quot;&gt;K_2&lt;&#x2F;span&gt; so that no history of keys needs to be maintained.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rate-limits-idea&quot;&gt;Rate limits (idea)&lt;&#x2F;h3&gt;
&lt;p&gt;It would be nice to have a rate limiting service. A means of recognizing
when rights are used in a suspicious manner. For example by exhaustively
using all the read access rights to create an unencrypted copy of all
the files.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;one-time-pads-idea&quot;&gt;One time pads (idea)&lt;&#x2F;h3&gt;
&lt;p&gt;Tens of gigabytes of random key material can easily be stored on
postmark sized microSD cards. Why not use this technology to obtain the
perfect encryption that comes with it?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;symmetric-encryption-link&quot;&gt;Symmetric encryption link&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
K_1 → K_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There is some information &lt;span class=&quot;math math-inline&quot;&gt;K_2&amp;#39;&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
K_2 = D(K_1, K_2&amp;#39;)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;asymmetric-encryption-link&quot;&gt;Asymmetric encryption link&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
K_1 \rightharpoonup K_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There is some information &lt;span class=&quot;math math-inline&quot;&gt;K_2&amp;#39;&lt;&#x2F;span&gt; such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
K_2 = D(
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stored-information-isn-t-dead&quot;&gt;Stored information isn’t dead&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Integrity verification&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Redistribution&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Reencryption for key revocation and cipher upgrades&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Create&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Read&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Update&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Delete&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Move: Delete + Create with same content&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Assign &quot;Create&quot; right&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Revoke &quot;Create&quot; right&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Change &quot;Create&quot; right&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;least-authority-file-system&quot;&gt;Least authority file system&lt;&#x2F;h2&gt;
&lt;p&gt;Inserting a file&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;File is encrypted&lt;&#x2F;li&gt;
&lt;li&gt;The result is segmented&lt;&#x2F;li&gt;
&lt;li&gt;Redundant data is added&lt;&#x2F;li&gt;
&lt;li&gt;Hashes are computed&lt;&#x2F;li&gt;
&lt;li&gt;Peers are selected&lt;&#x2F;li&gt;
&lt;li&gt;Data is send to selected peers&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The result is an ‘capability uri’ for downloading the file.&lt;&#x2F;p&gt;
&lt;p&gt;Donwloading a file&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Collect sufficient segments&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Validate their hashes&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Combine the segments&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Decrypt the segments&lt;&#x2F;p&gt;
&lt;p&gt;read-cap&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;code&gt;URI:CHK:(key):(hash):(needed-shares):(total-shares):(size)&lt;&#x2F;code&gt; key is the
16-byte AES encryption key encoded in Base32 encoding, hash is the
SHA265d hash of the URI Extension Block, needed-shares is the number of
shares needed to reconstruct the file, total-shares is the number of
total-shares distributed in the grid for that file, size is the size of
the file in bytes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;verify-cap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;URI:CHK-Verifier:(storageindex):(hash):(needed-shares):(total-shares):(size)&lt;&#x2F;code&gt;
storageindex is the SHA265d hash of the encryption key truncated to
16-byte.&lt;&#x2F;p&gt;
&lt;p&gt;literals (used for files smaller than 55 bytes)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;URI:LIT:(data)&lt;&#x2F;code&gt; data is the file hashed using SHA265d and encoded in
base32 encoding.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cryptree&quot;&gt;Cryptree&lt;&#x2F;h2&gt;
&lt;p&gt;Wuala uses Cryptree&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Because of the design of the Cryptree key management system used by
Wuala, it is possible for Wuala (and possibly other attackers, but I’m
not sure about that) to identify which files you have modified. This
sounds like a minor point, but it is a potential problem: For example,
when people decide to update their CVs &#x2F; resumes, they would often
prefer that their current employer not find out.&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;nilestore&#x2F;wiki&#x2F;TahoeLAFSBasics&quot;&gt;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;nilestore&#x2F;wiki&#x2F;TahoeLAFSBasics&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;dcg.ethz.ch&#x2F;publications&#x2F;srds06.pdf&quot;&gt;http:&#x2F;&#x2F;dcg.ethz.ch&#x2F;publications&#x2F;srds06.pdf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cryptographic Primitives</title>
        <published>2014-05-07T00:00:00+00:00</published>
        <updated>2014-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/cryptographic-primitives/"/>
        <id>https://2π.com/14/cryptographic-primitives/</id>
        
        <content type="html" xml:base="https://2π.com/14/cryptographic-primitives/">&lt;h1 id=&quot;cryptographic-primitives&quot;&gt;Cryptographic Primitives&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;symmetric-cryptography&quot;&gt;Symmetric cryptography&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;sponge-functions&quot;&gt;Sponge functions&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;one-way-functions&quot;&gt;One-way functions&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{H} &amp;amp;: &amp;amp;\{0,1\}^{*} &amp;amp;→ \{0,1\}^{l}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{H}(X_1) &amp;amp;= \mathrm{H}(X_2) &amp;amp;&amp;amp;⇔ &amp;amp;X_1 &amp;amp;= X_2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;Y&lt;&#x2F;span&gt; compute &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; such that &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{H}(X) = Y&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;message-authentication-codes&quot;&gt;Message authentication codes&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;pseudo-random-number-generator&quot;&gt;Pseudo random number generator&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;note: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.cr.yp.to&#x2F;20140205-entropy.html&quot;&gt;http:&#x2F;&#x2F;blog.cr.yp.to&#x2F;20140205-entropy.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;key-derivation-functions&quot;&gt;Key derivation functions&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;symmetric-encryption&quot;&gt;Symmetric encryption&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{E} &amp;amp;: &amp;amp;\{0,1\}^{l_K} × \{0,1\}^{*} &amp;amp;→
\{0,1\}^{*} \\ \mathrm{D} &amp;amp;: &amp;amp;\{0,1\}^{l_K} × \{0,1\}^{*}
&amp;amp;→ \{0,1\}^{*}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{D}(K_1, \mathrm{E}(K_2, X)) &amp;amp;= X &amp;amp;&amp;amp;⇔ &amp;amp; K_1 &amp;amp;= K_2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;authenticated-encryption&quot;&gt;Authenticated encryption&lt;&#x2F;h3&gt;
&lt;h2 id=&quot;asymmetric-cryptography&quot;&gt;Asymmetric cryptography&lt;&#x2F;h2&gt;
&lt;p&gt;Source: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.larc.usp.br&#x2F;~pbarreto&#x2F;pblounge.html&quot;&gt;http:&#x2F;&#x2F;www.larc.usp.br&#x2F;~pbarreto&#x2F;pblounge.html&lt;&#x2F;a&gt; Source:
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;courses.csail.mit.edu&#x2F;6.897&#x2F;spring04&#x2F;L25.pdf&quot;&gt;http:&#x2F;&#x2F;courses.csail.mit.edu&#x2F;6.897&#x2F;spring04&#x2F;L25.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given a group &lt;span class=&quot;math math-inline&quot;&gt;\mathcal G&lt;&#x2F;span&gt; written additively with a generator &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;,
consider the following problems:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Computational Diffie-Helman problem (CDHP): given &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;a\ P&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;b\ P&lt;&#x2F;span&gt;
in &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt;, compute &lt;span class=&quot;math math-inline&quot;&gt;ab\ P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Decisional Diffie-Helman problem (DDHP): given &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;a\ P&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;b\ P&lt;&#x2F;span&gt; and
&lt;span class=&quot;math math-inline&quot;&gt;c\ P&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt;, decide whether &lt;span class=&quot;math math-inline&quot;&gt;c = ab&lt;&#x2F;span&gt; (modulo the order of &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;Gap Diffie-Helman problem (GDHP): given an oracle that solves the
DDHP, solve the CDHP.&lt;&#x2F;li&gt;
&lt;li&gt;The Discrete Log Problem (DLP): given &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; find a such that &lt;span class=&quot;math math-inline&quot;&gt;Q = a\ P&lt;&#x2F;span&gt;.
This is also written as &lt;span class=&quot;math math-inline&quot;&gt;a = \log_P Q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;diffie-helman-key-agreement&quot;&gt;Diffie-Helman key agreement&lt;&#x2F;h3&gt;
&lt;p&gt;Two parties &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; have secrets &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A → B: a\ P&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;B → A: b\ P&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A: a\ (b\ P) = ab\ P&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;B: b\ (a\ P) = ab\ P&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Now both parties have the same secret &lt;span class=&quot;math math-inline&quot;&gt;K = ab\ P&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;asymmetric-encryption&quot;&gt;Asymmetric encryption&lt;&#x2F;h3&gt;
&lt;p&gt;This is similar to Diffie-Helman key agreement done offline.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;key-generation&quot;&gt;Key generation&lt;&#x2F;h4&gt;
&lt;ol&gt;
&lt;li&gt;Pick random private key &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;Q = q P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Publish &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; as public key, keep &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; as private key.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;encryption&quot;&gt;Encryption&lt;&#x2F;h4&gt;
&lt;p&gt;Given a message and public key &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Pick a random key &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;G = r\ Q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Encrypt the message using &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;R = r\ P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Provide &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; and the ciphertext&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;G = r\ Q = qr\ P&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;decryption&quot;&gt;Decryption&lt;&#x2F;h4&gt;
&lt;p&gt;Given a ciphertext, &lt;span class=&quot;math math-inline&quot;&gt;R&lt;&#x2F;span&gt; and private key &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;G = q\ R&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Decrypt the ciphertext using &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;G = q\ R = qr\ P&lt;&#x2F;span&gt;, the same as in the encryption process.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;distributed-key-generation&quot;&gt;Distributed key generation&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;distrib-rsa.sourceforge.net&#x2F;&quot;&gt;http:&#x2F;&#x2F;distrib-rsa.sourceforge.net&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;treshold-cryptosystem&quot;&gt;Treshold cryptosystem&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.mcs.csueastbay.edu&#x2F;~lertaul&#x2F;IJNSTCPAPERV11.pdf&quot;&gt;http:&#x2F;&#x2F;www.mcs.csueastbay.edu&#x2F;~lertaul&#x2F;IJNSTCPAPERV11.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;digital-signatures&quot;&gt;Digital signatures&lt;&#x2F;h3&gt;
&lt;p&gt;The method described here is EdDSA.
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;EdDSA&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;EdDSA&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;ed25519.cr.yp.to&#x2F;ed25519-20110926.pdf&quot;&gt;http:&#x2F;&#x2F;ed25519.cr.yp.to&#x2F;ed25519-20110926.pdf&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.cr.yp.to&#x2F;20140323-ecdsa.html&quot;&gt;http:&#x2F;&#x2F;blog.cr.yp.to&#x2F;20140323-ecdsa.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;key-generation-1&quot;&gt;Key generation&lt;&#x2F;h4&gt;
&lt;ol&gt;
&lt;li&gt;Pick random private key &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Pick a random salt &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;Q = q\ P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Publish &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; as public key, keep &lt;span class=&quot;math math-inline&quot;&gt;q&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt; as private key.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;sign&quot;&gt;Sign&lt;&#x2F;h4&gt;
&lt;p&gt;Given a message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;, a signature can be produced with:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;k = \mathrm{H_A}(r, M)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;K = k\ P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;s = \mathrm{H_B}(K, Q, m)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;s&amp;#39; = k + qs&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Provide &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;s&amp;#39;&lt;&#x2F;span&gt; as the signature.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;All integer calculation are done in a sufficiently large prime field.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;verify&quot;&gt;Verify&lt;&#x2F;h4&gt;
&lt;p&gt;Given a message &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;, a public key &lt;span class=&quot;math math-inline&quot;&gt;Q&lt;&#x2F;span&gt; and a signature &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;s&amp;#39;&lt;&#x2F;span&gt; we can verify
that the signature originated from the associated private key with:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;s = \mathrm{H_B}(K, Q, m)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;K&amp;#39; = s&amp;#39;\ P - s Q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Verify &lt;span class=&quot;math math-inline&quot;&gt;K = K&amp;#39;&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This should hold true because&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
K&amp;#39; &amp;amp;= s&amp;#39;\ P - s\ Q\\ &amp;amp;= (k + qs)\
P - s (q\ P)\\ &amp;amp;= (k + qs - sq)\ P \\ &amp;amp;= k\ P \\ &amp;amp;= K
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;forward-security&quot;&gt;Forward security&lt;&#x2F;h4&gt;
&lt;p&gt;The goal of forward security is to limit damage when a private key or
the signature algorithm gets compromised. Given a a trusted time
stamping authority the digital signature scheme can be made forward
secure. By adding a trusted time stamp is to the signature. It can,
after an incident, be determined if the signature was made before or
after the compromise. The forward secrecy of the time stamp itself can
be guaranteed by periodically adding a new time stamp, or by publication
in a public ledger such as a newspaper or a block chain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;password-authenticated-key-agreement&quot;&gt;Password-authenticated key agreement&lt;&#x2F;h3&gt;
&lt;p&gt;Two parties &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; have secrets &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; and a shared secret &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{H}&amp;amp;:&amp;amp; &amp;amp;{0,1}^* &amp;amp;→&amp;amp; \mathcal{G} 
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;TODO: Is &lt;span class=&quot;math math-inline&quot;&gt;H(c) = c\ P&lt;&#x2F;span&gt; sufficient?&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A, B: C = \mathrm{H}(c)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A → B: a\ C&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;B → A: b\ C&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A: a\ (b\ C) = ab\ C&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;B: b\ (a\ C) = ab\ C&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Now both parties have the same secret &lt;span class=&quot;math math-inline&quot;&gt;K = ab\ C&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;G&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;What about offline attacks?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;zero-knowledge-proof&quot;&gt;Zero-knowledge proof&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;blind-signatures&quot;&gt;Blind signatures&lt;&#x2F;h3&gt;
&lt;p&gt;The blind signature scheme allows a person to get a message signed by
another party without revealing any information about the message to the
other party. It differs from having the hash of the message signed by
the signer in that the signer can not determine which of a small set of
possible plaintexts the original message was.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;blinding&quot;&gt;Blinding&lt;&#x2F;h4&gt;
&lt;p&gt;Given a message m, the message can be &lt;em&gt;blinded&lt;&#x2F;em&gt; to make it unreadable to
the signer.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Generate a random number &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Computer &lt;span class=&quot;math math-inline&quot;&gt;B = b\ P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;M = m\ B&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Provide &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt; as the blinded message to be signed&lt;&#x2F;li&gt;
&lt;li&gt;Remember &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; as the blinding factor&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;M = m\ B = bm\ P&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;signing&quot;&gt;Signing&lt;&#x2F;h4&gt;
&lt;p&gt;Given a blinded message &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt; and an private key &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, the blinded message can
be signed by.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Calculate &lt;span class=&quot;math math-inline&quot;&gt;S = a\ M&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Provide &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; as the signature.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;S = a\ M = abm\ P&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;unblinding&quot;&gt;Unblinding&lt;&#x2F;h4&gt;
&lt;p&gt;Given a blinded signature &lt;span class=&quot;math math-inline&quot;&gt;S&lt;&#x2F;span&gt; and blinding factor &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;, unblind the signature&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;b^{-1}&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;S&amp;#39; = b^{-1}\ S&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Provide &lt;span class=&quot;math math-inline&quot;&gt;S&amp;#39;&lt;&#x2F;span&gt; as the signature for &lt;span class=&quot;math math-inline&quot;&gt;M&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;S&amp;#39; = b^{-1}\ S = abb^{-1}m\ P = am\ P&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;verifying&quot;&gt;Verifying&lt;&#x2F;h4&gt;
&lt;h2 id=&quot;pairing-cryptography&quot;&gt;Pairing cryptography&lt;&#x2F;h2&gt;
&lt;p&gt;Given two groups &lt;span class=&quot;math math-inline&quot;&gt;\mathcal G&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G&amp;#39;}&lt;&#x2F;span&gt; written multiplicatively
and a bilinear non-degenerate map (a.k.a a paring) &lt;span class=&quot;math math-inline&quot;&gt;e : \mathcal{G} ×
\mathcal{G} → \mathcal{G&amp;#39;}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It is currently not known how to construct pairings with &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G} =
\mathcal{G&amp;#39;}&lt;&#x2F;span&gt;. Typically &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G}&lt;&#x2F;span&gt; is an elliptic-curve group and &lt;span class=&quot;math math-inline&quot;&gt;G&amp;#39;&lt;&#x2F;span&gt;
is a finite field. Weil and Tate pairings are two well-known pairing
schemes.&lt;&#x2F;p&gt;
&lt;p&gt;Bilinearity:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
∀_{P ∈ \mathcal{G}}, ∀_{Q ∈ \mathcal{G}} , ∀ a, b ∈ ℤ_q^* e(a\ P, b\ Q) = ab\ e(P, Q)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Non-degeneracy means that not every thing maps to the identity and in
fact, given an nonzero element &lt;span class=&quot;math math-inline&quot;&gt;P∈\mathcal{G}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;With parings one can efficiently solve DDHP since &lt;span class=&quot;math math-inline&quot;&gt;c = ab&lt;&#x2F;span&gt; if and only if
&lt;span class=&quot;math math-inline&quot;&gt;e(a\ P, b\ P) = e(P, c\ P)&lt;&#x2F;span&gt;. This solves the DDHP for &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G}&lt;&#x2F;span&gt; and
can be used as an oracle for the GDHP in &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It should also be noted that the DLP in &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G}&lt;&#x2F;span&gt; can be solved in
terms of the one in &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G&amp;#39;}&lt;&#x2F;span&gt;. Suppose &lt;span class=&quot;math math-inline&quot;&gt;Q = a\ P&lt;&#x2F;span&gt; and we can solve
then&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\log_P Q &amp;amp;= \log_{e(P, P)} {e(P, Q)} \\ &amp;amp;= \log_{e(P, P)}
{e(P, a\ P)} \\ &amp;amp;= \log_{e(P, P)} \left(a\ e(P, P) \right) \\
&amp;amp;= a
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It also introduces a new problem:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bilinear Diffie-Helman problem (BDHP): given given &lt;span class=&quot;math math-inline&quot;&gt;P&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;aP&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;bP&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;cP&lt;&#x2F;span&gt;
in &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G}&lt;&#x2F;span&gt;, compute &lt;span class=&quot;math math-inline&quot;&gt;abc e(P,P)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;3-party-diffie-helman-agreement&quot;&gt;3-party Diffie-Helman agreement&lt;&#x2F;h3&gt;
&lt;p&gt;Three parties &lt;span class=&quot;math math-inline&quot;&gt;A&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;C&lt;&#x2F;span&gt; have secrets &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;c&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A → B, C: a\ P&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;B → A, C: b\ P&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;C → A, B: c\ P&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;A: a\ e(bP, cP) = abc\ e(P, P)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;B: b\ e(aP, cP) = abc\ e(P, P)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;span class=&quot;math math-inline&quot;&gt;C: c\ e(aP, bP) = abc\ e(P, P)&lt;&#x2F;span&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that this scheme is not secure under the &lt;em&gt;IND-CCA2&lt;&#x2F;em&gt; model, which
means it is vulnerable to adaptive chosen-ciphertext attacks. It can be
made secure with the Fujisaki-Okamoto construction. Essentially this
amounts to adding a random nonce to the message and including a hash.
The scheme is then secure under the &lt;em&gt;IND-CCA2&lt;&#x2F;em&gt; model with the BDH
assumption, the Random Oracle model and the hash.&lt;&#x2F;p&gt;
&lt;p&gt;Other desirable properties are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Recipient anonymity&lt;&#x2F;em&gt;, or &lt;em&gt;key privacy&lt;&#x2F;em&gt;: it should not be possible
to determine which public key was used in the encryption process.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note that steps &lt;span class=&quot;math math-inline&quot;&gt;(1, 2, 3)&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;(4, 5, 6)&lt;&#x2F;span&gt; can be done in parallel. At the
end all parties have the same secret &lt;span class=&quot;math math-inline&quot;&gt;K = abc\ e(P, P)&lt;&#x2F;span&gt; in &lt;span class=&quot;math math-inline&quot;&gt;\mathcal{G&amp;#39;}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;identity-based-encryption&quot;&gt;Identity-based encryption&lt;&#x2F;h3&gt;
&lt;p&gt;The public key can be arbitrary text strings, and therefore do not have
to be looked up.&lt;&#x2F;p&gt;
&lt;p&gt;It allows for a lazy PKI, people can encrypt messages for the recipient,
and when the recipient wants to open them, he can ask the authority for
the private key belonging to his identity. The authority can hand out
the private key after the users authority is verified. Note that after
the initial set up and domain parameter distribution, the authority is
only involved for retrieving the private key lazily.&lt;&#x2F;p&gt;
&lt;p&gt;Set up a paring as above, a secret key s known only to the authority,
public key &lt;span class=&quot;math math-inline&quot;&gt;s\ P&lt;&#x2F;span&gt; known to all parties and two random oracles:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{H_1} &amp;amp;:&amp;amp; &amp;amp; \{0,1\}^* &amp;amp;→&amp;amp; \mathcal{G} \\
\mathrm{H_2} &amp;amp;:&amp;amp; &amp;amp; \mathcal{G&amp;#39;} &amp;amp;→&amp;amp; \{0,1\}^*
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;encrypt&quot;&gt;Encrypt&lt;&#x2F;h4&gt;
&lt;p&gt;Encrypt a message &lt;span class=&quot;math math-inline&quot;&gt;M ∈ {0,1}^*&lt;&#x2F;span&gt; to public key &lt;span class=&quot;math math-inline&quot;&gt;A ∈ {0,1}^*&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Pick a random number &lt;span class=&quot;math math-inline&quot;&gt;r&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;Q = \mathrm{H_A}(A)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;G = e(Q, s\ P)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;G&amp;#39; = r\ G&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Encrypt the message using key stream &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{H_2}(G&amp;#39;)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;r\ P&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Provide &lt;span class=&quot;math math-inline&quot;&gt;r\ P&lt;&#x2F;span&gt; and the ciphertext to the recipient.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;G&amp;#39; = r\ G = r\ e(Q, s\ P) = sr\ e(Q, P)&lt;&#x2F;span&gt;, this will be
important when decrypting.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;deriving-the-private-key&quot;&gt;Deriving the private key&lt;&#x2F;h4&gt;
&lt;p&gt;Given a public key &lt;span class=&quot;math math-inline&quot;&gt;A ∈ {0,1}^*&lt;&#x2F;span&gt; the authority can derive the
corresponding private key:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Validate the identity of requester&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;Q = \mathrm{H_A}(A)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;D = s\ Q&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Provide &lt;span class=&quot;math math-inline&quot;&gt;D&lt;&#x2F;span&gt; as the private key&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;decryption-1&quot;&gt;Decryption&lt;&#x2F;h4&gt;
&lt;p&gt;Given a private key &lt;span class=&quot;math math-inline&quot;&gt;D&lt;&#x2F;span&gt;, the ciphertext and &lt;span class=&quot;math math-inline&quot;&gt;r\ P&lt;&#x2F;span&gt; construct as above.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;G&amp;#39; = e(D, r\ P)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Decrypt the ciphertext using the keystream &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{H_2}(G&amp;#39;)&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Note that &lt;span class=&quot;math math-inline&quot;&gt;G&amp;#39; = e(D, r\ P) = e(s\ Q, r\ P) = sr\ e(Q, P)&lt;&#x2F;span&gt; and thus
equals the &lt;span class=&quot;math math-inline&quot;&gt;G&amp;#39;&lt;&#x2F;span&gt; from the encryption process.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;final-remarks&quot;&gt;Final remarks&lt;&#x2F;h4&gt;
&lt;p&gt;Note that this scheme is not secure under the &lt;em&gt;IND-CCA2&lt;&#x2F;em&gt; model, which
means it is vulnerable to adaptive chosen-ciphertext attacks. It can be
made secure with the Fujisaki-Okamoto construction. Essentially this
amounts to adding a random nonce to the message and including a hash.
The scheme is then secure under the &lt;em&gt;IND-CCA2&lt;&#x2F;em&gt; model with the BDH
assumption, the Random Oracle model and the hash.&lt;&#x2F;p&gt;
&lt;p&gt;Other desirable properties are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Recipient anonymity&lt;&#x2F;em&gt;, or &lt;em&gt;key privacy&lt;&#x2F;em&gt;: it should not be possible
to determine which public key was used in the encryption process.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;attribute-based-encryption&quot;&gt;Attribute based encryption&lt;&#x2F;h3&gt;
&lt;p&gt;Attribute based encryption builds upon identity based encryption by
adding to the key management, the algorithms are the same. Attributes
take the form of credentials issued by an authority that is in essence
an AA (attribute authority).&lt;&#x2F;p&gt;
&lt;p&gt;Can implement any access-control policy expressible as a monotone
boolean formula on attribute values. That is, any function using &lt;em&gt;and&lt;&#x2F;em&gt;
and &lt;em&gt;or&lt;&#x2F;em&gt; without negation over the attributes. Should it be required the
absence of an attribute can be implemented as a separate attribute.&lt;&#x2F;p&gt;
&lt;p&gt;A resource protected with an access-control policy can only be read
using a key with attributes that satisfy the access-control policy. In
particular it is not possible to collude.&lt;&#x2F;p&gt;
&lt;p&gt;First the boolean function to is converted to &lt;em&gt;disjunctive normal form&lt;&#x2F;em&gt;
or another form involving only attributes, and and or operations. Some
algorithms optimize these for size and might be relevant:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Quine%E2%80%93McCluskey_algorithm&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Quine%E2%80%93McCluskey_algorithm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Espresso_heuristic_logic_minimizer&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Espresso_heuristic_logic_minimizer&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Given a message m to be encrypted with attribute a. Encrypt the message
using identity based encryption on identity &quot;a&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Given a message m to be encrypted with attribute a for user u. Encrypt
the message with identity &quot;u || a&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;For key management purposes it can be useful to add expiry dates to the
keys. Given a message m to be encrypted with attribute a for user u
valid in month x. Encrypt the message with identity &quot;u || a || x&quot;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;disjunctive-construction&quot;&gt;Disjunctive construction&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f = f_1 ∨ f_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;κ&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute a perfect &lt;span class=&quot;math math-inline&quot;&gt;(2,2)&lt;&#x2F;span&gt;-sharing of &lt;span class=&quot;math math-inline&quot;&gt;κ&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;κ_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;κ_2&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;f(κ) = (f_1(κ), f_2(κ))&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;To recover &lt;span class=&quot;math math-inline&quot;&gt;κ&lt;&#x2F;span&gt; both &lt;span class=&quot;math math-inline&quot;&gt;f_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;f_2&lt;&#x2F;span&gt; are required. With generic &lt;em&gt;j&lt;&#x2F;em&gt; out of
&lt;em&gt;n&lt;&#x2F;em&gt; sharing schemes this can be generalized.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;conjunctive-construction&quot;&gt;Conjunctive construction&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f = f_1 ∧ f_2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Given &lt;span class=&quot;math math-inline&quot;&gt;κ&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Compute a perfect &lt;span class=&quot;math math-inline&quot;&gt;(2, 2)&lt;&#x2F;span&gt;-sharing of &lt;span class=&quot;math math-inline&quot;&gt;κ&lt;&#x2F;span&gt; as &lt;span class=&quot;math math-inline&quot;&gt;κ_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;κ_2&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Compute &lt;span class=&quot;math math-inline&quot;&gt;f(κ) = (f_1(κ_1), f_2(κ_2))&lt;&#x2F;span&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;To recover &lt;span class=&quot;math math-inline&quot;&gt;κ&lt;&#x2F;span&gt; either &lt;span class=&quot;math math-inline&quot;&gt;f_1&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;f_2&lt;&#x2F;span&gt; can be used.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;key-revocation-schemes&quot;&gt;Key revocation schemes&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;functional-encryption&quot;&gt;Functional Encryption&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;libfenc&#x2F;&quot;&gt;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;libfenc&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;homomorphic-cryptography&quot;&gt;Homomorphic cryptography&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;additive-homomorphic&quot;&gt;Additive homomorphic&lt;&#x2F;h3&gt;
&lt;p&gt;e.g. Damgård–Jurik cryptosystem&lt;&#x2F;p&gt;
&lt;p&gt;Additive homomorphic: given only the public key and the ciphertext of
&lt;span class=&quot;math math-inline&quot;&gt;m_1&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;m_2&lt;&#x2F;span&gt;, you can derive the encryption of &lt;span class=&quot;math math-inline&quot;&gt;m_1 + m_2&lt;&#x2F;span&gt;. As a
consequence, it is also possible to do multiplication by a plaintext
integer.&lt;&#x2F;p&gt;
&lt;p&gt;The encryption is also randomized, encrypting the same plaintexts with
the same keys will result in different ciphertexts. A blinding operation
can be implemented by encrypting 0 and adding it to the ciphertext.&lt;&#x2F;p&gt;
&lt;p&gt;The Pallier cryptosystem, which is very similar, with an additional hash
can be proven &lt;em&gt;IND-CCA2&lt;&#x2F;em&gt; secure in the random oracle model under the
DCRA assumption.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;signed-network-coding&quot;&gt;Signed network coding&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Homomorphic_Signatures_for_Network_Coding&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Homomorphic_Signatures_for_Network_Coding&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fully-homomorphic&quot;&gt;Fully homomorphic&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cs.ut.ee&#x2F;~lipmaa&#x2F;crypto&#x2F;link&#x2F;public&#x2F;homomorphic.php&quot;&gt;http:&#x2F;&#x2F;www.cs.ut.ee&#x2F;~lipmaa&#x2F;crypto&#x2F;link&#x2F;public&#x2F;homomorphic.php&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;shaih&#x2F;HElib&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;shaih&#x2F;HElib&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;thep&#x2F;&quot;&gt;https:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;thep&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;other&quot;&gt;Other&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;hms.isi.jhu.edu&#x2F;acsc&#x2F;&quot;&gt;http:&#x2F;&#x2F;hms.isi.jhu.edu&#x2F;acsc&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;proof-of-work&quot;&gt;Proof-of-work&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;secret-sharing-scheme&quot;&gt;Secret sharing scheme&lt;&#x2F;h3&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Huge Graph Visualization</title>
        <published>2014-05-07T00:00:00+00:00</published>
        <updated>2014-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/huge-graph-visualization/"/>
        <id>https://2π.com/14/huge-graph-visualization/</id>
        
        <content type="html" xml:base="https://2π.com/14/huge-graph-visualization/">&lt;h1 id=&quot;huge-graph-visualization&quot;&gt;Huge Graph Visualization&lt;&#x2F;h1&gt;
&lt;!-- ![](gosper-worm-locality.png) --&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-plan&quot;&gt;The plan&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Sort nodes so that related nodes are closest&lt;&#x2F;li&gt;
&lt;li&gt;Points along a space filling curve&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Rapid Graph Layout Using Space Filling Curves
http:&#x2F;&#x2F;vis.cs.ucdavis.edu&#x2F;papers&#x2F;muelder_ma_rgl_2008.pdf
Network data frequently arises in a wide variety of fields, and
node-link diagrams are a very natural and intuitive represen- tation of
such data. In order for a node-link diagram to be effective, the nodes
must be arranged well on the screen. While many graph layout algorithms
exist…
Large-Scale Graph Visualization and Analytics
http:&#x2F;&#x2F;vis.cs.ucdavis.edu&#x2F;papers&#x2F;computer2013-graphvis.pdf
Novel approaches to network visualization and analytics use
sophisticated metrics that enable rich interactive network views and
node grouping and filtering. A survey of graph layout and simplification
methods reveals considerable progress in these new directions.
&quot;Fast Modularity&quot; Community Structure Inference Algorithm
http:&#x2F;&#x2F;cs.unm.edu&#x2F;~aaron&#x2F;research&#x2F;fastmodularity.htm
This page documents and supports the fast modularity maximization
algorithm I developed jointly with Mark Newman and Cristopher Moore.
This algorithm is being widely used in the community of complex network
researchers…&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-peano-gosper-curve&quot;&gt;The Peano-Gosper curve&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;producing-the-curve&quot;&gt;Producing the curve&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;gosper-worm1.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;gosper-worm2.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;gosper-worm3.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;gosper-worm4.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;gosper-worm5.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;gosper-worm6.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The matrix&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{1}{14} \begin{bmatrix} -\sqrt{3} &amp;amp; 5 \\ 0.2474 &amp;amp; 4 \end{bmatrix}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The source&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;static const double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; CAsin &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0.12371791482634837810910331010756231192448608955788433057541&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; -sqrt(3) &#x2F; 14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;static const double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; CAcos &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;static const double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; CBsin &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.247435829652696756218206620215124623848972179115768661150829&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;static const double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; CBcos &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7.0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-flowsnake-in-c&quot;&gt;The Flowsnake in C++&lt;&#x2F;h3&gt;
&lt;p&gt;Aperiodic space-filling curves?&lt;&#x2F;p&gt;
&lt;p&gt;Write a curve in recursive aperiodic titles?
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Penrose_tiling&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Penrose_tiling&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Alternative:&lt;&#x2F;p&gt;
&lt;p&gt;Place points using Poisson disk. Create a weighted graph out of the
distances. Apply linearisation to the weight matrix. Now the points are
sorted and can be used as in the space-filling case.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Low-discrepancy_sequence&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Low-discrepancy_sequence&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;full-graph&quot;&gt;Full graph&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;full-graph.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This reminds me of electron diffraction patterns in crystals, also very
beautiful.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;electron-diffraction.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;electron-diffraction2.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Right, back to our main goal.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;locality&quot;&gt;Locality&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;gosper-worm-locality.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The graph has roughly 17 thousand nodes and 34 thousand edges.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-data&quot;&gt;Test data&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-hairball.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-hairball-adjacency.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;walktrap-ordering&quot;&gt;Walktrap ordering&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-2.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-2-adjacency.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;balancing-the-binary-tree&quot;&gt;Balancing the binary tree&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s now look at the community hierarchy:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-2-tree.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-4-tree.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-4.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-4-adjacency.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sorting-the-binary-tree&quot;&gt;Sorting the binary tree&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-5-tree.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-5.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;14&#x2F;huge-graph-visualization&#x2F;testgraph-walktrap-5-adjacency.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;separating-the-communities&quot;&gt;Separating the communities&lt;&#x2F;h2&gt;
&lt;p&gt;Compared to the first plot, the community structure suffered from
sorting, because now the interacting communities are forced closer
together.&lt;&#x2F;p&gt;
&lt;p&gt;TODO:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Recursive cluster&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Identities</title>
        <published>2014-05-07T00:00:00+00:00</published>
        <updated>2014-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/identities/"/>
        <id>https://2π.com/14/identities/</id>
        
        <content type="html" xml:base="https://2π.com/14/identities/">&lt;h1 id=&quot;identities&quot;&gt;Identities&lt;&#x2F;h1&gt;
&lt;p&gt;The mathematical identities from my Advanced Quantum Mechanics course note:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Γ(z+1) = z Γ(z)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
Γ(1-ε) Γ(ε) = \frac{π}{\sin {πε}} = ε + \frac{π^2}{6}\frac{1}{ε} + O\left(\frac{1}{ε^3}\right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
∫_0^∞ \mathrm{d} x; x^α \mathrm{e}^{-βx} = Γ(1+α)β^{-(1+α)}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x^{-1} = ∫_0^∞ \mathrm{d} α; \mathrm{e}^{-αx}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
∫_0^∞ \mathrm{d} x; x^α (1-x)^β = Γ(1+α)Γ(1+β) &#x2F; Γ(1 + α + β)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
∫_0^∞ \mathrm{d} a_1; \cdots ∫_0^∞ \mathrm{d} a_n; f\left(sum a_i \right) = frac{1}{(n-1)!} ∫_0^∞ \mathrm{d} s; s^{n-1} f(s)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Miller-Rabin primality test</title>
        <published>2014-05-07T00:00:00+00:00</published>
        <updated>2014-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/primality-testing/"/>
        <id>https://2π.com/14/primality-testing/</id>
        
        <content type="html" xml:base="https://2π.com/14/primality-testing/">&lt;h1 id=&quot;the-miller-rabin-primality-test&quot;&gt;The Miller-Rabin primality test&lt;&#x2F;h1&gt;
&lt;p&gt;The Miller-Rabin primality test&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Modular multiplication&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The first factor, a &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The second factor, b &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The reduced product, a b mod m &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Perform 128 multiplication and division&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; q = ⌊a b &#x2F; m⌋&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; r = a b mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;mulq %3;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;		&amp;quot;divq %4;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;=a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;=d&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Modular exponentiation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The base, b &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The exponent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The reduced power of a, a^b mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Miller-Rabin probabilistic primality testing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number to test for  primality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The witness for primality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True iff n is a k-stong pseudoprime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; millerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Factor n-1 as d*2^s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Verify x = k^(d 2^i) mod n != 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-- &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; x = x^2 mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;miller-rabin.appspot.com&#x2F;&quot;&gt;https:&#x2F;&#x2F;miller-rabin.appspot.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; isPrime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Small primes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 13&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 29&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 31&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 37&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 41&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 43&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 47&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 53&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 59&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 67&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 71&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 73&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Jim Sinclair&amp;#39;s Miller-Rabin base for 2^64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;millerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; || !&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;millerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 325&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; || !&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;millerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9375&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	|| !&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;millerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 28178&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; || !&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;millerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 450775&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	|| !&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;millerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9780504&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; || !&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;millerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1795265022&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Must be prime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Convergent Encryption</title>
        <published>2014-03-20T00:00:00+00:00</published>
        <updated>2014-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/convergent-encryption/"/>
        <id>https://2π.com/14/convergent-encryption/</id>
        
        <content type="html" xml:base="https://2π.com/14/convergent-encryption/">&lt;h1 id=&quot;convergent-encryption&quot;&gt;Convergent Encryption&lt;&#x2F;h1&gt;
&lt;!--

Convergent encrypt allowed one cloud storage provider to claim ‘infinite storage’ in addition to ‘security’. For another storage provider it resulted in controversy when some of the weaknesses became apparent. Convergent encryption is an interesting trade-off between efficiency and privacy. At the epicenter is an interesting question: Can a file provide the entropy for its own key? In this article I will explain the situation both practically and technically.

--&gt;
&lt;h2 id=&quot;value-of-deduplication&quot;&gt;Value of deduplication&lt;&#x2F;h2&gt;
&lt;p&gt;When storing large amounts of data it is efficient to store duplicate
data only once, a process called deduplication. This is particularly
interesting in large corporate networks where many machines contain
identical documents. A randomly selected sample of 585 desktops at
Microsoft has revealed of the total 685 GB of documents only 368 GB was
unique. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;research.microsoft.com&#x2F;pubs&#x2F;69954&#x2F;tr-2002-30.pdf&quot;&gt;1&lt;&#x2F;a&gt;
This implies that up to half of the space can be saved by deduplication.&lt;&#x2F;p&gt;
&lt;p&gt;Even more space can be saved by finding duplicate content inside
different, but similar files. Such files arise often when storing
different versions of the same document. An experiment was done by
Coblue: A LibreOffice writer document containing several megabytes of
images had some changes made. Images where added, removed, rearranged
and the text was edited. When storing the different versions together,
the total storage space required was little more than the sum of the
sizes of the large images. This result was surprising, because Open
Document Format files are compressed and a single byte change could
change the whole file (much like with encrypted files).&lt;&#x2F;p&gt;
&lt;p&gt;Deduplication has more advantages than saving space. When synchronizing
machines, deduplication can minimize the amount of data that must be
transfered. This reduces bandwidth consumption and speeds up the
synchronization process. Faster synchronization in turn leads to less
divergence and more resilience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;content-addressable-storage&quot;&gt;Content addressable storage&lt;&#x2F;h2&gt;
&lt;p&gt;A simple but insecure method of deduplication is using a
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Content-addressable_storage&quot;&gt;content-addressable storage&lt;&#x2F;a&gt;
(CAS). A CAS has two operations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;put&lt;&#x2F;code&gt;: content address → data&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;get&lt;&#x2F;code&gt;: data → content address&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To store a file or other large piece of binary data the &lt;code&gt;put&lt;&#x2F;code&gt; method is
called which results in an short address. Ideally, calling &lt;code&gt;put&lt;&#x2F;code&gt; with
the same data will always result in the same address and calling &lt;code&gt;put&lt;&#x2F;code&gt;
with different data will always result in a different address. Once
&lt;code&gt;put&lt;&#x2F;code&gt; is called at least once, the data can then be retrieved with
&lt;code&gt;get&lt;&#x2F;code&gt;. Note that &lt;code&gt;get&lt;&#x2F;code&gt; requires the address, of the data, so the
interface nicely forces that &lt;code&gt;put&lt;&#x2F;code&gt; is called first.&lt;&#x2F;p&gt;
&lt;p&gt;Often the content addresses are cryptographic hashes of the data. And
the CAS is implemented as an associative array of addresses to data.
When the determining the address length the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Birthday_attack&quot;&gt;birthday attack&lt;&#x2F;a&gt; should be taken
into account. As a guideline, 128 bits seem enough to prevent an
attacker from colliding with a given pre-existing file (possibly
corrupting that file) and 256 bit seem enough to prevent an attacker
from manufacturing two files that collide with each other (possibly
confusing the system). This is assuming the brute force is the best
attack on the hash function.&lt;&#x2F;p&gt;
&lt;p&gt;Resilience is an important quality of hash-based content-addressable
storage. If data is lost at one location, but a (H, X&#x27;) pair is
recovered it can be verified to be correct. This will work no matter
whether the pair came from. A backup system, a shady figure in an ally
or a fortuneteller, the source doesn’t have to be trustworthy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;privacy-and-deduplication&quot;&gt;Privacy and deduplication&lt;&#x2F;h2&gt;
&lt;p&gt;The hashed associative array approach does not provide any privacy.
Anyone with access to the raw associative array can list the contents of
all the stored files. It is possible to encrypt all the files before
storing them, but if the same file is encrypted with a different key,
the encrypted files will be different and the deduplication will fail.
This could be solved by encrypting all the files with the same key, but
then everyone with some access would immediately have full access.&lt;&#x2F;p&gt;
&lt;p&gt;We need a solution with different encryption keys for every file but
that still deduplicates files. This may seem paradoxical, until you bend
the rules slightly to require different encryption keys for every
&lt;em&gt;different&lt;&#x2F;em&gt; file. You can then have equal keys for equal files. Equal
files, equal keys thus equal encrypted data and problem solved!&lt;&#x2F;p&gt;
&lt;p&gt;In &lt;em&gt;convergent encryption&lt;&#x2F;em&gt; this is done by taking a hash of the
unencrypted file as the encryption key. This is safe because you need
the key to decrypt the file, unless you have already have the
unencrypted file, but then there is nothing left to secure.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is not to be confused with &lt;em&gt;deterministic encryption&lt;&#x2F;em&gt;, which
means the same output for the same input. Allmost all modern
cryptographic algorithms such as RSA, ECDSA and AES are deterministic.
They are made non-deterministic by introducing a random salt or an
initialization vector.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It was famously used by bitcasa to claim ‘infinite storage’, but it is
also used by: Dropbox, Wuala, Tahou-LAFS, Microsoft Farsite, Permabit,
Freenet, GNUnet, flud, MojoNation&lt;&#x2F;p&gt;
&lt;h2 id=&quot;convergent-encryption-1&quot;&gt;Convergent encryption&lt;&#x2F;h2&gt;
&lt;p&gt;First we need some ingredients. Take the cryptographic primitives&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{H_A} &amp;amp;: &amp;amp;\{0,1\}^{*} &amp;amp;→ \{0,1\}^{l_A} \\
\mathrm{H_B} &amp;amp;: &amp;amp;\{0,1\}^{*} &amp;amp;→ \{0,1\}^{l_B} \\ \mathrm{E}
&amp;amp;: &amp;amp;\{0,1\}^{l_K} × \{0,1\}^{*} &amp;amp;→ \{0,1\}^{*} \\
\mathrm{D} &amp;amp;: &amp;amp;\{0,1\}^{l_K} × \{0,1\}^{*} &amp;amp;→ \{0,1\}^{*}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{H_A}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{H_B}&lt;&#x2F;span&gt; are cryptographic hash functions
of length &lt;span class=&quot;math math-inline&quot;&gt;l_A&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;l_B&lt;&#x2F;span&gt; respectively and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{E}&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{D}&lt;&#x2F;span&gt; are
symmetric encryption and decryption functions with key length &lt;span class=&quot;math math-inline&quot;&gt;l_K&lt;&#x2F;span&gt;. This
implies that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{H_A}(X_1) &amp;amp;= \mathrm{H_A}(X_2) &amp;amp;&amp;amp;⇔ &amp;amp;X_1 &amp;amp;= X_2 \\
\mathrm{H_B}(X_2) &amp;amp;= \mathrm{H_B}(X_2) &amp;amp;&amp;amp;⇔ &amp;amp;X_1 &amp;amp;= X_2 \\
\mathrm{D}(K_1, \mathrm{E}(K_2, X)) &amp;amp;= X &amp;amp;&amp;amp;⇔ &amp;amp; K_1 &amp;amp;= K_2 
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where the implications in the leftward direction are exact but in the
rightward implications are only with cryptographic confidence. This will
be important later in the security analysis. For permanent storage, we
will use an associative array with interface&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{Store} &amp;amp;:&amp;amp; \{0,1\}^{l_B} × \{0,1\}^{*} &amp;amp;→ ∅ \\
\mathrm{Retrieve} &amp;amp;:&amp;amp; \{0,1\}^{l_B} &amp;amp;→ \{0,1\}^{*}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The convergent encryption store will have the interface&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{Put} &amp;amp;:&amp;amp; \{0,1\}^{*} &amp;amp;→ \{0,1\}^{l_B} ×
\{0,1\}^{l_A} \\ \mathrm{Get} &amp;amp;:&amp;amp; \{0,1\}^{l_B} ×
\{0,1\}^{l_A} &amp;amp;→ \{0,1\}^{*}
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{Put}&lt;&#x2F;span&gt; operation takes a piece of information and stores it
encrypted in the associative array. It is implemented as&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{Put}(X) &amp;amp;≕ (H, K)\\ K &amp;amp;= \mathrm{H_A}(X) \\ X&amp;#39; &amp;amp;=
\mathrm{E}(K, X) \\ H &amp;amp;= \mathrm{H_B}(X&amp;#39;) \\ &amp;amp;\phantom{=}
\mathrm{Store}(H, X&amp;#39;)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{Get}&lt;&#x2F;span&gt; operation is simply the inverse operation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
\mathrm{Get}(H, K) &amp;amp;≕ X \\ X&amp;#39; &amp;amp;= \mathrm{Retrieve}(H) \\ X &amp;amp;=
\mathrm{D}(K, X&amp;#39;)
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{Get}&lt;&#x2F;span&gt; operation can optionally verify the integrity of the
data by checking &lt;span class=&quot;math math-inline&quot;&gt;K = \mathrm{H_A}(X)&lt;&#x2F;span&gt; and&#x2F;or &lt;span class=&quot;math math-inline&quot;&gt;H = \mathrm{H_A}(X&amp;#39;)&lt;&#x2F;span&gt;.
The later has an advantage we will show below.&lt;&#x2F;p&gt;
&lt;p&gt;The implementation given above requires three passes through the data.
The passes have data dependencies so they can not be parallelized. It is
possible to develop a two-pass system. The hash H of the output stream
X&#x27; can be calculated while the output stream is being produced. This is
similar to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Authenticated_encryption&quot;&gt;authenticated encryption&lt;&#x2F;a&gt; but
differs in the use of a hash instead of a message authentication code.
But it is not possible to construct a one-pass system that de-duplicates
and has at least the security of convergent encryption. In a one-pass
system, the first couple of bytes can not rely on all the remaining
bytes. But this is necessary to have a key with the entropy of the
entire file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;weaknesses&quot;&gt;Weaknesses&lt;&#x2F;h2&gt;
&lt;p&gt;Assuming the attacker has access to the associative array and knows the
functions used, what can he do?&lt;&#x2F;p&gt;
&lt;p&gt;The associative array only stores ciphertext &lt;span class=&quot;math math-inline&quot;&gt;X&amp;#39;&lt;&#x2F;span&gt; and the hashes thereof,
&lt;span class=&quot;math math-inline&quot;&gt;H = H_B(X&amp;#39;)&lt;&#x2F;span&gt;. It never stores the plaintext &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; or even the hash of the
plaintext K.&lt;&#x2F;p&gt;
&lt;p&gt;It is not possible for an attacker to manipulate the stored information.
If the attacker where to change a pair &lt;span class=&quot;math math-inline&quot;&gt;(H, X&amp;#39;)&lt;&#x2F;span&gt; into &lt;span class=&quot;math math-inline&quot;&gt;(H, X&amp;#39;&amp;#39;)&lt;&#x2F;span&gt; it can be
detected because the relation &lt;span class=&quot;math math-inline&quot;&gt;H = H_B(X&amp;#39;)&lt;&#x2F;span&gt; will no longer hold. This
check only requires knowledge of &lt;span class=&quot;math math-inline&quot;&gt;H_B&lt;&#x2F;span&gt;, the verifier does not even have
to have the key to the data &lt;span class=&quot;math math-inline&quot;&gt;K&lt;&#x2F;span&gt;. It is therefore advisable to implement
this check at any place where such manipulation might occur.&lt;&#x2F;p&gt;
&lt;p&gt;It is possible for an attacker to remove information. If the attacker
somehow knows the H it can remove the pair and make the information
unavailable. Or it can simply remove the entire associative array. Or
the system containing the associative array could catch fire. Fending
off these attacks is about having backup systems in place and preventing
unauthorized access. The inherent resilience of hash-based
content-addressable storage will solve the rest.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;confirmation-attack&quot;&gt;Confirmation attack&lt;&#x2F;h3&gt;
&lt;p&gt;A more fundamental problem with convergent encryption is the
confirmation attack. Here an attacker can check if a given key &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt; is in
the associative array. If the attacker can do this, he can also check if
a given plaintext &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; is in the associative array by checking the presence
of&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
H = \mathrm{H_B}(\mathrm{E}(\mathrm{H_A}(X), X)))
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If no preventative measures are taken, this could allow an attacker to
confirm if the user is in possession of a certain file, for example a
banned book or a pirated movie.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;offline-brute-force-attack&quot;&gt;Offline brute-force attack&lt;&#x2F;h3&gt;
&lt;p&gt;In an offline attack the attacker can try key combinations at his
leisure without the risk of discovery or interference. It could for
example mount a brute-force attack by trying out all possible keys until
the right one is found.&lt;&#x2F;p&gt;
&lt;p&gt;Determining when the right key is found is hard in conventional
encryption systems. Every possible key will result in some sort of
plaintext, correct or not. Determining what the correct plaintext looks
like involves a heuristic. In general it is impossible to find such a
heuristic, and this is what provides the one-time pad with its perfect
security.&lt;&#x2F;p&gt;
&lt;p&gt;In convergent encryption it is easy to recognize the correct key. The
correct key K will satisfy the equation&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
K = \mathrm{H_A}(\mathrm{D}(K, X&amp;#39;))
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;While theoretically interesting, offline brute-force attacks on
conventional symmetric cyphers are already possible in practice.
Plaintexts often contain easily recognizable structures such as file
headers. This can then be used as an effective heuristic to check if the
correct key is found. Such an attack will work on any cipher where keys
are significantly shorter than the messages, which in practice means
anything but the one-time pad.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;learn-the-remaining-attack&quot;&gt;Learn the remaining attack&lt;&#x2F;h3&gt;
&lt;p&gt;Perhaps the most important of the possible attacks is the learn the
remaining attack. Suppose an attacker knows most of the file, for
example if the file is a PDF form where the user needs to fill in
sensitive information, say a PIN code. The attacker can now create all
possible versions of the file X and check if it matches a ciphertext X&#x27;
by encrypting and comparing or using the identity&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
X = \mathrm{D}(\mathrm{H_A}(X), X&amp;#39;))
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In fact, the attacker does not even need to have the value &lt;span class=&quot;math math-inline&quot;&gt;X&amp;#39;&lt;&#x2F;span&gt;, it is
sufficient to check if a given key &lt;span class=&quot;math math-inline&quot;&gt;H&lt;&#x2F;span&gt; is in the associative array using
the equation given above.&lt;&#x2F;p&gt;
&lt;p&gt;This attack is possible when &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt; is known to be a member of a small set.
The set of possible &lt;span class=&quot;math math-inline&quot;&gt;X&lt;&#x2F;span&gt;&#x27;s can then be exhaustively tried at the small cost
of three hashing and one encryption operation per try. Or in information
theoretical terms: when the relative entropy of the plaintext relative
to the attacker is low.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;domain-separation&quot;&gt;Domain separation&lt;&#x2F;h2&gt;
&lt;p&gt;Suppose we make &lt;span class=&quot;math math-inline&quot;&gt;\mathrm{H_A}&lt;&#x2F;span&gt; a &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Message_authentication_code&quot;&gt;keyed hash function&lt;&#x2F;a&gt;
with a key &lt;span class=&quot;math math-inline&quot;&gt;K_A&lt;&#x2F;span&gt;. This will thwart attacks relying on knowledge of
&lt;span class=&quot;math math-inline&quot;&gt;\mathrm{H_A}&lt;&#x2F;span&gt;, unless the attacker knows the key. This includes all
major the attacks mentioned above. The downside is that it also
restricts deduplication to data encrypted with the same &lt;span class=&quot;math math-inline&quot;&gt;K_A&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The different &lt;span class=&quot;math math-inline&quot;&gt;K_A&lt;&#x2F;span&gt; effectively create different domains. Within such a
domain, deduplication happens. But anyone within the domain can also
confirm that certain files are stored, or even use the learn the
remaining attack to find which of a small set of possible files is
stored. From outside the domain, all the encryption keys K depend on the
domain key &lt;span class=&quot;math math-inline&quot;&gt;K_A&lt;&#x2F;span&gt;. The domains are thus at least as secure as when they
where encrypted using just the domain key.&lt;&#x2F;p&gt;
&lt;p&gt;Where the domain boundaries should be, or when to use different &lt;span class=&quot;math math-inline&quot;&gt;K_A&lt;&#x2F;span&gt;&#x27;s
will be an important design decision. Larger domains will result in more
deduplication and a more efficient system, but it will also leak some
knowledge about what is stored in the system to a larger group.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cryptographic-tuning&quot;&gt;Cryptographic tuning&lt;&#x2F;h2&gt;
&lt;p&gt;For the system to function properly it relies on:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;H_B&lt;&#x2F;span&gt; needs pre-image resistance to prevent an attacker from manipulating
data undetectably. Collision resistance would be required if the
implementation can not handle hash collisions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;H_A&lt;&#x2F;span&gt; needs to be a good &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Randomness_extractor&quot;&gt;randomness extractor&lt;&#x2F;a&gt;. Its role
is to extract sufficient entropy from the plaintext to create a key. A
hash that maps the plaintext distribution uniformly to the set of
encryption keys will satisfy this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;see-also&quot;&gt;See also&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cypherpunks.venona.com&#x2F;date&#x2F;1996&#x2F;02&#x2F;msg02013.html&quot;&gt;http:&#x2F;&#x2F;cypherpunks.venona.com&#x2F;date&#x2F;1996&#x2F;02&#x2F;msg02013.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.usenix.org&#x2F;legacy&#x2F;event&#x2F;lisa10&#x2F;tech&#x2F;full_papers&#x2F;Anderson.pdf&quot;&gt;https:&#x2F;&#x2F;www.usenix.org&#x2F;legacy&#x2F;event&#x2F;lisa10&#x2F;tech&#x2F;full_papers&#x2F;Anderson.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;research.microsoft.com&#x2F;pubs&#x2F;69954&#x2F;tr-2002-30.pdf&quot;&gt;https:&#x2F;&#x2F;research.microsoft.com&#x2F;pubs&#x2F;69954&#x2F;tr-2002-30.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;research.microsoft.com&#x2F;pubs&#x2F;74262&#x2F;Sigmetrics2000.pdf&quot;&gt;https:&#x2F;&#x2F;research.microsoft.com&#x2F;pubs&#x2F;74262&#x2F;Sigmetrics2000.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ssrc.ucsc.edu&#x2F;Papers&#x2F;storer-storagess08.pdf&quot;&gt;http:&#x2F;&#x2F;www.ssrc.ucsc.edu&#x2F;Papers&#x2F;storer-storagess08.pdf&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tahoe-lafs.org&#x2F;pipermail&#x2F;tahoe-dev&#x2F;2008-March&#x2F;000449.html&quot;&gt;https:&#x2F;&#x2F;tahoe-lafs.org&#x2F;pipermail&#x2F;tahoe-dev&#x2F;2008-March&#x2F;000449.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;thesimplecomputer.info&#x2F;behind-the-curtain-of-encrypted-cloud-storage-page1&#x2F;&quot;&gt;http:&#x2F;&#x2F;thesimplecomputer.info&#x2F;behind-the-curtain-of-encrypted-cloud-storage-page1&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Convergent_encryption&quot;&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Convergent_encryption&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tahoe-lafs.org&#x2F;hacktahoelafs&#x2F;drew_perttula.html&quot;&gt;https:&#x2F;&#x2F;tahoe-lafs.org&#x2F;hacktahoelafs&#x2F;drew_perttula.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bitcasa.com&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.bitcasa.com&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tahoe-lafs.org&#x2F;&quot;&gt;https:&#x2F;&#x2F;tahoe-lafs.org&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forums.dropbox.com&#x2F;topic.php?id=48652&amp;amp;page=2&quot;&gt;https:&#x2F;&#x2F;forums.dropbox.com&#x2F;topic.php?id=48652&amp;amp;page=2&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;paranoia.dubfire.net&#x2F;2011&#x2F;04&#x2F;how-dropbox-sacrifices-user-privacy-for.html&quot;&gt;http:&#x2F;&#x2F;paranoia.dubfire.net&#x2F;2011&#x2F;04&#x2F;how-dropbox-sacrifices-user-privacy-for.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;http:&#x2F;&#x2F;patft.uspto.gov&#x2F;netacgi&#x2F;nph-Parser?Sect1=PTO1&amp;amp;Sect2=HITOFF&amp;amp;d=PALL&amp;amp;p=1&amp;amp;u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&amp;amp;r=1&amp;amp;f=G&amp;amp;l=50&amp;amp;s1=5778395.PN.&amp;amp;OS=PN&#x2F;5778395&amp;amp;RS=PN&#x2F;5778395&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;http:&#x2F;&#x2F;www.patents.com&#x2F;us-7437555.html&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;http:&#x2F;&#x2F;patft.uspto.gov&#x2F;netacgi&#x2F;nph-Parser?Sect1=PTO1&amp;amp;Sect2=HITOFF&amp;amp;d=PALL&amp;amp;p=1&amp;amp;u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&amp;amp;r=1&amp;amp;f=G&amp;amp;l=50&amp;amp;s1=7,412,462.PN.&amp;amp;OS=PN&#x2F;7,412,462&amp;amp;RS=PN&#x2F;7,412,462&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Jimmy-rig FM: The half-wave dipole antenna</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/jimmy-rig-fm/"/>
        <id>https://2π.com/09/jimmy-rig-fm/</id>
        
        <content type="html" xml:base="https://2π.com/09/jimmy-rig-fm/">&lt;h1 id=&quot;jimmy-rig-fm-the-half-wave-dipole-antenna&quot;&gt;Jimmy-rig FM: The half-wave dipole antenna&lt;&#x2F;h1&gt;
&lt;p&gt;Together with two friends I constructed an antenna for the Racal 9084
signal generator I &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;jimmy-rig-fm&#x2F;radio-remco&quot;&gt;posted about&lt;&#x2F;a&gt; to see how much we could
increase the range.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, the whole thing had to be constructed on a shoe-string
budget. Here’s how it went:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;design&quot;&gt;Design&lt;&#x2F;h2&gt;
&lt;p&gt;The goal is to create a simple antenna for approximately 94 Mhz. The
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dipole_antenna&quot;&gt;dipole&lt;&#x2F;a&gt; is on of the
easiest to build, it just requires two conductors of a certain length.
An often cited formula for deriving the total length of a half-wave
dipole antenna is: &lt;span class=&quot;math math-inline&quot;&gt;l = 0.95 \frac{1}{2} \lambda \approx \frac{142
\mathrm{[m]}}{f \mathrm{[Mhz]}} \mathrm{[m]} = \frac{142
\mathrm{[m]}}{94 \mathrm{[Mhz]}} \mathrm{[m]} = 1.51 \mathrm{[m]}&lt;&#x2F;span&gt; So
the antenna works out to be about one and a half meter.&lt;&#x2F;p&gt;
&lt;p&gt;Next is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.orgwikiImpedance_matching&quot;&gt;impedance
matching&lt;&#x2F;a&gt; so we can get
the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.orgwikiMaximum_power_theorem&quot;&gt;maximum power&lt;&#x2F;a&gt;
out of the transmitter without blowing it up. On wikipedia it is derived
that the resistance of the antenna is about 73 Ω. The transmitter is
designed for a 50 Ω load, so the matching is not that necessary.&lt;&#x2F;p&gt;
&lt;p&gt;However, it is necessary to convert the unbalanced (signal + ground)
feed into an balanced (signal + negative signal) feed for the antenna.
This can be done using a device called a
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Balun&quot;&gt;balun&lt;&#x2F;a&gt;. For this application we
designed an
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Autotransformer&quot;&gt;autotransformer&lt;&#x2F;a&gt; style
balun like this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;jimmy-rig-fm&#x2F;200910202349_118.jpg&quot; alt=&quot;Diagram of the balun&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;By connecting the ground half way between the positive signal and
negative antenna lead and placing the signal on the positive side a
balanced signal is created.&lt;&#x2F;p&gt;
&lt;p&gt;But, if I were to connect the input signal directly to the positive
antenna lead the effective load would change: the turn ratio would be
2:1, the impedance ratio 4:1 and the effective load would be about 18 Ω,
much less than 50 Ω!&lt;&#x2F;p&gt;
&lt;p&gt;This is because the voltage and current depend linearly on the number of
windings, so the impedance depends quadratically on the number of
windings. The load over the antenna is about 72 Ω and has 2×N windings,
this means the number of windings for the transmitter has to be about
1.7×N to create a 50 Ω load. This can easily be done by adding a 0.7×N
windings to the right of the transformer, as shown in the diagram.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;build&quot;&gt;Build&lt;&#x2F;h2&gt;
&lt;p&gt;The antenna was cheaply constructed using steel-cored clothes line,
tape, rope and electric tubing. I bet the radio frequency conductive
properties of clothes line are very bad, but we’ll see. For the balun I
salvaged a ferrite core from a broken computer power supply (I counted a
total of twelve transformers and chokes in it, they are packed with
them!). The power supplies operate at a few kHz and the ferrites are not
designed for operation at a hundred Mhz, but we’ll see. I then wound
three wires 20, 20 and 14 times and soldered the thing to a pcb with
some nice connectors. All in all it took about one and a half hour to
scavenge the parts and construct.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;jimmy-rig-fm&#x2F;200910231254_119.jpg&quot; alt=&quot;Close up of the finished antenna&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;measurements&quot;&gt;Measurements&lt;&#x2F;h2&gt;
&lt;p&gt;Since we are all three properly educated in physics andor technology we
have a tendency to measure everything we can, this antenna is no
exception. Unfortunately, we do not have an antenna analyser, or even a
scope that goes to up to FM radio frequencies. Therefore we choose this
poor-mans method:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Connect the antenna&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Set a frequency&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Start transmitting at 2.2 V (maximum)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Find the transmission on my friends mobile phone&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Walk down the street until reception is failing&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Measure the distance as the crow flies using Google earth.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;em&gt;Resuls&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Antenna             Frequency  Range&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Piece of wire       94.5 Mhz   104 m
Dipole antenna      94.5 Mhz   304 m
Dipole antenna      88.5 Mhz   723 m&lt;&#x2F;p&gt;
&lt;p&gt;The pore range on the second attempt at 94.5 Mhz was mainly due to a
much stronger dutch pirate radio which also transmitted on that
frequency and overtook the reception. This did not happen on the
bare-wire trial. We then tried again with 88.5 Mhz because it was in a
large empty area.&lt;&#x2F;p&gt;
&lt;p&gt;The dipole has whopping increase of &lt;span class=&quot;math math-inline&quot;&gt;10 \log \frac{723^2}{104^2} = 17
\mathrm{[dB]}&lt;&#x2F;span&gt; over the bare wire! However, some of that can be
attributed to the dipole sticking out a window, while the bare wire was
inside the house and maybe the pirate interfered with the first
measurement as well.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pictures-of-the-antenna&quot;&gt;Pictures of the antenna&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;TODO&lt;&#x2F;strong&gt;: Pictures&lt;&#x2F;p&gt;
&lt;p&gt;Salvaging a ferrite core, Salvaging a ferrite core form a broken
computer power supply.&lt;&#x2F;p&gt;
&lt;p&gt;Diagram of the balun, Diagram of the balun.&lt;&#x2F;p&gt;
&lt;p&gt;Close up of the finished antenna, Close up of the finished antenna&lt;&#x2F;p&gt;
&lt;p&gt;The finished antenna, The finished antenna&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Brent Pollard ρ factorisation</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/brent-pollard-r-factorisation/"/>
        <id>https://2π.com/11/brent-pollard-r-factorisation/</id>
        
        <content type="html" xml:base="https://2π.com/11/brent-pollard-r-factorisation/">&lt;h1 id=&quot;brent-pollard-r-factorisation&quot;&gt;Brent Pollard ρ factorisation&lt;&#x2F;h1&gt;
&lt;p&gt;In the previous post the Pollard ρ method was by far the fastest of the
methods tested to factor an 64 bit integer. In this post I implement an
improved version by John Pollard and Richard Brent. It is described in
this paper:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wwwmaths.anu.edu.au&#x2F;~brent&#x2F;pd&#x2F;rpb051i.pdf&quot;&gt;Richard P. Brent (1980) – An Improved Monte Carlo Factorization
Algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The straightforward implementation in C++ is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; brent_pollard_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint64 m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;                &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	do&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	q &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64 i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; y = y² + a mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max_uint64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		uint64 k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64 i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;				&#x2F;&#x2F; y = y² + a mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;				if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max_uint64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;				&#x2F;&#x2F; q = q |x-y| mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				q &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; ys = ys² + a mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max_uint64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The parameter &lt;code&gt;m&lt;&#x2F;code&gt; has been fixed to &lt;code&gt;1000&lt;&#x2F;code&gt;, this seemed to be the
fastest choice.&lt;&#x2F;p&gt;
&lt;p&gt;Given a composite number &lt;code&gt;n&lt;&#x2F;code&gt; it will return a non-trivial factor of &lt;code&gt;n&lt;&#x2F;code&gt;.
To turn this method into a prime factorisation method this factor must
be further split up in factors until the numbers are prime. I develop
the function listed below to do this.&lt;&#x2F;p&gt;
&lt;p&gt;It maintains a stack of possibly composite factors and a list of prime
already discovered. It pops a possible composite from the stack, checks
its primality (with &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;?p=548&quot;&gt;this method&lt;&#x2F;a&gt;).
If the number is prime, it is removed from all the other factors on the
stack and put on the prime list, else, the number is split using either
trial division, if it is small, or &lt;code&gt;brent_pollard_factor&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 factor &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; brent_pollard_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		uint64 m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pop_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;is_prime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Remove the prime from the other factors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				uint64 k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;				if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;				{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;					do&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;					factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;				}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			factor &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; small_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; brent_pollard_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;benchmark-and-conclusion&quot;&gt;Benchmark and conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Compared to the methods posted previously, this method can perform the
task in 0.3 s. A tenfold improvement over the previous best and three
thousand times faster than trial division. Also, the time spent in &lt;code&gt;gcd&lt;&#x2F;code&gt;
is less than 20%, much less than the previous 90%.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Compose Key</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/compose-key/"/>
        <id>https://2π.com/11/compose-key/</id>
        
        <content type="html" xml:base="https://2π.com/11/compose-key/">&lt;h1 id=&quot;the-compose-key&quot;&gt;The Compose Key&lt;&#x2F;h1&gt;
&lt;p&gt;Unless you are shouting on online fora, the tab key is pretty much useless. I&#x27;ve remapped it to a compose key. With XCompose you can enter all sorts of unicode characters using the compose key followed by key sequences. But, the format to configure this is a bit verbose:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;A&amp;gt; &amp;lt;A&amp;gt; : &amp;quot;∀&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;C&amp;gt; &amp;lt;c&amp;gt; : &amp;quot;∁&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;p&amp;gt; &amp;lt;d&amp;gt; : &amp;quot;∂&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;E&amp;gt; &amp;lt;E&amp;gt; : &amp;quot;∃&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;slash&amp;gt; &amp;lt;E&amp;gt; &amp;lt;E&amp;gt; : &amp;quot;∄&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;q&amp;gt; &amp;lt;e&amp;gt; &amp;lt;d&amp;gt; : &amp;quot;∎&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;slash&amp;gt; &amp;lt;o&amp;gt; : &amp;quot;∅&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;plus&amp;gt; &amp;lt;minus&amp;gt; : &amp;quot;±&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;minus&amp;gt; &amp;lt;plus&amp;gt; : &amp;quot;∓&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;v&amp;gt; &amp;lt;slash&amp;gt; : &amp;quot;√&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;slash&amp;gt; &amp;lt;asciitilde&amp;gt; &amp;lt;minus&amp;gt; : &amp;quot;≄&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;asciitilde&amp;gt; &amp;lt;equal&amp;gt; : &amp;quot;≅&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;slash&amp;gt; &amp;lt;asciitilde&amp;gt; &amp;lt;equal&amp;gt; : &amp;quot;≇&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Multi_key&amp;gt; &amp;lt;asciitilde&amp;gt; &amp;lt;asciitilde&amp;gt; &amp;lt;space&amp;gt; : &amp;quot;≈&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To fix this I developed my own specification format that compiles to the above format. It looks like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∀     AA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∁     Cc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∂     pd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∃     EE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∄     &#x2F;EE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎     qed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∅     &#x2F;o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;±   +-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∓     -+&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;√     v&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;≄     &#x2F;~-&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;≅     ~=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;≇     &#x2F;~=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;≈     ~~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#!&#x2F;usr&#x2F;bin&#x2F;python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;# coding=utf-8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;XComposeNames&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;~&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;asciitilde&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;  &amp;quot;=&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;equal&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;       &amp;quot;-&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;minus&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;_&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;underscore&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;  &amp;quot;+&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;plus&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;        &amp;quot;&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;greater&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;&amp;lt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;less&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;        &amp;quot;|&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;bar&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;         &amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;slash&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-character z-escape&quot;&gt;\&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-punctuation z-definition z-string&quot;&gt;: &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;backslash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;,  &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;period&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;,      &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;: &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;exclam&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;:&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;colon&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;       &amp;quot;^&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;asciicircum&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;?&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;question&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;(&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;parenleft&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;   &amp;quot;)&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;parenright&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;  &amp;quot;[&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;bracketleft&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;]&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;bracketright&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;`&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;grave&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;       &amp;quot;&amp;#39;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;apostrophe&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;	&amp;quot;&amp;quot;&amp;quot;: &amp;quot;quotedbl&amp;quot;,   &amp;quot; &amp;quot;: &amp;quot;space&amp;quot;,       &amp;quot;,&amp;quot;: &amp;quot;comma&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&amp;quot;@&amp;quot;: &amp;quot;at&amp;quot;,          &amp;quot;#&amp;quot;: &amp;quot;numbersign&amp;quot;,  &amp;quot;$&amp;quot;: &amp;quot;dollar&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	&amp;quot;%&amp;quot;: &amp;quot;percent&amp;quot;,     &amp;quot;*&amp;quot;: &amp;quot;asterisk&amp;quot;,   u&amp;quot;←&amp;quot;: &amp;quot;Left&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	u&amp;quot;↑&amp;quot;: &amp;quot;Up&amp;quot;,        u&amp;quot;→&amp;quot;: &amp;quot;Right&amp;quot;,      u&amp;quot;↓&amp;quot;: &amp;quot;Down&amp;quot;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;def XComposeSequence(s, target):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	seq = &amp;quot;&amp;lt;Multi_key&amp;gt; &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	for c in s:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;		if c in XComposeNames:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;			seq += &amp;quot;&amp;lt;&amp;quot; + XComposeNames[c] + &amp;quot;&amp;gt; &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;		else:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;			seq += &amp;quot;&amp;lt;&amp;quot; + c + &amp;quot;&amp;gt; &amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string z-punctuation z-definition z-string&quot;&gt;	seq += &amp;quot;: &amp;quot;&amp;quot; + target + &amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; seq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;sequences = &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;while&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt; True&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	try&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; line = &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;raw_input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;().&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;decode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;utf-8&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	except&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt; EOFError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;#&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;		print&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;utf-8&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;		continue&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sequence = line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;split&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;t&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sequences&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;iterkeys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;startswith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;sequence&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt; or&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sequence&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;startswith&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				sys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;stderr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;WARNING: sequence &amp;quot;&amp;quot; + sequence +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;					&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; clashes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; with&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;					&amp;quot;previous sequence &amp;quot;&amp;quot; + s + &amp;quot;&amp;quot; for &amp;quot;&amp;quot; +&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;					sequences&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;).encode(&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;utf&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-meta z-indexed-name z-python&quot;&gt;	sequences&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;sequence&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; = target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;	print&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; XComposeSequence&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;sequence&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;utf-8&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .&#x2F;XCompile&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; UnicodeMath&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ~&#x2F;.XCompose&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; setxkbmap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;xmodmap -pke&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Full source is available on https:&#x2F;&#x2F;github.com&#x2F;Recmo&#x2F;XCompile.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Debuggin MinGW32 crashes under Windows XP</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/debugging-mingw32-crashes-under-windows-xp/"/>
        <id>https://2π.com/11/debugging-mingw32-crashes-under-windows-xp/</id>
        
        <content type="html" xml:base="https://2π.com/11/debugging-mingw32-crashes-under-windows-xp/">&lt;h1 id=&quot;debuggin-mingw32-crashes-under-windows-xp&quot;&gt;Debuggin MinGW32 crashes under Windows XP&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;em&gt;Summary&lt;&#x2F;em&gt;: You must pass the compiler flag &lt;code&gt;-mincoming-stack-boundary=2&lt;&#x2F;code&gt;
to gcc under mingw32.&lt;&#x2F;p&gt;
&lt;p&gt;I spent most of last week debugging a rather difficult problem under
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;uncyclopedia.wikia.com&#x2F;wiki&#x2F;Windows&quot;&gt;Windows XP&lt;&#x2F;a&gt;. A
multithreaded program would work properly under Windows 7, but would
randomly crash under Windows XP.&lt;&#x2F;p&gt;
&lt;p&gt;My first thought went to a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Race_condition&quot;&gt;race
condition&lt;&#x2F;a&gt;. A difference in
scheduling between XP and 7 might explain why it hapes in the former and
not in the later.&lt;&#x2F;p&gt;
&lt;p&gt;So I put in more and more locks, but that did not help. I then tries
hellgrind, but it flooded me with false positives from OpenSSL (well, I
&lt;em&gt;hope&lt;&#x2F;em&gt; they are false).&lt;&#x2F;p&gt;
&lt;p&gt;I then spent a lot of time using gdb to step trough the program. This
was very difficult since Windows has some sort of own debugger. This
debugger takes over control as soon as the crash occurs, hiding it from
gdb and in turn crashes itself in an unrelated place. After many hours I
still couldn’t find the location of the crash.&lt;&#x2F;p&gt;
&lt;p&gt;After much googling and trying I finally found &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;eigen.tuxfamily.org&#x2F;dox&#x2F;TopicWrongStackAlignment.html&quot;&gt;this
page&lt;&#x2F;a&gt;. The
problem is that 32bit windows has 4 byte stack allignment and GCC
assumes 16 byte, which is required for SSE instructions. GCC corrects
for this by aligning the stack before calling &lt;code&gt;main&lt;&#x2F;code&gt;. However, if a
windows library uses a callback or creates a new thread than the stack
allignment might be lost. And this will make any SSE instruction after
it crash. In my case I think the SSE instructions came from Qt’s unicode
converters.&lt;&#x2F;p&gt;
&lt;p&gt;The solution is simple: teach GCC not to assume only 4 byte stack
allignment with &lt;code&gt;-mincoming-stack-boundary=2&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Formal Languages</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/generic-syntax/"/>
        <id>https://2π.com/11/generic-syntax/</id>
        
        <content type="html" xml:base="https://2π.com/11/generic-syntax/">&lt;h1 id=&quot;formal-languages&quot;&gt;Formal Languages&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;classical-languages&quot;&gt;Classical languages&lt;&#x2F;h2&gt;
&lt;p&gt;Classically formal languages are serial. Using brackets the language can
express hiearchical structures. Using bound variables the languages can
contain arbitrary expressions?&lt;&#x2F;p&gt;
&lt;p&gt;Problem areas: complex structures, reflection, self-reference.&lt;&#x2F;p&gt;
&lt;p&gt;Lambda calculus: one can dispense entirely with multiple inputs and
multiple outputs by currying the inputs. However, I think this is
unnatural.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;proposed-alternative&quot;&gt;Proposed alternative&lt;&#x2F;h2&gt;
&lt;p&gt;Concepts, applications and definitions.&lt;&#x2F;p&gt;
&lt;p&gt;The fundamental entity of the language is understood as an application
(as in &quot;a concept that is applied&quot; not as in a piece of software). An
application has a number of arguments and results. Sentences can be
constructed by composing applications, one connects all the inputs of
the algorithms to the outputs of others.&lt;&#x2F;p&gt;
&lt;p&gt;Well-formed sentences have exactly one output assigned to every input
and contain no cycles.&lt;&#x2F;p&gt;
&lt;p&gt;Now that the concept of application is understood, there is a second
concept required, that of definition.&lt;&#x2F;p&gt;
&lt;p&gt;A concept&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Integer factorization in 64 bit</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/integer-factorization-in-64-bit/"/>
        <id>https://2π.com/11/integer-factorization-in-64-bit/</id>
        
        <content type="html" xml:base="https://2π.com/11/integer-factorization-in-64-bit/">&lt;h1 id=&quot;integer-factorization-in-64-bit&quot;&gt;Integer factorization in 64 bit&lt;&#x2F;h1&gt;
&lt;p&gt;For a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Residue_number_system&quot;&gt;residue number
system&lt;&#x2F;a&gt; I am trying
to implement I need to factor 64 bit integers n. They have the special
for that n+1 is a prime number, so they are all divisible by two and
they tend to have other small factors. Here are a few representative
examples:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
18446744073709551556 &amp;amp;= 2^2 \cdot 11 \cdot 137 \cdot 547 \cdot
5594472617641 \\ 18446744073709551532 &amp;amp;= 2^2 \cdot 43 \cdot 67
\cdot 193 \cdot 809383 \cdot 10247197 \\ 18446744073709551520 &amp;amp;=
2^5 \cdot 5 \cdot 2663 \cdot 43294085790719 \\
18446744073709551436 &amp;amp;= 2^2 \cdot 41 \cdot 101 \cdot 4051 \cdot
6199 \cdot 44347651 \\ 18446744073709551426 &amp;amp;= 2 \cdot 3 \cdot 23
\cdot 133672058505141677
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;trial-division&quot;&gt;Trial division&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Trial_division&quot;&gt;Trial division&lt;&#x2F;a&gt; is the
simplest method, simply start dividing out numbers from one to
&lt;span class=&quot;math math-inline&quot;&gt;\sqrt{n}&lt;&#x2F;span&gt;. Since you will factor out the primes before any of their
composites the resulting list only contains prime factors. I also tested
a version which used a list of small primes first, before trying all
numbers, but the extra memory bandwidth was worse than the speedup from
having to try less numbers. Here is the source:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Remove the twos&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Remove other factors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;wheel-factorisation&quot;&gt;Wheel factorisation&lt;&#x2F;h2&gt;
&lt;p&gt;In the previous example I took the two out as a special case and skipped
all the odd integers. A generalisation of this trick is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Wheel_factorization&quot;&gt;wheel
factorisation&lt;&#x2F;a&gt;, where
a few small primes are taken out and a skip list is produced of numbers
that must be multiples of those small primes. The end result is a list
of numbers that contains more primes (without missing any!) than plainly
listing all odd integers.&lt;&#x2F;p&gt;
&lt;p&gt;There is a trade off between memory usage by the skip list and small
primes list and the percentage of composites that are skipped. As often
with these memory trade offs, its best to choose the size such that it
fits snugly in the cpu cache. Now that I think about it, I could
probably take 32 bit numbers for the primes and skip list, and fit twice
the amount in the cpu cache.&lt;&#x2F;p&gt;
&lt;p&gt;The small primes are produced using the Sieve of Erastosthenes I
implemented &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;?p=492&quot;&gt;earlier&lt;&#x2F;a&gt;. This
implementation creates the largest possible wheel for a given number of
small primes, which can then be used to factor integers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; prime_wheel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	prime_wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint64s small_primes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_sieve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; prime_wheel wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;prime_wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;prime_wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 max_size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	max_size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 211&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; max_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 previous &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; include &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				include &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; previous&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		previous &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; previous &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_factors_wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Remove the twos&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Remove prime wheel factors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Turn the prime wheel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;				do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;					n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;				while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; What&amp;#39;s left must be prime or one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;brent-pollard-rho-factorisation&quot;&gt;Brent-Pollard rho factorisation&lt;&#x2F;h2&gt;
&lt;p&gt;This is John Pollard’s rho factorisation method (see
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pollard_rho&quot;&gt;wikipedia&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;planetmath.org&#x2F;encyclopedia&#x2F;PollardsRhoAlgorithm.html&quot;&gt;planet
math&lt;&#x2F;a&gt;. It
operates by iterating a random function f modulo n. This iteration must
become cyclic sometime since there are only a finite amount numbers
modulo n. The congruence relations resulting from this cycle give us
clues about factors of n.&lt;&#x2F;p&gt;
&lt;p&gt;Richard Brent has made quite a few improvements to this algorithm. The
original algorithm compares &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;x_{2i}&lt;&#x2F;span&gt; to detect a cycle, but I
implemented Brent’s improvement, which compares &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;x_j&lt;&#x2F;span&gt;, where &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt;
is the first power of two below &lt;span class=&quot;math math-inline&quot;&gt;i&lt;&#x2F;span&gt;. Brent also suggested that one can
multiply a few differences &lt;span class=&quot;math math-inline&quot;&gt;\left\vert x_i - x_j \right\vert&lt;&#x2F;span&gt; modulo
&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and compute the gcd of the product and &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; once in a while. I did not
implement this last suggestion, but I did measure that &amp;gt;90% of the time
is spent computing gcd’s, so this would be an important improvement. I
also did not implement &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;?p=566&quot;&gt;Montogomery reduced
multiplication&lt;&#x2F;a&gt;, which may speed up
the multiplication.&lt;&#x2F;p&gt;
&lt;p&gt;This algorithm will run indefinitely for prime numbers, so these are
checked for on start. There are also some special cases where the cycle
may be very long or where it will not result in a proper factor, so
after a while the algorithm terminates and tries again with a different
random function. I have not thought hard about the best time to
terminate and try again, so this might be sub-optimal.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Source: http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Binary_GCD_algorithm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Remove common twos in u and v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shift &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Remove twos from u&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	do&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Remove twos in v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Now u and v are both odd, so diff(u, v) is even.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Let u = min(u, v), v = diff(u, v)&#x2F;2.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			uint64 diff &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; diff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; brents_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;is_prime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; x = x² + a mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max_uint64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		uint64 g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;			brents_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;				brents_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Found no factors, yet n is not a prime, retry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	brents_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;benchmark-and-conclusion&quot;&gt;Benchmark and conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;The algorithms are compared by factoring p-1 for the thousand largest 64
bit primes:&lt;&#x2F;p&gt;
&lt;p&gt;Algorithm             Running time&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Trial division               959 s
Wheel factorisation          544 s
Brent-Pollard                  3 s&lt;&#x2F;p&gt;
&lt;p&gt;Clearly the Brent-Pollard method is the way to go, I should implement
the optimisations I suggested and think more thoroughly about the loop
termination.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Miller-Rabin primality test</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/miller-rabin-primality-test/"/>
        <id>https://2π.com/11/miller-rabin-primality-test/</id>
        
        <content type="html" xml:base="https://2π.com/11/miller-rabin-primality-test/">&lt;h1 id=&quot;miller-rabin-primality-test&quot;&gt;Miller-Rabin primality test&lt;&#x2F;h1&gt;
&lt;p&gt;As an exercise I implemented the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Miller%E2%80%93Rabin_primality_test&quot;&gt;Miller-Rabin&lt;&#x2F;a&gt;
primality test in plain C++. It turns out this algorithms lends itself
for a true festival of operators, so I couldn’t resist making the code
very dense:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Factor n-1 as d 2^s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; x = k^d mod n using exponentiation by squaring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; The squaring overflows for n &amp;gt;= 2^32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Verify k^(d 2^[0…s-1]) mod n != 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-- &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That’s it! Now, the algorithm will overflow for &lt;span class=&quot;math math-inline&quot;&gt;n \geq 2^{32}&lt;&#x2F;span&gt; but I
intend to use it to find 64-bit primes, so I’ll have to work on that.&lt;&#x2F;p&gt;
&lt;p&gt;Interestingly, the &quot;primes page&quot; claims that
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;primes.utm.edu&#x2F;prove&#x2F;prove2_3.html&quot;&gt;source&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;If n &amp;lt; 4,759,123,141 is a 2, 7 and 61-SPRP, then n is prime.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;(A number n is called “&lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-SPRP” or “strong probable-prime base &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;” if it
passes Miller Rabin with this k)&lt;&#x2F;p&gt;
&lt;p&gt;Since 4 759 123 141 is greater that &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt; we can use this to implement
a fast and &lt;em&gt;exact&lt;&#x2F;em&gt; function to determine whether some 32 bit number is
prime. I special cased the first several primes to improve performance
and made the whole thing into an incomprehensible operator soup, just
like the Miller-Rabin implementation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; isPrime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;73&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;13&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;17&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;19&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;23&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;29&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;31&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;37&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;41&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;43&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;47&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;53&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;59&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;61&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;67&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;71&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;73&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt;false&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;64-bits&quot;&gt;64-bits&lt;&#x2F;h1&gt;
&lt;p&gt;In the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;?p=530&quot;&gt;previous post&lt;&#x2F;a&gt; I showed an
implementation of Miller-Rabin that overflowed when the number was more
that 32 bits. In this post I present a way to fix this.&lt;&#x2F;p&gt;
&lt;p&gt;I could remember an instruction I used before, &lt;code&gt;mulq&lt;&#x2F;code&gt; which does 128 bit
multiplication. It multiplies two 64 bit number and stores the least
significant 64 bits in &lt;code&gt;rax&lt;&#x2F;code&gt; and the significant half in &lt;code&gt;rdx&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now we still need to reduce this number modulo m. Originally I planned
to create a table of &lt;span class=&quot;math math-inline&quot;&gt;2^n \mod m&lt;&#x2F;span&gt;, use the bits of &lt;code&gt;rdx&lt;&#x2F;code&gt; to add them and
then add &lt;code&gt;rax % m&lt;&#x2F;code&gt;. But after consulting this &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~fp&#x2F;courses&#x2F;15213-s06&#x2F;misc&#x2F;asm64-handout.pdf&quot;&gt;x86-64
manual&lt;&#x2F;a&gt;
I found out about &lt;code&gt;divq&lt;&#x2F;code&gt;, which takes a 128 bit number stored in
&lt;code&gt;rdx:rax&lt;&#x2F;code&gt;, a 64 bit number &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and produces the quotient and remainder.
The whole thing can be coded as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Modular multiplication&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The first factor, a &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The second factor, b &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The reduced product, a b mod m &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Perform 128 multiplication and division&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		uint64 q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; q = ⌊a b &#x2F; m⌋&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		uint64 r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; r = a b mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;mulq %3;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;		    &amp;quot;divq %4;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		    :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;=a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;=d&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		    :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should work fast, but I still need to look into &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Montgomery_reduction&quot;&gt;Montgomery
reduction&lt;&#x2F;a&gt;. Perhaps I
should benchmark the two.&lt;&#x2F;p&gt;
&lt;p&gt;Modular exponentiation can now be implemented using &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exponentiation_by_squaring&quot;&gt;exponentiation by
squaring&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Modular exponentiation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The base, b &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The exponent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The reduced power of a, a^b mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the Miller-Rabin test becomes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Miller-Rabin probabilistic primality testing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number to test for  primality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The witness for primality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True iff when n is a k-stong pseudoprime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Factor n-1 as d*2^s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Verify x = k^(d 2^i) mod n != 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-- &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; x = x^2 mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Together with the prime sieve I created
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;?p=492&quot;&gt;earlier&lt;&#x2F;a&gt; a fast probablilistic prime
checking procedure can be developed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_sieve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Miller-Rabin probabilistic primality testing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number to test for  primality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; False when n is not a prime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; is_prime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Handle small primes fast&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		uint64 p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Do a few Miller-Rabin rounds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This algorithm correctly identifies the first ten primes less than
&lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt;. But then again, so does a single Miller-Rabin round with &lt;span class=&quot;math math-inline&quot;&gt;K= 17&lt;&#x2F;span&gt;.
Perhaps I should implement the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Baillie%E2%80%93PSW_primality_test&quot;&gt;Baillie-PSW&lt;&#x2F;a&gt;
algorithm, there are &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.trnicely.net&#x2F;misc&#x2F;bpsw.html&quot;&gt;rumours&lt;&#x2F;a&gt;
that it has no false positives for 64 bits!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Montgomery multiplication</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/montgomery-multiplication/"/>
        <id>https://2π.com/11/montgomery-multiplication/</id>
        
        <content type="html" xml:base="https://2π.com/11/montgomery-multiplication/">&lt;h1 id=&quot;montgomery-multiplication&quot;&gt;Montgomery multiplication&lt;&#x2F;h1&gt;
&lt;p&gt;I looked at the wonderful concept of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Montgomery_reduction&quot;&gt;Montgomery
reduction&lt;&#x2F;a&gt;. At the
start I didn’t think such a complicated algorithm could be faster than a
single &lt;code&gt;divq&lt;&#x2F;code&gt; instruction. But it was! By more than six times!&lt;&#x2F;p&gt;
&lt;p&gt;To compare the algorithms I contrived a small program
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;wp-content&#x2F;uploads&#x2F;2009&#x2F;11&#x2F;mul_monty.cpp&quot;&gt;mul_monty.cpp&lt;&#x2F;a&gt;)
to calculate a lot of modular exponents, which in turn use even more
multiplications. This was then run with no calculation, calculation
using &lt;code&gt;divq&lt;&#x2F;code&gt; and calculation with Montgomery multiplication. All three
loops compute the Montogomery conversion too take that out of the
comparison.&lt;&#x2F;p&gt;
&lt;p&gt;Method          Time&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Empty loop    0.37 s
&lt;code&gt;divq&lt;&#x2F;code&gt;       38.02 s
Montgomery    6.19 s&lt;&#x2F;p&gt;
&lt;p&gt;So Montgomery multiplication is about six times faster. Lesson learned:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;One instruction can be slower than many lines of code.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here is how to convert to Monty form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x&amp;#39; = x\; 2^{64} \mod m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Converts from modular to Montgomery reduced form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number in a mod m form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to R = 2⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; a 2⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mod_to_monty&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;mul_asm&lt;&#x2F;code&gt; function is the original &lt;code&gt;divq&lt;&#x2F;code&gt; based multiplication. It
might seem silly to depend on the original method to improve it, but
remember that this conversion only happens sporadically in comparison to
multiplication.&lt;&#x2F;p&gt;
&lt;p&gt;And here is how to convert back to modular form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = x&amp;#39;\, 2^{-64} \mod m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Converts from Montgomery reduced form to modular&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number in x = aR mod m  form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to r = 2⁻⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus, must be m &amp;gt; 2⁶³&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; a 2⁻⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; monty_to_mod&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, what you have been waiting for: the multiplication! The task is to
calculate &lt;span class=&quot;math math-inline&quot;&gt;p = a b \mod m&lt;&#x2F;span&gt; or rather, its Monty form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p&amp;#39; = a b 2^{64} \mod m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The parameters given are:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a&amp;#39; &amp;amp;= a\, 2^{64} \mod m \\ b&amp;#39; &amp;amp;= b\, 2^{64} \mod m
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first step is to calculate (with 128 bits)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
t = a&amp;#39; b&amp;#39; = a b\, 2^{128} \mod m^2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now, if this number is divisible by &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt; the we can simply bit shift
&lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; and return this result as &lt;span class=&quot;math math-inline&quot;&gt;p&amp;#39;&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If g is not a divisible by &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt; we can make it divisible by adding a
(128 bit) number &lt;span class=&quot;math math-inline&quot;&gt;v&lt;&#x2F;span&gt; to it. The great Montgomery trick is to choose this
number such that &lt;span class=&quot;math math-inline&quot;&gt;v \mod m = 0&lt;&#x2F;span&gt;. It turns out that with:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
k &amp;amp;= \left(-m\right)^{-1} \mod 2^{64} \\ u &amp;amp;= t k \mod
2^{64} \\ v &amp;amp;= u m 
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We obtain the number &lt;span class=&quot;math math-inline&quot;&gt;v&lt;&#x2F;span&gt; we want!&lt;&#x2F;p&gt;
&lt;p&gt;Now all that remains is to compute t + v and bit shift this result. And
since we know the least significant bits will be zero with a carry this
can be done using 64 bit arithmetic.&lt;&#x2F;p&gt;
&lt;p&gt;All in all the algorithm can be implemented as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Multiplication with Montgomery reduction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The first factor in Monty form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The second factor in Monty form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to R = 2⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to r = 2⁻⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to k = (-m)⁻¹ mod 2⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The product in Monty form: a b 2⁻⁶⁴ mod 2⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_monty&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; th 2⁶⁴ + tl = a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 th&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;mulq %3&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;=a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;tl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;=d&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;th&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; If t is a multiple of 2⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; then return the quotient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;tl &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; th&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; u = t n  mod  2⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tl &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; vh 2⁶⁴ + vl = u m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 vh&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; vl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;mulq %3;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;=a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;=d&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vh&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; a = vh + th + 1 (take care of overflow)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; vh &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; th &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; th&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Variable Sized Integers</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/variable-sized-integers/"/>
        <id>https://2π.com/11/variable-sized-integers/</id>
        
        <content type="html" xml:base="https://2π.com/11/variable-sized-integers/">&lt;h1 id=&quot;variable-sized-integers&quot;&gt;Variable Sized Integers&lt;&#x2F;h1&gt;
&lt;p&gt;In this article I’ll show different methods to compactly
encode integers which are likely to be small. In the process I’ll show
some neat bit-fiddeling techniques and I’ll try to develop a coding that
is both faster and denser.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;existing-work&quot;&gt;Existing work&lt;&#x2F;h2&gt;
&lt;p&gt;Variable sized integer codings are used in several existing projects,
usually when very efficient use of storage space is required and large
values can occur but small values are much more frequent. Typical cases
would be content sizes, or anything that follows a
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Power_law&quot;&gt;power-law&lt;&#x2F;a&gt; distribution, which
according to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Zipf%E2%80%99s_law&quot;&gt;Zipf’s law&lt;&#x2F;a&gt;
happens very often. I’ll start by showing three well-known variable
integer coders.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ebml-matroska&quot;&gt;EBML (Matroska)&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.matroska.org&#x2F;technical&#x2F;specs&#x2F;index.html&quot;&gt;Matroska file
format&lt;&#x2F;a&gt;, with file
extenstion &lt;code&gt;.mkv&lt;&#x2F;code&gt;, is a popular choice for high definition video
content. Matroska is a modern and flexible container format based on the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;ebml.sourceforge.net&#x2F;specs&#x2F;&quot;&gt;&lt;code&gt;EBML&lt;&#x2F;code&gt; specification&lt;&#x2F;a&gt;. An &lt;code&gt;EBML&lt;&#x2F;code&gt;
formatted file consists of a stream of key, size, value triples known as
‘tags’. Here the key is an one to four byte identifier and the size is
the varint encoded length of the value. These tags can be nested, making
the format heirarchical and easily extended.&lt;&#x2F;p&gt;
&lt;p&gt;The varint is between 1 and 9 bytes, the most significant bits of the
first byte determine the total number of bytes used in the encoding.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;EBML varint format&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;value  encoded as&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&amp;lt; 2⁷   &lt;code&gt;1xxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2¹⁴  &lt;code&gt;01xx xxxx xxxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2²¹  &lt;code&gt;001x xxxx xxxx xxxx xxxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2²⁸  &lt;code&gt;0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx₂&lt;&#x2F;code&gt;
⋮       ⋮
&amp;lt; 2⁶⁴  &lt;code&gt;0000 0001 xxxx xxxx&lt;&#x2F;code&gt; …(48 bits)… &lt;code&gt;xxxx xxxx₂&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;EBML&lt;&#x2F;code&gt; uses this format to encode tags and &lt;em&gt;field sizes&lt;&#x2F;em&gt;, not to
encode integer valued fields. For example, encoding an integer valued
field with value 123₁₆ would result in a size of two bytes, which is
varint encoded as 02₁₆ and then prefixed to the integer’s bytes giving
the output 020123₁₆. Since the size is 0–8 bytes, which is always
encoded as a single byte, the net effect is a one-byte prefix.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The varint coder is defined in
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;matroska.svn.sourceforge.net&#x2F;viewvc&#x2F;matroska&#x2F;trunk&#x2F;libebml&#x2F;src&#x2F;EbmlElement.cpp?revision=746&amp;amp;view=markup&quot;&gt;EbmlElement.cpp&lt;&#x2F;a&gt;,
but the original code is too complicated to show it here. It contains
special cases for the end of the read&#x2F;write buffer, some minor variants
for signed integers and special values, but is is also rather entangled
with other functions. I will therefore show a simplified version, with
my own variable names and comments to clarify. I did not try to optimize
the functions. Please rever to the original sourcecode at the links
above before making any judgements.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;EBML write function (simplified).&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Determine the number of bytes to write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 127&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; 2^7 - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	else if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 16383&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; 2^14 - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	else if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2097151&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; 2^21 - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	else if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 268435455&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;L&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; 2^28 - 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	else&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Write the bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mask &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;FF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	OutBuffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;FF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		mask &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;FF&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Higher cases where marked marked as &quot;TODO&quot; in original code&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;EBML read function (simplified).&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; read&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	char&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mask &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	char&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mask &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			mask &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; index &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;index&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;FF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp; ~&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mask&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;unsigned int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; PossibleSize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size_buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Handle overflow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;google-protocol-buffers&quot;&gt;Google Protocol Buffers&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;apis&#x2F;protocolbuffers&#x2F;&quot;&gt;Google Protocol Buffers&lt;&#x2F;a&gt;
is designed as a highly efficient alternative to xml for data exchange
between processes and data storage. It is apparently the default remote
procedure call protocol for Google’s internal software, so one can
assume that the code is very well designed and povides a significant
improvement over existing alternatives. A fundamental part of the
specification are &quot;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;apis&#x2F;protocolbuffers&#x2F;docs&#x2F;encoding.html#varints&quot;&gt;base 128
varints&lt;&#x2F;a&gt;&quot;.
These varints are the default encoding format for integer field types
and they are used to encode data lengths.&lt;&#x2F;p&gt;
&lt;p&gt;The varint format consist of groups of eight bits, bytes. The most
significant bit in each byte is a flag that is one when more groups are
comming and zero if this is was the last group. The other seven bits are
part of the encoded number, but counterintuitively the format starts
with the &lt;em&gt;least&lt;&#x2F;em&gt; significant group of seven bits first.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Google Protocol Buffers varint format&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;value  encoded as&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&amp;lt; 2⁷   &lt;code&gt;0xxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2¹⁴  &lt;code&gt;1xxx xxxx 0xxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2²¹  &lt;code&gt;1xxx xxxx 1xxx xxxx 0xxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2²⁸  &lt;code&gt;1xxx xxxx 1xxx xxxx 1xxx xxxx 0xxx xxxx₂&lt;&#x2F;code&gt;
⋮       ⋮
&amp;lt; 2⁶⁴  &lt;code&gt;1xxx xxxx 1xxx xxxx&lt;&#x2F;code&gt; …(48 bits)… &lt;code&gt;0xxx xxxx₂&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The code has some special cases at the end of the buffer and for 32-bit
and signed integer which I will not go into. When the pointer is not to
close to the end of the buffer then the encoding is done using
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;protobuf&#x2F;source&#x2F;browse&#x2F;trunk&#x2F;src&#x2F;google&#x2F;protobuf&#x2F;io&#x2F;coded_stream.cc?r=349#427&quot;&gt;CodedInputStream::ReadVarint64Fallback&lt;&#x2F;a&gt;
and the decoding is done using
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;protobuf&#x2F;source&#x2F;browse&#x2F;trunk&#x2F;src&#x2F;google&#x2F;protobuf&#x2F;io&#x2F;coded_stream.cc?r=349#681&quot;&gt;CodedOutputStream::WriteVarint64ToArrayInline&lt;&#x2F;a&gt;.
The functions are defined as follows:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Google Protocol Buffers writer.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-function z-definition z-cpp&quot;&gt; CodedOutputStream&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;WriteVarint64ToArrayInline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;	uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Splitting into 32-bit pieces gives better performance on 32-bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; processors.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint32 part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value      &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint32 part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint32 part2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint32&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Here we can&amp;#39;t really optimize for small numbers, since the value is&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; split into three parts.  Cheking for numbers &amp;lt; 128, for instance,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; would require three comparisons, since you&amp;#39;d have to make sure part1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; and part2 are zero.  However, if the caller is using 64-bit integers,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; it is likely that they expect the numbers to often be very large, so&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; we probably don&amp;#39;t want to optimize for small numbers anyway.  Thus,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; we end up with a hardcoded binary search tree...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;				size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	GOOGLE_LOG&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;FATAL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Can&amp;#39;t get here.&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part2      &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size6&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1      &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	size1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part0      &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	target&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; target &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Google Procol Buffers reader.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-function z-definition z-cpp&quot;&gt; CodedInputStream&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;ReadVarint64Fallback&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;BufferSize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; kMaxVarintBytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Optimization:  If the varint ends at exactly the end of the buffer,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; we can detect that and still use the fast path.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer_end_ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; buffer_ &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer_end_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Fast path:  We have enough bytes left in the buffer to guarantee that&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; this read won&amp;#39;t cross the end, so we can skip the checks.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;		const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ptr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; buffer_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		uint32 b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; Splitting into 32-bit pieces gives better performance on 32-bit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; processors.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		uint32 part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part0  &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)      ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part1  &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)      ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 21&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part2  &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)      ;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; part2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7F&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;  7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;80&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; We have overrun the maximum size of a varint (10 bytes).  The data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;		&#x2F;&#x2F; must be corrupt.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	done&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		Advance&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ptr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; buffer_&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 28&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;			(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;static_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;part2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ReadVarint64Slow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Looking at the comments, a lot of thought went into the performance.
Loops are unrolled and the code is filled with &lt;code&gt;goto&lt;&#x2F;code&gt;&#x27;s.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;unicode&quot;&gt;Unicode&lt;&#x2F;h3&gt;
&lt;p&gt;This list would not be complete without to of the most popular variable
sized integer coders, &lt;code&gt;UTF-8&lt;&#x2F;code&gt; and &lt;code&gt;UTF-16&lt;&#x2F;code&gt;. Yes, that’s right, these
unicode encodings can also be seen as varint coders. They encode the
valid unicode codepoints in the range 0–10FF₁₆ to sequences of bytes or
words.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;UTF-8 format&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;value  encoded as&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&amp;lt; 2⁷   &lt;code&gt;0xxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2¹¹  &lt;code&gt;110x xxxx 10xx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2¹⁶  &lt;code&gt;1110 xxxx 10xx xxxx 10xx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2²¹  &lt;code&gt;1111 0xxx 10xx xxxx 11xx xxxx 10xx xxxx₂&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This format is a lot less size efficient than the previous ones, but it
satisfies a few additional constraints due to ascii compatibility.
Values less than 127, the ascii values, are encoded as themselves and
non ascii values are encoded using only non-ascii bytes. Furthermore the
start of a sequence can always be identified by the bitstring
&lt;code&gt;11xx xxxx&lt;&#x2F;code&gt;, this allows a decoder to resynchronize on a corrupt
bitstream.&lt;&#x2F;p&gt;
&lt;p&gt;The UTF-16 format has a preprocessing step, if the value is higher than
10000₁₆ then 10000₁₆ is subtracted from the value befor encoding using
the pattern in the second row otherwise the value is written out
plainly:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;UTF-16 format&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;value  encoded as&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&amp;lt; 2¹⁶  &lt;code&gt;xxxx xxxx xxxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2²⁰  &lt;code&gt;1110 10xx xxxx xxxx 1110 11xx xxxx xxxx₂&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To let the decoder identify between the first and second row, the first
row must not start with &lt;code&gt;1110 10₂&lt;&#x2F;code&gt;! With a nice disregard for
sepparation of concerns the Unicode standard was modified to exclude the
whole range &lt;code&gt;1110 1xxx xxxx xxxx&lt;&#x2F;code&gt; solely for UTF-16. In fact, UTF-8
originally went up to 31 bits, but was limited to 21 bits to conform
with UTF-16.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;improving&quot;&gt;Improving&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Operations on 64-bit unsigned integers are allowed&lt;&#x2F;li&gt;
&lt;li&gt;The buffer is overallocated eight bytes&lt;&#x2F;li&gt;
&lt;li&gt;Very fast encoding&#x2F;decoding&lt;&#x2F;li&gt;
&lt;li&gt;Encode whole number of bytes&lt;&#x2F;li&gt;
&lt;li&gt;Encode minimal number of bytes&lt;&#x2F;li&gt;
&lt;li&gt;Bijective encoding (every value has a unique encoding)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;One can learn a few things from the the three formats above. The &lt;code&gt;EBML&lt;&#x2F;code&gt;
and &lt;code&gt;UTF-8&lt;&#x2F;code&gt; format have the advantage that the the total number of bytes
to read is known after the first byte is read, the Google format lacks
this advantage. However, Google’s format shares with &lt;code&gt;UTF-8&lt;&#x2F;code&gt; that values
less than 127 are encoded as themselfs, this is fundamental to the
ascii-compatibility of &lt;code&gt;UTF-8&lt;&#x2F;code&gt;. There are both pro’s and con’s to this
approach, the pro is that users with non-unicode tools might be able to
read the file, the con is that user might not feel inclined to update
their tools untill something breaks horribly.&lt;&#x2F;p&gt;
&lt;p&gt;I personally shun backwards compatibility, it often does more harm than
good. Besides, a non compatible solution saves me one instruction on my
processor. Therefore my format will be the same as &lt;code&gt;EBML&lt;&#x2F;code&gt;&#x27;s. (Should you
want the backwards compatibility, you can reverse the ones and zeros in
the prefix and modify the source accordingly).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;custom varint format&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;value  encoded as&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&amp;lt; 2⁷   &lt;code&gt;1xxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2¹⁴  &lt;code&gt;01xx xxxx xxxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2²¹  &lt;code&gt;001x xxxx xxxx xxxx xxxx xxxx₂&lt;&#x2F;code&gt;
&amp;lt; 2²⁸  &lt;code&gt;0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx₂&lt;&#x2F;code&gt;
⋮       ⋮
&amp;lt; 2⁶⁴  &lt;code&gt;0000 0001 xxxx xxxx&lt;&#x2F;code&gt; …(48 bits)… &lt;code&gt;xxxx xxxx₂&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;loop-free-almost-branch-free&quot;&gt;Loop free, almost branch free&lt;&#x2F;h3&gt;
&lt;p&gt;Now that the format is settled, how are we going to encode&#x2F;decode it
efficiently? The &lt;code&gt;EBML&lt;&#x2F;code&gt; implementation is filled with loops within
loops, that can never be efficient. The Google one solves this by
unrolling the loop and jumping into it using a decission tree. But both
solution still require conditional branching wich can cause &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Branch_predictor&quot;&gt;branch
misprediction&lt;&#x2F;a&gt; and the
associated performance penalty of ten to twenty cycles.&lt;&#x2F;p&gt;
&lt;p&gt;So I would like to avoid fors and&#x27; ifs where possible. And in fact this
can be done to a large degree! Using GCC’s builtin function
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;gcc.gnu.org&#x2F;onlinedocs&#x2F;gcc&#x2F;Other-Builtins.html&quot;&gt;&lt;code&gt;__builtin_clzll&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; we can
quickly count the number of zero bits left of the most significant one
bit. Another usefull function is &lt;code&gt;builtin_bswap64&lt;&#x2F;code&gt;, which
converts between little-endian and big-endian. I’ve wrapped the builtin
functions in &lt;code&gt;leading_zeros&lt;&#x2F;code&gt; and &lt;code&gt;byte_swap&lt;&#x2F;code&gt; so one can provide compiler
independent implementations for them. Additionally GCC’s
&lt;code&gt;__builtin_clzll&lt;&#x2F;code&gt; is undefined for the value zero, which I would like to
be set to 64. Testing shows that in practice it returns zero on zero
input, the following corrects that:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline int&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;){&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;__builtin_clzll&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;){&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; __builtin_bswap64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; expect_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; __builtin_expect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; expect_true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; __builtin_expect&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I have also defined two macro’s, &lt;code&gt;expect_false&lt;&#x2F;code&gt; and &lt;code&gt;expect_true&lt;&#x2F;code&gt; which
give the compiler a clue about wich branch is more likely, these are
purely optional. With these functions one can construct the following
variabel integer encoder for the format given above:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;expect_true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;ul&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		*reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;00&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	*reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Line 2 calculates the number of bytes required using that we encode the
value in groups of seven bits. The number of bits in to write down a
value &lt;span class=&quot;math math-inline&quot;&gt;x&lt;&#x2F;span&gt; in binary is &lt;span class=&quot;math math-inline&quot;&gt;⌊\log₂ x⌋&lt;&#x2F;span&gt;. Note that &lt;code&gt;leading_zeros&lt;&#x2F;code&gt; returns the
value &lt;span class=&quot;math math-inline&quot;&gt;64 - ⌊\log₂ x⌋&lt;&#x2F;span&gt;. Which gives the following derivation for the
number of seven bit blocks required:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
⌈ \frac{⌊\log₂ x⌋}7 ⌉ ≟ 9 - ⌊ \frac{64 - ⌊\log₂ x⌋}7 ⌋
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Lines 4–9 handle the case where the encoded value fits in a &lt;code&gt;uint64&lt;&#x2F;code&gt;.
Line 4 shifts the value to the most significant bytes. Line 5 adds the
one bit that marks the number of bytes. Line 6 converts the in memory
representation from little-endian to big-endian. Line 7 writes the eight
bytes of &lt;code&gt;value&lt;&#x2F;code&gt; in one go by reinterpreting the buffer as an &lt;code&gt;uint64&lt;&#x2F;code&gt;
array. This will always write eight bytes to the buffer, but we have the
assumption that this is can always be done. Line 8 increments the buffer
pointer by the correct amount.&lt;&#x2F;p&gt;
&lt;p&gt;Lines 11–15 handle the very large value case, which is unlikely to
happen. An all-zero prefix byte is written and the big endian value is
written in one go.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; read&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;expect_true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; offset &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;56&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;expect_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Overflow: value ≧ 2⁶⁴&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;removing-ambiguity&quot;&gt;Removing ambiguity&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; This constant will add the proper offsets for all the different&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; cases and move the leading one one position to the right&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint64 offset &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0102040810204080&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; write&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;~&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;expect_true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		*reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;00&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	*reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; read&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;expect_true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; offset &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;56&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 56&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; leading_zeros &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;expect_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; offset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Overflow: value ≧ 2⁶⁴&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Optimizing the Google format.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;~&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;8080808080808080&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;benchmarking&quot;&gt;Benchmarking&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;written-size&quot;&gt;Written size&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;writing-time&quot;&gt;Writing time&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;reading-time&quot;&gt;Reading time&lt;&#x2F;h3&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Byte-swap based hash function</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/12/byte-swap-based-hash-function/byte-swap-based-hash-function/"/>
        <id>https://2π.com/12/byte-swap-based-hash-function/byte-swap-based-hash-function/</id>
        
        <content type="html" xml:base="https://2π.com/12/byte-swap-based-hash-function/byte-swap-based-hash-function/">&lt;h1 id=&quot;byte-swap-based-hash-function&quot;&gt;Byte-swap based hash function&lt;&#x2F;h1&gt;
&lt;p&gt;This weekend I played with the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;smhasher&#x2F;&quot;&gt;SMHasher&lt;&#x2F;a&gt; benchmark suite for
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hash_function&quot;&gt;non-cryptographic hash functions&lt;&#x2F;a&gt;. And I couldn’t
resist designing my own hash function, with some unique properties.&lt;&#x2F;p&gt;
&lt;p&gt;The general design of MurMurHash and some other popular hash functions
is something along these lines:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;hash&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; seed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; seed&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;* more data *&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		quick_mix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	perfect_mix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This example is simplified in that it assumes the data is a multiple of
128 bits. It is easy to accommodate for different size by padding with
zeros.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;quick_mix&lt;&#x2F;code&gt; function mixes a 128 bit input into the 128 bit state.
It should mix enough of the input into the state to prevent simple
collisions. But, if the input data is large the &lt;code&gt;quick_mix&lt;&#x2F;code&gt; function
becomes the bottleneck. So we’d like to make it as simple as possible,
without getting collisions.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;perfect_mix&lt;&#x2F;code&gt; takes the output of the inner loop and does some final
processing so that the hash function satisfies some strong statistical
properties such as the strict avalanche criterion and the bit
independence criterion.&lt;&#x2F;p&gt;
&lt;p&gt;The hash state is initialized with a seed and the length of the data.
The seed value allows independent hash values to be created using the
same algorithm. This is necessary for Bloom filters or to protect hash
tables against certain &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;events.ccc.de&#x2F;congress&#x2F;2011&#x2F;Fahrplan&#x2F;events&#x2F;4680.en.html&quot;&gt;denial of service&lt;&#x2F;a&gt;
attacks. The some implementations of &lt;code&gt;quick_mix&lt;&#x2F;code&gt; have a weakness where
an input of all zero’s does not change the state, this would mean all
inputs consisting of only zeros would map to the same hash value,
despite the fact that they could have different lengths. To compensate
for this, the length is also used as a sort of seed.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s look at MurMurHash’s implementation of &lt;code&gt;quick_mix&lt;&#x2F;code&gt; (version 3,
x64, 128 bit hash):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;87c37b91114253d5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;ULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c2 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;4cf5ad432745937f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;ULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; quick_mix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; input0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; input1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	input0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	input0  &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ROTL64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;input0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;31&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	input0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	hash0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	hash0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ROTL64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;27&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	hash0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	hash0 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;52dce729&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	input1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	input1  &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ROTL64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;input1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;33&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	input1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	hash1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	hash1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ROTL64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;31&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	hash1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	hash1 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;38495ab5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It uses multiplication, rotation, and a linear congruential generator to
mix bits within an integer and it uses addition and xor to mix two
integers. Let’s look at the avalanche plot :&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;mmh3-0.png&quot; alt=&quot;MurMurHash one iteration&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(See Bret Mulvey’s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;home.comcast.net&#x2F;~bretm&#x2F;hash&#x2F;5.html&quot;&gt;page&lt;&#x2F;a&gt;
for what this means)&lt;&#x2F;p&gt;
&lt;p&gt;Now that is a nice texture!&lt;&#x2F;p&gt;
&lt;p&gt;The 128 columns represent the output state, the 128 rows represent the
input bits. If a pixels is black, it means that there is a small chance
(&amp;lt; 50%) that the corresponding bit of the output is changed by the
corresponding bit of the input. If the pixels is white, it means there
is a large chance (&amp;gt; 50%) that the bit is changed. Under the strict
avalanche criterion, the image would be solid gray, representing all
≈50% chances. Clearly we’re not there yet.&lt;&#x2F;p&gt;
&lt;p&gt;The 4x4 block structure is because of the almost 32 bit rotates. The
diagonal stripes are caused by the multiplication, which can only mix an
input bit into higher bits. One can also see that the first 32 bits of
input affect all the bits of the state, but the last bits of the input
only affect the lower 32 bits of &lt;code&gt;hash1&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s run the &lt;code&gt;quick_mix&lt;&#x2F;code&gt; function once more on the same state, with all
zero inputs. From the function one can see that zero inputs mean that
the first and third line do nothing. We are only looking at the state
mixing functions in the second and fourth line. The state after a second
iteration looks like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;mmh3-1.png&quot; alt=&quot;MurMurHash two iterations&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It looks much better, there is a large number of gray pixels and almost
all the bits are affected by the input bits in some way. Let’s do one
more iteration.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;mmh3-2.png&quot; alt=&quot;MurMurHash three iterations&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Even better! The state is almost entirely avalanches and even the most
difficult bit, bit 128, has some gray pixels in its row. One more:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;mmh3-3.png&quot; alt=&quot;MurMurHash four iterations&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Almost there. Just one more round…&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;mmh3-5.png&quot; alt=&quot;MurMurHash five iterations&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;…and we’re there! After five iterations all the bits have become
completely dependent on the input bit. The strict avalanche condition
appears to be satisfied.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;designing-a-byte-swap-based-mixing-function&quot;&gt;Designing a byte-swap based mixing function&lt;&#x2F;h2&gt;
&lt;p&gt;Multiplication by a large prime modulo 64 is a great way to design a
hash function. The operation is injective on the 64 bit numbers, meaning
it loses no information and can thus be inverted. It is also fast,
modern processors can do several such operations in a single clock
cycle. Finally, the inverse is non-trivial to compute, just what we want
for a hash function.&lt;&#x2F;p&gt;
&lt;p&gt;Multiplication would be perfect if it was not for two weaknesses. First,
it maps zeros to zeros. It is not hard to work around this, you can just
seed the hash with the length of the data or offset zeros with some
constant. The second weakness is more profound. Multiplication only
escalates bits to higher bits! It causes the avalanche diagrams to
become triangles instead of squares, just like what can be seen in the
first image.&lt;&#x2F;p&gt;
&lt;p&gt;The multiplication operation needs an operation to complement it,
something that will mix the higher bits into the lower bits. In all the
hash functions I know, this is done by bitshifting or rotating the
higher bits into lower positions. This process of multiplication and
rotation can then repeated until the result is sufficiently mixed.&lt;&#x2F;p&gt;
&lt;p&gt;The problem is how much do we rotate? If we rotate by 32 bits, the
highest bits get mixed into bit 32, which is still quite high. If we
rotate by 60 bits, the highest bits are nicely mixed into the lowest
bits, but only four of them get mixed.&lt;&#x2F;p&gt;
&lt;p&gt;What we would ideally like to do is mix the best-mixed bits into the
least mixed bits, that is mix bit 64 into bit 1, mix bit 63 into bit 2,
etcetera. This entails reversing the order of the bits. Despite some
cool algorithms in &quot;Hacker’s Delight&quot;, this is still a slow operation.&lt;&#x2F;p&gt;
&lt;p&gt;And then it struck me: there is a single instruction operation that does
almost the same as reversing all the bits: it reverses all the bytes!
It’s not very well known unless you’re writing low level code that mixes
little endian and big endian representations. But still, it is there. To
access it you can use the GCC builtin function &lt;code&gt;__builtin_bswap64&lt;&#x2F;code&gt;, or
this wrapper:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; __builtin_bswap64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now let’s build a hash function using byte swap! Start simple: multiply
and swap:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;const uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;436174bab1d5558d&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;ULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; quick_mix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	byte_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The constant &lt;code&gt;k64&lt;&#x2F;code&gt; is a large prime that was found by simulated
annealing. (I took this idea, and everything else, besides the byte-swap
from the author of SMHasher and MurMurHash.) You start with a random
value. Measure its quality. Flip some bits. Measure it again. Keep the
change if it’s an improvement. Repeat until satisfied.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pseudo-hadamard-transform&quot;&gt;Pseudo-Hadamard transform&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;code&gt;quick_mix&lt;&#x2F;code&gt; function is good for mixing a single integer, but we
need to mix several integers. Two input values and two state values.&lt;&#x2F;p&gt;
&lt;p&gt;A good way to mix integers two integers such is the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pseudo-Hadamard_transform&quot;&gt;Pseudo-Hadamard
transform&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The net result is that &lt;code&gt;a&#x27; = a + b&lt;&#x2F;code&gt; and &lt;code&gt;b&#x27; = a + 2b&lt;&#x2F;code&gt;, both &lt;code&gt;a&#x27;&lt;&#x2F;code&gt; and
&lt;code&gt;b&#x27;&lt;&#x2F;code&gt; depend on &lt;code&gt;a&lt;&#x2F;code&gt; and &lt;code&gt;b&lt;&#x2F;code&gt;. The operation effectively diffuses &lt;code&gt;a&lt;&#x2F;code&gt; and
&lt;code&gt;b&lt;&#x2F;code&gt; into each other. It is also invertible, so no information is lost be
using it.&lt;&#x2F;p&gt;
&lt;p&gt;It can be extended to more variables by recursions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a good function to mix four integers. It uses a total of eight
additions, two of which can be pipelined at a time.&lt;&#x2F;p&gt;
&lt;p&gt;For my hash function I can get away with a variation that is faster, but
less good. The idea is to use addition modulo 2 instead of modulo 2⁶⁴.
That is, to use xor instead of add:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; quick_hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you meditate on this for a moment you will see that it amounts to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; quick_hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So the output &lt;code&gt;a&#x27;&lt;&#x2F;code&gt; will depend on both &lt;code&gt;a&lt;&#x2F;code&gt; &lt;em&gt;and&lt;&#x2F;em&gt; &lt;code&gt;b&lt;&#x2F;code&gt;, but &lt;code&gt;b&#x27;&lt;&#x2F;code&gt; will only
depend on &lt;code&gt;a&lt;&#x2F;code&gt;. Still, it will turn out to be good enough. The reason it
is faster is that the &lt;code&gt;swap&lt;&#x2F;code&gt; operation can often be folded in other
operations.&lt;&#x2F;p&gt;
&lt;p&gt;The four integer Hadamard transform simplifies to:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; quick_hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;^=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The net effect is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a&amp;#39; = a ^ b ^ c ^ d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b&amp;#39; = a ^ c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c&amp;#39; = a ^ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;d&amp;#39; = a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;a-256-bit-to-128-bit-mixing-function&quot;&gt;A 256 bit to 128 bit mixing function&lt;&#x2F;h3&gt;
&lt;p&gt;From the &lt;code&gt;quick_mix&lt;&#x2F;code&gt; and &lt;code&gt;quick_hadamard&lt;&#x2F;code&gt; above I constructed the
following hash function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; quick_mix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; input0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; input1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	quick_hadamard&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	quick_mix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;hash0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	quick_mix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;hash1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;First a xor Psuedo-Hadamard tranform is used to mix the input into the
state, then the state is scrambled using &lt;code&gt;quick_mix&lt;&#x2F;code&gt; and an additional
multiply.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s look at the avalanche diagrams:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;msh-0.png&quot; alt=&quot;Mul Swap Hash&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After the initial mixing, the result is already very nice. There is no
mixing of &lt;code&gt;input1&lt;&#x2F;code&gt; into &lt;code&gt;hash1&lt;&#x2F;code&gt;, this is caused by the simplicity of my
Hadamard tranform. If you look closely you can see blocks eight by eight
pixels, this is due to the &lt;code&gt;byte_swap&lt;&#x2F;code&gt; working in blocks of eight bits.
You can even see small triangles caused by the multiply in the lower
left corner of the three large blocks. Every input bit affects at least
56 state bits.&lt;&#x2F;p&gt;
&lt;p&gt;If you look more closely you’ll see that the three mixed blocks have
identical patterns. This means there is a lot of correlation between the
bits. The MurMurHash function does not have this problem because it uses
slightly different functions on all the variables. This could be done
here by using different multiplication constants for &lt;code&gt;hash0&lt;&#x2F;code&gt; and
&lt;code&gt;hash1&lt;&#x2F;code&gt;. But for now, let’s iterate once more:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;msh-1.png&quot; alt=&quot;Mul Swap Hash&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Wow! It looks as if &lt;code&gt;hash0&lt;&#x2F;code&gt; is already perfectly mixed! It appears to
pass the strict avalanche criterion. At this point it would be very
interesting to test the bit independence criterion as well, maybe some
other time. Let’s iterate once more.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;msh-2.png&quot; alt=&quot;Mul Swap Hash&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Perfect, in only three iterations! Clearly there is some merit in using
&lt;code&gt;byte_swap&lt;&#x2F;code&gt;. Time to benchmark this algorithm!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;smhasher&quot;&gt;SMHasher&lt;&#x2F;h3&gt;
&lt;p&gt;Time to benchmark this algorithm!&lt;&#x2F;p&gt;
&lt;p&gt;The algorithm was implemented as above. The final two multiplications
where moved to the start of the loop, so they can happen in tandem with
the loads and adds. This does not change the state transformation
between two &lt;code&gt;quick_hadamard&lt;&#x2F;code&gt;&#x27;s in any way, so it should not change the
analysis above.&lt;&#x2F;p&gt;
&lt;p&gt;On my machine it passes all tests and performs as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3.289 bytes&#x2F;cycle - 9409.16 MiB&#x2F;sec @ 3 ghz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1-byte keys -    26.46 cycles&#x2F;hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Compare this with MurMurHash 3:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2.755 bytes&#x2F;cycle - 7883.52 MiB&#x2F;sec @ 3 ghz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1-byte keys -    23.52 cycles&#x2F;hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or with CityHashCrc which uses special CRC instructions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;7.056 bytes&#x2F;cycle - 20188.66 MiB&#x2F;sec @ 3 ghz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1-byte keys -    47.37 cycles&#x2F;hash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All benchmarks where done on a Core i7 processor, your millage may vary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;We’ve constructed a promising non-cryptographic hash function using only
multiply, byte swap and xor. As far as I know, this is the only hash
function that does not use rotates or shifts, which makes it rather
unique!&lt;&#x2F;p&gt;
&lt;p&gt;Even though it passes all the tests in SMHasher, I am concerned that
there may be a lot of correlation in the bits which goes undetected. It
would be good to build in some defenses and measure the quality of the
bit independence criterion.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;source-code&quot;&gt;Source code&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;mulswap-avalanche.cpp&quot;&gt;mulswap-avalanche.cpp&lt;&#x2F;a&gt;: The program used to
compute avalanche diagrams. It requires
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.libpng.org&#x2F;pub&#x2F;png&#x2F;libpng.html&quot;&gt;libpng&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;12&#x2F;byte-swap-based-hash-function&#x2F;byte-swap-based-hash-function&#x2F;smasher-mulswaphash.patch&quot;&gt;smasher-mulswaphash.patch&lt;&#x2F;a&gt;: Patch to include
MulSwapHash in SMHasher.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fern Generator</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/13/fern-generator/"/>
        <id>https://2π.com/13/fern-generator/</id>
        
        <content type="html" xml:base="https://2π.com/13/fern-generator/">&lt;h1 id=&quot;fern-generator&quot;&gt;Fern Generator&lt;&#x2F;h1&gt;
&lt;p&gt;Spend this evening playing with the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;processing.org&quot;&gt;Processing&lt;&#x2F;a&gt;
digital art development environment and it’s javascript export plugin
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;processingjs.org&quot;&gt;Processing.js&lt;&#x2F;a&gt;. Starting with the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;processing.org&#x2F;examples&#x2F;tree.html&quot;&gt;Tree&lt;&#x2F;a&gt; example I created the
following &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;L-system&quot;&gt;Lindenmayer system&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;script src=&quot;processing.js&quot; type=&quot;text&#x2F;javascript&quot;&gt;&lt;&#x2F;script&gt;
&lt;script type=&quot;text&#x2F;javascript&quot;&gt;function getProcessingSketchId () { return &#x27;tree&#x27;; }&lt;&#x2F;script&gt;
&lt;p&gt;&lt;canvas id=&quot;tree&quot; data-processing-sources=&quot;tree.pde&quot; 
		width=&quot;640&quot; height=&quot;360&quot;&gt;
&lt;p&gt;Your browser does not support the canvas tag.&lt;&#x2F;p&gt;
&lt;&#x2F;canvas&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;examples&quot;&gt;Examples&lt;&#x2F;h2&gt;
&lt;p&gt;Try to find the points that produce these:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;13&#x2F;fern-generator&#x2F;fern-1.png&quot; alt=&quot;Fern 1&quot; &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;13&#x2F;fern-generator&#x2F;fern-2.png&quot; alt=&quot;Fern 2&quot; &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;13&#x2F;fern-generator&#x2F;fern-3.png&quot; alt=&quot;Fern 3&quot; &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;13&#x2F;fern-generator&#x2F;fern-4.png&quot; alt=&quot;Fern 4&quot; &#x2F;&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;13&#x2F;fern-generator&#x2F;fern-5.png&quot; alt=&quot;Fern 5&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;source-code&quot;&gt;Source code&lt;&#x2F;h2&gt;
&lt;p&gt;And of course, here is the full source code to hack on
&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;13&#x2F;fern-generator&#x2F;tree.pde&quot;&gt;tree.pde&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;float&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; theta&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;float&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; gamma&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; oldMouseX&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; oldMouseY&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;float&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; detail&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; setup&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;560&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 360&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	detail &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; draw&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	background&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	frameRate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;30&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	stroke&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;40&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	float&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;50&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mouseX &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;float&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; width&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	float&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mouseY&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;float&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; height&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	theta &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; radians&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	gamma &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; radians&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mouseX &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; oldMouseX &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mouseY &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; oldMouseY&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		counter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;counter &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		counter &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;detail &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			detail &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; detail &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;detail &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			detail &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		detail &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	oldMouseX &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mouseX&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	oldMouseY &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; mouseY&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	translate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;width&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;height&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	strokeWeight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;12&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;120&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	translate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;120&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	branch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;120&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; branch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;float&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0.66&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	rotate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;gamma&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; detail&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		pushMatrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		rotate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;theta&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		stroke&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;255&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		strokeWeight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;			strokeWeight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		translate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		branch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		popMatrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		pushMatrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		rotate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;theta&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		stroke&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;255&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2.5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		strokeWeight&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		translate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		branch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;h&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;		popMatrix&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Persistent SSH Tunnels in Kubuntu</title>
        <published>2014-02-27T00:00:00+00:00</published>
        <updated>2014-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/14/autossh/"/>
        <id>https://2π.com/14/autossh/</id>
        
        <content type="html" xml:base="https://2π.com/14/autossh/">&lt;h1 id=&quot;persistent-ssh-tunnels-in-kubuntu&quot;&gt;Persistent SSH Tunnels in Kubuntu&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;install-openssh&quot;&gt;Install OpenSSH&lt;&#x2F;h2&gt;
&lt;p&gt;Kubuntu doesn’t come with SSH pre-installed. This is odd for a Linux
distribution, since even some of the more minimalist ones come with SSH
out of the box. In fact, Ubuntu is the first one I’ve seen that doesn’t.&lt;&#x2F;p&gt;
&lt;p&gt;I can understand it though, Ubuntu is aimed at novices, and SSH is
somewhat advanced usage of Linux. It can also leave your system
vulnerable if you pick weak passphrases.&lt;&#x2F;p&gt;
&lt;p&gt;The procedure of installing OpenSSH is as simple as&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	apt-get&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; install openssh-server openssh-client&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;but see the next section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;install-ssh-with-hpn-patches&quot;&gt;Install SSH with HPN patches&lt;&#x2F;h2&gt;
&lt;p&gt;(From &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;spoutcraft.org&#x2F;threads&#x2F;blazing-fast-sftp-ssh-transfer.7682&#x2F;&quot;&gt;http:&#x2F;&#x2F;spoutcraft.org&#x2F;threads&#x2F;blazing-fast-sftp-ssh-transfer.7682&#x2F;&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;(See &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.psc.edu&#x2F;index.php&#x2F;hpn-ssh&quot;&gt;http:&#x2F;&#x2F;www.psc.edu&#x2F;index.php&#x2F;hpn-ssh&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;By default Ubuntu does not use the HPN patches in its distribution. The
fault is really with the OpenSSH developers, who should &quot;merge the
patches already&quot;!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; apt-get install python-software-properties&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; add-apt-repository ppa:w-rouesnel&#x2F;openssh-hpn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; apt-get update -y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; apt-get install openssh-server openssh-client&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&#x2F;etc&#x2F;ssh&#x2F;sshd_config&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	HPNDisabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	TcpRcvBufPoll&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	HPNBufferSize&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8192&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	NoneEnabled&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;disallowing-password-based-logins&quot;&gt;Disallowing password based logins&lt;&#x2F;h2&gt;
&lt;p&gt;(From: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;help.ubuntu.com&#x2F;community&#x2F;SSH&#x2F;OpenSSH&#x2F;Configuring&quot;&gt;https:&#x2F;&#x2F;help.ubuntu.com&#x2F;community&#x2F;SSH&#x2F;OpenSSH&#x2F;Configuring&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&#x2F;etc&#x2F;ssh&#x2F;sshd_config&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	PasswordAuthentication&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; restart ssh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;nats-and-ssh-tunnels&quot;&gt;NATs and SSH tunnels&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;etc&#x2F;ssh&#x2F;sshd_config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	GatewayPorts&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;configuring-the-remote-machine&quot;&gt;Configuring the remote machine&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; useradd -r autossh -m -N&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; mkdir &#x2F;home&#x2F;autossh&#x2F;.ssh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; nano &#x2F;home&#x2F;autossh&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; chown autossh:users -R &#x2F;home&#x2F;autossh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;configuring-the-local-machine&quot;&gt;Configuring the local machine&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; useradd -r autossh -m -N&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; mkdir &#x2F;home&#x2F;autossh&#x2F;.ssh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ssh-keygen -b&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 384&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-punctuation z-definition z-string&quot;&gt; -t ecdsa -f &#x2F;home&#x2F;autossh&#x2F;.ssh&#x2F;id_ecdsa -N &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; chown autossh:users -R &#x2F;home&#x2F;autossh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;test:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; su autossh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	ssh&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -NnT -R&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;:2201:localhost:22&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-source&quot;&gt; $REMOTE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	netstat&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -lan&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; |&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2201&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	tcp&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;        0      0&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; 0.0.0.0:2201            0.0.0.0:&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;               LISTEN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	tcp6&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;       0      0&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; :::2201                 :::&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;                    LISTEN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now from any machine&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	ssh&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2201&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-source&quot;&gt; $REMOTE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;autossh&quot;&gt;AutoSSH&lt;&#x2F;h2&gt;
&lt;p&gt;(See &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.harding.motd.ca&#x2F;autossh&#x2F;&quot;&gt;http:&#x2F;&#x2F;www.harding.motd.ca&#x2F;autossh&#x2F;&lt;&#x2F;a&gt;)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	sudo&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; apt-get install autossh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;autossh-daemon&quot;&gt;AutoSSH daemon&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;description &amp;quot;autossh tunnel&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;start on runlevel [2345]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stop on runlevel [!2345]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;respawn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;respawn limit 5 60&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;exec autossh -M 0 -N -R *:2201:127.0.0.1:22 -o &amp;quot;ServerAliveInterval 60&amp;quot; -o &amp;quot;ServerAliveCountMax 3&amp;quot; -o &amp;quot;StrictHostKeyChecking=no&amp;quot; -o &amp;quot;BatchMode=yes&amp;quot; -i &#x2F;home&#x2F;autossh&#x2F;.ssh&#x2F;id_ecdsa autossh@149.210.213.161&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Unit]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Description=Autossh tunnel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Service]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Type=simple&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ExecStart=&#x2F;usr&#x2F;bin&#x2F;autossh -M 0 -N -R *:2201:127.0.0.1:22 -o &amp;quot;ServerAliveInterval 60&amp;quot; -o &amp;quot;ServerAliveCountMax 3&amp;quot; -o &amp;quot;StrictHostKeyChecking=no&amp;quot; -o &amp;quot;BatchMode=yes&amp;quot; -i &#x2F;home&#x2F;autossh&#x2F;.ssh&#x2F;id_ecdsa autossh@149.210.213.161&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Install]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WantedBy=multi-user.target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Can your programming language do this?</title>
        <published>2011-02-04T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/11/can-your-programming-language-do-this/"/>
        <id>https://2π.com/11/can-your-programming-language-do-this/</id>
        
        <content type="html" xml:base="https://2π.com/11/can-your-programming-language-do-this/">&lt;h1 id=&quot;can-your-programming-language-do-this&quot;&gt;Can your programming language do this?&lt;&#x2F;h1&gt;
&lt;p&gt;I have occasionally criticized several programming languages. These
critiques should be taken with a heap of salt, since languages I
criticize most tend to be the ones I use and prever most (i.e. C++). But
still, I should not complain but improve, so here is the start of my
attempt at &quot;The Perfect Language&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;First off: some language features that I find inspiring and would like
the language to have. Two thing should be noted: (1) I did not include
anything that is related to syntax or easily implemented as syntax
suggar, since I’m focussing on the core of the language right now and
(2) some of these features can be implemented in terms of another, if
this implementation is trivial and free of overhead then this
implementation can replace the feature.&lt;&#x2F;p&gt;
&lt;p&gt;In order of subjectively increasing difficulty, I’d like the language to
have:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Simple pure functions&lt;&#x2F;li&gt;
&lt;li&gt;Functions with side effects&lt;&#x2F;li&gt;
&lt;li&gt;Flow control, loops and recursion&lt;&#x2F;li&gt;
&lt;li&gt;Data structures&lt;&#x2F;li&gt;
&lt;li&gt;Multiple return values&lt;&#x2F;li&gt;
&lt;li&gt;First class functions&lt;&#x2F;li&gt;
&lt;li&gt;Closures&lt;&#x2F;li&gt;
&lt;li&gt;Continuations and coroutines&lt;&#x2F;li&gt;
&lt;li&gt;Reflection&lt;&#x2F;li&gt;
&lt;li&gt;Extensibility&lt;&#x2F;li&gt;
&lt;li&gt;Verification&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now what does this all mean? Let me give some examples:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-simple-pure-functions&quot;&gt;1 Simple pure functions&lt;&#x2F;h2&gt;
&lt;p&gt;Pure functions allow you to write a procedure once and use it many times
elsewhere in the code, without having to be concerned with the
internals. The return value of the function is completely determined by
the function arguments, just like mathematical functions and hence they
are called &lt;em&gt;pure&lt;&#x2F;em&gt;. The &lt;em&gt;simple&lt;&#x2F;em&gt; part refers to the fact that I have not
allows and form of loops or recursion yet. These kinds of functions
exist in any language that has only the vaguest notion of &lt;em&gt;function&lt;&#x2F;em&gt;, so
only the most essoteric languages exclude them.&lt;&#x2F;p&gt;
&lt;p&gt;A nice example is the function that takes two numbers and returns the
average of the numbers:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Example 1.1: Average of two numbers.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;number Average (numer a, numer b):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	return (a + b) &#x2F; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;2-side-effects&quot;&gt;2 Side effects&lt;&#x2F;h2&gt;
&lt;p&gt;In the majority of popular languages functions are not required to be
pure, their return values may depend on some external information
source. In fact, some form of impure functions are necessary for the
language to be useful; a function that returns the current time would be
impure by definition, or a function that asks the user for some value,
or basically anything that involves the world outside of the language.&lt;&#x2F;p&gt;
&lt;p&gt;Some functional languages go to great lengths to avoid having impure
functions and they user elaborate constructions to keep the language as
pure as possible (uniqueness types, monads, etc.). I’d like to avoid
these constructions, but I do share the strong preference for pure
functions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Example 2.1: Welcome.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is a popular variation of the ubiquites &quot;Hello World!&quot; program:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Welcome ( ):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	name ≔ ask (&amp;quot;You name please?&amp;quot;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	write (&amp;quot;Hello &amp;quot;.name.&amp;quot;!&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;3-flow-control-loops-and-recursion&quot;&gt;3 Flow control, loops and recursion&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Example 3.1: Factorial.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since input&#x2F;output is a touchy subject in functional programming
languages, they tend to substitute the following program:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;number Factorial (number n):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	if n = 0 return 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	else return n × Factorial (n - 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Example 3.2: Péter-Robinson-Ackermann function.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Ackermann function is also popular in the functional language
community, it is often used as a simple benchmark for recursion. The
function is nice because it is not immediately obvious that it
terminates on all values, however, this has been proven (in fact, we did
so this week during the lectures).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;number Ackermann (number m, number n):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	if m = 0 return n + 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	if n = 0 return A(m - 1, 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	else return A(m - 1, A(m, n - 1))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I could go on and list a few other interesting examples, but I’ll keep
it brief. A nice function would be one that calculates the Collatz
sequence. Wheter the program terminates would be and open mathematical
problem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-sctructures&quot;&gt;Data sctructures&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Example 5: Trabb Pardo-Knuth algorithm.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is another algorithm that is intended to demonstrate the language.
It demonstrates all of the features seen so far and adds the concept of
an array.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Trabb Pardo-Knuth():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	for i from 1 to 11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		S[i] ≔ readNumber()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	reverse S&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	for each x in S&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		y ≔ √|x| + 5 x³&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		if y &amp;gt; 400&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			print &amp;quot;TOO LARGE&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			print result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Example 6: Complex numbers.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Most languages do not directly support complex numbers, but allow one to
extend the language by introducing a complex type and operations to go
with it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;type complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;number r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; number i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;	complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r ≔ a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i ≔ a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt; complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;	complex&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r ≔ a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r × b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i × b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i ≔ a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r × b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i × b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Tagged unions&lt;&#x2F;p&gt;
&lt;p&gt;Multiple dispatch&lt;&#x2F;p&gt;
&lt;h2 id=&quot;multiple-return-values&quot;&gt;Multiple return values&lt;&#x2F;h2&gt;
&lt;p&gt;Most languages do not directly support for multiple return values.
Theoretically every MRV-function can be split up into several functions,
one for each return value. For example a function &lt;code&gt;sincos&lt;&#x2F;code&gt; that returns
both the sine and cosine of an angle can always be replaced the
functions &lt;code&gt;sin&lt;&#x2F;code&gt; and &lt;code&gt;cos&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Consider an algorithm exists that would calculate both the sine and
cosine of an angle simultaneously, implementing a single valued sin and
cos using this algorithm has two disadvantages: first, the algorithm
must executed twice, which takes more time, and second, there is code
duplication.&lt;&#x2F;p&gt;
&lt;p&gt;These disadvanteges are sufficiently strong that methods have been
developed to emulate proper MRV-functions. In C++ one could for example
return a &lt;code&gt;std::pair&lt;&#x2F;code&gt; or take a non-constant reference as argument and
store the result there. Both methods seem like an ugly hack to me.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Example 6: Division algorithm.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A simple example of an algorithm that computes two useful results at
once is the naive division algorithm. In any immaginable case this
particular algorithm would preform horrible, but some of the fastest
division algorithms also calculate the remainder in the process. You may
also rightly claim that in practice one would rather use the division
and modulo instruction available on the CPU, but this does not extend to
division with bigints, polynomials or general integral domains.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(result, remainder) Divide (numerator, denominator):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; result ≔ 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	remainder ≔ numerator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	while (remainder &amp;gt; denominator):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		remainder ≔ remainder - denominator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		result ≔ result + 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Example 7: Extended Euclidean algorithm.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The extended Euclidean algorithm hardly makes any sense when the x and y
are treated differently, and this is not a consequence of the algorithm,
it is a consequence of a symmetry in the function: (gcd, x, y) ≔ Euclid
(a, b) is equivalent to (gcd, y, x) ≔ Euclid (b, a). It is therefore a
strong case for multiple return values.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Euclid&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ≔ &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Divide&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;, x&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;) ≔ Euclid(b, r)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39;, x&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;#39; - d * y&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;first-class-functions&quot;&gt;First class functions&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;closures&quot;&gt;Closures&lt;&#x2F;h2&gt;
&lt;p&gt;Constructs such as objects and control structures can thus be
implemented with closures. Closures require garbage collection.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Example : Numerical differentiation.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;function f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; number ε&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	number&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;&amp;#39;(number x):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	return (f(x + ε) - f(x)) &#x2F; ε&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;	return f&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;continuations-and-coroutines&quot;&gt;Continuations and coroutines&lt;&#x2F;h2&gt;
&lt;p&gt;&quot;In any language which supports closures and proper tail calls, it is
possible to write programs in continuation-passing style and manually
implement call&#x2F;cc.&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reflection&quot;&gt;Reflection&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Example 8: Symbolic differentiaton.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;function f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; variable x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; c&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;      return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ^&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;ln&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; sin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; cos&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; cos&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;sin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; exp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; ln&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;   return&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt; Derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course this is very sloppy notation, but it should be clear what the
intended algorithm is: recursively apply differentiation rules untill
one reaches either the variable or a constant. The derivative function
is constructed in the returns. Note that there is a possiblity for
infinite recursion when trying to differentiate functions like f(x) =
tan(x), because there is no special rule for tan, it will indefinitely
recurse on the last rule.&lt;&#x2F;p&gt;
&lt;p&gt;To implement it one needs to be able to express the algorithm without
any ambiguety and sloppyness. Furthermore, the way it is written above
uses a fair amount of pattern matching.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;extensibility&quot;&gt;Extensibility&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Example 9: Regular expressions.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;astNode&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; RegexpHandler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; sourceCode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; …&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	…&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Regular expression compiler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;Compiler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;AddSyntaxRule&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;s&#x2F;*&#x2F;*&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; RegexpHandler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;write s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;W&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ld&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;World&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;Hello Wereld!&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;verification&quot;&gt;Verification&lt;&#x2F;h2&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fast packed integers</title>
        <published>2010-08-04T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/fast-packed-integers/"/>
        <id>https://2π.com/10/fast-packed-integers/</id>
        
        <content type="html" xml:base="https://2π.com/10/fast-packed-integers/">&lt;h1 id=&quot;fast-packed-integers&quot;&gt;Fast packed integers&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;unsigned-integers&quot;&gt;Unsigned integers&lt;&#x2F;h2&gt;
&lt;p&gt;The encoding I implemented is the same as the one used in
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;ebml.sourceforge.net&#x2F;specs&#x2F;&quot;&gt;EBML&lt;&#x2F;a&gt;. It works as follows&lt;&#x2F;p&gt;
&lt;p&gt;bits  bytes  pattern&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;7     1      &lt;code&gt;1xxx xxxx&lt;&#x2F;code&gt;
14    2      &lt;code&gt;01xx xxxx xxxx xxxx&lt;&#x2F;code&gt;
21    3      &lt;code&gt;001x xxxx xxxx xxxx xxxx xxxx&lt;&#x2F;code&gt;
28    4      &lt;code&gt;0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx&lt;&#x2F;code&gt;
35    5      &lt;code&gt;0000 1xxx xxxx xxxx xxxx … xxxx xxxx xxxx&lt;&#x2F;code&gt;
42    6      &lt;code&gt;0000 01xx xxxx xxxx xxxx … xxxx xxxx xxxx&lt;&#x2F;code&gt;
49    7      &lt;code&gt;0000 001x xxxx xxxx xxxx … xxxx xxxx xxxx&lt;&#x2F;code&gt;
56    8      &lt;code&gt;0000 0001 xxxx xxxx xxxx … xxxx xxxx xxxx&lt;&#x2F;code&gt;
64    9      &lt;code&gt;0000 0000 xxxx xxxx xxxx … xxxx xxxx xxxx&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Using a bit of&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; length_uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;63&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; count_leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; read_uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint64 value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; endian_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; count_leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;= *reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; endian_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; write_uint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt;char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;63&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; count_leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;8&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; endian_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		*reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; 0x&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;FF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; endian_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	*reinterpret_cast&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	buffer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; num_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;inline int&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; count_leading_zeros&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; __builtin_clzl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;inline&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; endian_swap&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; __builtin_bswap64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;value&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;signed-integers&quot;&gt;Signed integers&lt;&#x2F;h2&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>About Ontologies</title>
        <published>2010-06-05T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/about-ontologies/"/>
        <id>https://2π.com/10/about-ontologies/</id>
        
        <content type="html" xml:base="https://2π.com/10/about-ontologies/">&lt;h1 id=&quot;about-ontologies&quot;&gt;About Ontologies&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;about-ontologies-1&quot;&gt;About Ontologies&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;ontology-of-relations&quot;&gt;Ontology of relations&lt;&#x2F;h3&gt;
&lt;p&gt;Statements                                           Interpretation&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;em&gt;Nonary statements (propositions)&lt;&#x2F;em&gt;
true                                                 (true)
Humans are mortal                                    (humansAreMortal)
&lt;em&gt;Unary relations (predicates)&lt;&#x2F;em&gt;
X exists                                             (exist X)
X is heavy                                           (isHeavy X)
X is green                                           (isGreen X)
&lt;em&gt;Binary relations (triples)&lt;&#x2F;em&gt;
X equals Y                                           (equals X Y)
X likes Y                                            (like X Y)
X’s weight is Y                                      (weight X Y)
X’s colour is Y                                      (colour X Y)
&lt;em&gt;Ternary relations&lt;&#x2F;em&gt;
X was introduced to Y by Z                           (introducedToBy X Y Z)
X bought Y from Z                                    (boughtFrom X Y Z)
X is between Y and Z                                 (between X Y Z)
&lt;em&gt;Higher order relations:&lt;&#x2F;em&gt;
X loaned Y from Z between Q and R in exchange for S  (loanedFromBetweenFor X Y Z Q R S)
&lt;em&gt;Variable relations&lt;&#x2F;em&gt;
X has friends A and B and C and …                    (friends X A B C …)
X prefers A then B then C …                          (preference X A B C …)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;higher-order-relations&quot;&gt;Higher order relations:&lt;&#x2F;h4&gt;
&lt;p&gt;X loaned Y from Z between Q and R in exchange for S.&lt;&#x2F;p&gt;
&lt;p&gt;X: Person Y: Object Z: Person Q: Time R: Time S: Object&lt;&#x2F;p&gt;
&lt;p&gt;X thinks (statement)&lt;&#x2F;p&gt;
&lt;p&gt;X heard (statement)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ontologies-in-programming-languages&quot;&gt;Ontologies in programming languages&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c = mul(a, b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(q, r) = div(n, d)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(x, y) = extended_gcd(a, b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;ontologies-in-formal-mathematics&quot;&gt;Ontologies in formal mathematics&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;ontologies-in-semantic-web&quot;&gt;Ontologies in semantic web&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;a-compromise&quot;&gt;A compromise?&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;layer-1-nodes&quot;&gt;Layer 1: Nodes&lt;&#x2F;h3&gt;
&lt;p&gt;The entire data set consists of a set of nodes, &lt;span class=&quot;math math-inline&quot;&gt;\mathcal N&lt;&#x2F;span&gt;. The nodes
contain a bitstring value, but have an identity separate of their value
(so two different nodes can have the same bitstring).&lt;&#x2F;p&gt;
&lt;p&gt;This is everything there is to know about layer one.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;layer-2-tuples&quot;&gt;Layer 2: Tuples&lt;&#x2F;h3&gt;
&lt;p&gt;In layer two the value of some nodes are intepretted to represent tuples
of nodes, &lt;span class=&quot;math math-inline&quot;&gt;\left(n_1, n_2, \dots \right)&lt;&#x2F;span&gt; where &lt;span class=&quot;math math-inline&quot;&gt;n_i \in \mathcal N&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;old-version&quot;&gt;Old version:&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left( \mathcal N, \mathcal R \right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\mathcal N&lt;&#x2F;span&gt; is a set of nodes, which contain a bitstring &lt;span class=&quot;math math-inline&quot;&gt;B(n)&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;\mathcal R&lt;&#x2F;span&gt; is a set of relations of the form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left(n_1, n_2, \dots \right) \text{ where } n_i \in \mathcal N
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first object is interpreted as the kind of relation.&lt;&#x2F;p&gt;
&lt;p&gt;The second object is interpreted as the object of a relation and&lt;&#x2F;p&gt;
&lt;p&gt;That is, ordered lists of two or more nodes. This can represent a
variety of statements such as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left(n_{statement}\right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left(n_{predicate}, n_{subject}\right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left(n_{verb}, n_{subject}, n_{object}\right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left(n_{property}, n_{subject}, n_{value}\right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left(n_{function}, n_{variable}, n_{variable}, n_{variable},
n_{variable}\right)
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Node: a bitstring, can be zero to N bits long, in increments of eight.
Interpretation depends on other information available, but the following
encodings are recommended: DateTime, UTF-8.&lt;&#x2F;p&gt;
&lt;p&gt;Equivalence of content does &lt;em&gt;not&lt;&#x2F;em&gt; mean that the nodes are identical. The
nodes have their own identity. How this identity is achieved (i.e. by an
unique identification number, memory pointer or other means) is an
implementation detail which should be hidden from the programmer.&lt;&#x2F;p&gt;
&lt;p&gt;Tuple: Represents a statement. It is a list of minimal two nodes, the
first node represents the subject of the node, the second represents the
property described to the first node. The other nodes are optional
parameters to this property.&lt;&#x2F;p&gt;
&lt;p&gt;Example use cases are&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(UserJoe, IsMale) or (UserJoe, Gender, Male)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(IsMale, UserJoe) or (Gender, UserJoe, Male)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(FavoriteBands, UserJoe, Beatles, RollingStones, Metallica, ACDC)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;reification&quot;&gt;Reification&lt;&#x2F;h3&gt;
&lt;p&gt;The following example defines a node wich represents the statement
&quot;Humans are mortal&quot;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(humansAreMortal isa statement)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(humansAreMortal verb are)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(humansAreMortal subject humans)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(humansAreMortal object mortal)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With this node defined, one can now claim that humans are mortal:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(humansAreMortal)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which is a reification of the statement:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(are humans mortal)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;binding&quot;&gt;Binding&lt;&#x2F;h3&gt;
&lt;p&gt;The previous example can be considered as a special case of binding,
where all variables are bound.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;queries&quot;&gt;Queries&lt;&#x2F;h3&gt;
&lt;p&gt;Basic queries, should be O(1):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Does (predicate, object) exist?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Does (verb, object, subject) exist?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For which value does (property, object, value) exist?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For which values (x1, x2, …) does (property, object, x1, x2, …)
exist?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;More advanced, maximum O(n):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For which objects does (predicate, object) exist?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For which objects does (predicate, object) exist?&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;the-element-of-change-time&quot;&gt;The element of change&#x2F;time&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Change &lt;em&gt;the nodes&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create node&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Delete node&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Replace node value&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Change &lt;em&gt;the relations&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create relation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Delete relation&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Replace relation predicate&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Replace relation subject&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Change the argument&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Change &lt;em&gt;the argument&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Add node at position&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Remove node from position&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Swap node positions&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;revision-management&quot;&gt;Revision management&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;random-stuff&quot;&gt;Random stuff&lt;&#x2F;h3&gt;
&lt;p&gt;x = n × ( n + 1 ) &#x2F; 2 = x ÷ × n + n 1 2&lt;&#x2F;p&gt;
&lt;p&gt;(t1 + n 1) (t2 × n t1) (x ÷ t2 2)&lt;&#x2F;p&gt;
&lt;p&gt;(x ÷ (. × n (. + n &quot;1&quot;)) &quot;2&quot;)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example-using-unicode-string-instead-of-bitstrings&quot;&gt;Example using unicode string instead of bitstrings&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;quot;&amp;quot;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        . &amp;quot;Type&amp;quot;[]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        . &amp;quot;Name&amp;quot;[]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        . &amp;quot;Male&amp;quot;[]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        . &amp;quot;User&amp;quot;[]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        . &amp;quot;&amp;quot;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                . Type User&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                . Name &amp;quot;Joe&amp;quot;[]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                . Male&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Proofs without variables</title>
        <published>2010-05-09T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/proofs-without-variables/"/>
        <id>https://2π.com/10/proofs-without-variables/</id>
        
        <content type="html" xml:base="https://2π.com/10/proofs-without-variables/">&lt;h1 id=&quot;proofs-without-variables&quot;&gt;Proofs without variables&lt;&#x2F;h1&gt;
&lt;p&gt;Suppose we have a formal system for proposition logic with an axiom set
containing the modus ponens, the principle of simplification and Frege’s
axiom:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C →&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Modus Ponens&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ a → b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Principle of simplification&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ a → (b → a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Frege&amp;#39;s axiom&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ (a → (b → c)) → ((a → b) → (a → c))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is similar to the system I have &lt;a href=&quot;&#x2F;09&#x2F;12&#x2F;simple-proof-verification-system&quot;&gt;used
before&lt;&#x2F;a&gt; but I have removed the
well-formedness and Polish notation for clarity.&lt;&#x2F;p&gt;
&lt;p&gt;In this system one can proof truths like &quot;a → a&quot; as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;From a follows a&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Principle of simplification&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ a → (a → a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Principle of simplification&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a → a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ a → ((a → a) → a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Frege&amp;#39;s axiom&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a → a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                c ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ (a → ((a → a) → a)) → ((a → (a → a)) → (a → a))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Modus Ponens&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a → ((a → a) → a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ (a → (a → a)) → (a → a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ (a → (a → a)) → (a → a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Modus Ponens&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a → (a → a)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a → a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ a → a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;the-problem-with-variables&quot;&gt;The problem with variables&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;a&lt;&#x2F;em&gt; → (&lt;em&gt;b&lt;&#x2F;em&gt; → &lt;em&gt;a&lt;&#x2F;em&gt;)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;non-unique-representations&quot;&gt;Non-unique representations&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;em&gt;a&lt;&#x2F;em&gt; → (&lt;em&gt;b&lt;&#x2F;em&gt; → &lt;em&gt;a&lt;&#x2F;em&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;b&lt;&#x2F;em&gt; → (&lt;em&gt;a&lt;&#x2F;em&gt; → &lt;em&gt;b&lt;&#x2F;em&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;In fact, if you give me &lt;em&gt;n&lt;&#x2F;em&gt; different variable names, I can give you &lt;em&gt;n&lt;&#x2F;em&gt;
² different representations &lt;em&gt;of the exact same theorem&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bound-variables&quot;&gt;Bound variables&lt;&#x2F;h3&gt;
&lt;p&gt;Consider&lt;&#x2F;p&gt;
&lt;p&gt;∀&lt;em&gt;x&lt;&#x2F;em&gt; ∃&lt;em&gt;y&lt;&#x2F;em&gt; (&lt;em&gt;x&lt;&#x2F;em&gt; ≠ &lt;em&gt;y&lt;&#x2F;em&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;For every number &lt;em&gt;x&lt;&#x2F;em&gt; there exist a number &lt;em&gt;y&lt;&#x2F;em&gt; such that &lt;em&gt;x&lt;&#x2F;em&gt; is not equal
to &lt;em&gt;y&lt;&#x2F;em&gt;. True.&lt;&#x2F;p&gt;
&lt;p&gt;and now substitute &lt;em&gt;a&lt;&#x2F;em&gt; for &lt;em&gt;x&lt;&#x2F;em&gt; and &lt;em&gt;a&lt;&#x2F;em&gt; for &lt;em&gt;y&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;∀&lt;em&gt;a&lt;&#x2F;em&gt; ∃&lt;em&gt;a&lt;&#x2F;em&gt; (&lt;em&gt;a&lt;&#x2F;em&gt; ≠ &lt;em&gt;a&lt;&#x2F;em&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;For every number &lt;em&gt;a&lt;&#x2F;em&gt; there exist a number &lt;em&gt;a&lt;&#x2F;em&gt; such that &lt;em&gt;a&lt;&#x2F;em&gt; is not equal
to &lt;em&gt;a&lt;&#x2F;em&gt;. Rubbish!&lt;&#x2F;p&gt;
&lt;p&gt;It is even funnier to substitute &lt;em&gt;a&lt;&#x2F;em&gt; for &lt;em&gt;x&lt;&#x2F;em&gt; and 3 for &lt;em&gt;y&lt;&#x2F;em&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;∀&lt;em&gt;a&lt;&#x2F;em&gt; ∃3 (&lt;em&gt;a&lt;&#x2F;em&gt; ≠ 3)&lt;&#x2F;p&gt;
&lt;p&gt;For every number &lt;em&gt;a&lt;&#x2F;em&gt; there exist a number 3 such that &lt;em&gt;a&lt;&#x2F;em&gt; is not equal
to 3. Ridiculous!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;expressions-as-directed-graphs&quot;&gt;Expressions as directed graphs&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;operators&quot;&gt;Operators&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;theorems&quot;&gt;Theorems&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;unique-representations&quot;&gt;Unique representations&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;definitions-as-directed-graphs&quot;&gt;Definitions as directed graphs&lt;&#x2F;h3&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Optimizing brainfuck compiler using LLVM</title>
        <published>2010-02-27T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/brainfuck-using-llvm/"/>
        <id>https://2π.com/10/brainfuck-using-llvm/</id>
        
        <content type="html" xml:base="https://2π.com/10/brainfuck-using-llvm/">&lt;h1 id=&quot;optimizing-brainfuck-compiler-using-llvm&quot;&gt;Optimizing brainfuck compiler using LLVM&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;optimizing-brainfuck-compiler-using-llvm-1&quot;&gt;Optimizing brainfuck compiler using LLVM&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.llvm.org&quot;&gt;LLVM&lt;&#x2F;a&gt; is currently the hype in the world of
compilers. This C++ based compiler infrastruture is hard on its way to
replace the Gnu Compiler Collection. In contrast with GCC LLVM has a
nice C++ interface wich allows you to easily implement your own
language, or so I thought.&lt;&#x2F;p&gt;
&lt;p&gt;It turns out that LLVM is still somewhat of a moving target and examples
from previous versions no longer compile. It was quite a struggle to get
the simplest example to work since the API is very unintuitive and
complex at first.&lt;&#x2F;p&gt;
&lt;p&gt;In the end I managed to get it working.&lt;&#x2F;p&gt;
&lt;p&gt;Then I played with it some more. Trying out other ways to translate
brainfuck to LLVM IR.&lt;&#x2F;p&gt;
&lt;p&gt;In the end I found that I could get remarkable optimzation results. The
key was:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;enabled some complex loop optimization passes&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;allocated the brainfuck memory on the stack&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;do not create a loop to initialize the memory, but explicittly set
every cell&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you have done all that, then the compiler is capable of compiling the
following brainfuck &quot;Hello Wordl!&quot;-program:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt;+++++++++[&amp;lt;++++++++&amp;gt;-]&amp;lt;.&amp;gt;+++++++[&amp;lt;++++&amp;gt;-]&amp;lt;+.+++++++..+++.&amp;gt;&amp;gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;++++++++[&amp;lt;++++&amp;gt;-]&amp;lt;.&amp;gt;&amp;gt;&amp;gt;++++++++++[&amp;lt;+++++++++&amp;gt;-]&amp;lt;---.&amp;lt;&amp;lt;&amp;lt;&amp;lt;.+++&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.------.--------.&amp;gt;&amp;gt;+.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;into&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;define&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;code&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;72&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;101&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;108&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;108&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;111&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;87&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;111&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;114&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;108&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  call&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; @&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i8 &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;33&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  ret&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; void&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which is optimal! All the loops and operations are elliminated! Compare
that with the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;code.google.com&#x2F;p&#x2F;esotope-bfc&#x2F;&quot;&gt;esotope compiler&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benchmark&quot;&gt;Benchmark!&lt;&#x2F;h2&gt;
&lt;p&gt;Okay, now that I have my super-optimizing llvm-based brainfuck compiler
it is time to benchmark it against the direct-threaded virtual machine I
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;2010&#x2F;02&#x2F;brainfuck-vm&#x2F;&quot;&gt;developed earlier&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The direct threaded VM has two modes; &lt;em&gt;non-optimizing&lt;&#x2F;em&gt; where it executes
brainfuck instructions as-is and &lt;em&gt;optimizing&lt;&#x2F;em&gt; where it replaces certain
sequences of instructions with more efficient onces.&lt;&#x2F;p&gt;
&lt;p&gt;The llvm jit-compiler has a broad selection of optimization passes that
can be chained in uncountable ways. After a lot of trial and error I
found the chain presented in the source below. In the benchmark I also
included no optimization passes, only an instruction combining pass, the
default selection for amd64, the aggressive default selection for amd64
and my own extensive chain.&lt;&#x2F;p&gt;
&lt;p&gt;The first benchmark program, &lt;em&gt;Bottles&lt;&#x2F;em&gt;, prints the lyric to &quot;99 bottles
of beer&quot;. Developed by Andrew Paczkowski.
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;99-bottles-of-beer.net&#x2F;language-brainfuck-101.html&quot;&gt;origin&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The second, &lt;em&gt;Hanoi&lt;&#x2F;em&gt;, solves the three peg nine disk towers of Hanoi
problem and animates the solution with ascii art. Developed by Clifford
Wolf. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.clifford.at&#x2F;bfcpu&#x2F;hanoi.html&quot;&gt;origin&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Last, &lt;em&gt;Mandelbrot&lt;&#x2F;em&gt;, calculates a 512×192 mandelbrot fractal and displays
it with ascii characters. Developed by Erik Bosman.
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;esoteric.sange.fi&#x2F;brainfuck&#x2F;utils&#x2F;mandelbrot&#x2F;&quot;&gt;origin&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Virtual machine  Optimization    Bottles   Hanoi  Mandelbrot&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;direct threaded  none              0.008  29.647    1978.041
direct threaded  simple            0.017   1.091     273.033
llvm jit         none              0.129  11.731     111.611
llvm jit         combining pass    0.121   7.245      52.894
llvm jit         default           0.157   9.491      42.440
llvm jit         aggressive        0.174   9.618      42.048
llvm jit         extensive         0.375  50.141      37.745&lt;&#x2F;p&gt;
&lt;p&gt;The results are in seconds and include everything from starting the
compiler until the exit of the brainfuck program.&lt;&#x2F;p&gt;
&lt;p&gt;One result stands out: the extensively optimized hanoi takes a lot of
time! Well, actually, the optimization takes a lot of time, the
resulting program executes in less than a second. Further analysis
(using callgrind, callgraph shown below) showed that all the time was
spend in the &quot;Loop Invariant Code Motion&quot; pass. This pass is largely
responsible for the incredible optimization result shown earlier. I
suspect that LLVM was also able to reduce hanoi to a near minimal set of
output instructions, although the resulting code is too messy to confirm
this.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;brainfuck-using-llvm&#x2F;callGraphWith.png&quot; alt=&quot;Hanoi case callgraph&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;source&quot;&gt;Source!&lt;&#x2F;h2&gt;
&lt;p&gt;As always, here is the source:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;stack&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;fstream&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;Module.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;Function.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;PassManager.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;CallingConv.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;Analysis&#x2F;Verifier.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;Support&#x2F;IRBuilder.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;ExecutionEngine&#x2F;ExecutionEngine.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;Target&#x2F;TargetData.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;ModuleProvider.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;LinkAllPasses.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;ExecutionEngine&#x2F;JIT.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;lt;llvm&#x2F;Target&#x2F;TargetSelect.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-type&quot;&gt;using namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-type&quot;&gt;using namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-namespace&quot;&gt; llvm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; MyLoopInfo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; beforeValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	PHINode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; startValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; endValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; afterValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	BasicBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; beforeBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	BasicBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; startBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	BasicBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; endBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	BasicBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; afterBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; makeFunc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Module&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; module&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt; const char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; tapeSize&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 300&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Some useful types and constants&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; voidType &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; Type&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getVoidTy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getGlobalContext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; IntegerType&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; cellType &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; IntegerType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getGlobalContext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; IntegerType&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; indexType &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; IntegerType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getGlobalContext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; PointerType&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tapeType &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; PointerType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;cellType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; zero &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; ConstantInt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;cellType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; one &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; ConstantInt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;cellType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; minOne &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; ConstantInt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;cellType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F;declare i32 @getchar()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; getchar &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; cast&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getOrInsertFunction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;getchar&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; cellType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	getchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;setCallingConv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;CallingConv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F;declare i32 @putchar(i32)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; putchar &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; cast&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	getOrInsertFunction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;putchar&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; voidType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; cellType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;setCallingConv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;CallingConv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Contruct void main(char* tape)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; main &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; cast&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getOrInsertFunction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;main&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; voidType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;setCallingConv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;CallingConv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;C&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	BasicBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; block &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; BasicBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getGlobalContext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;code&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;MyLoopInfo&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loops&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	IRBuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; codeIR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; codeIR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateAlloca&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;cellType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; ConstantInt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;get&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;indexType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tapeSize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; it &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tapeSize&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		codeIR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateStore&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;zero&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; it&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		it &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; codeIR&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateGEP&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;it&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	IRBuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	switch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;source&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;&amp;gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateGEP&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;&amp;lt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateGEP&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; minOne&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;+&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; headValue &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateLoad&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateAdd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;headValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateStore&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; headValue &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateLoad&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateSub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;headValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateStore&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;.&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; output &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateLoad&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateCall&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;putchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; output&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;,&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; input &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateCall&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;getchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateStore&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;[&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Construct loop info&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			MyLoopInfo loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;beforeBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; BasicBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getGlobalContext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;afterBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; BasicBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getGlobalContext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;beforeValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Create branching instructions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; headValue &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateLoad&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; condition &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateIsNotNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;headValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateCondBr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;condition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;afterBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Create a phi node&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			IRBuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; sbuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sbuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreatePHI&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;tapeType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;addIncoming&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;beforeValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;beforeBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Push the loop&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loops&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			block &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			head &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		case&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;]&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Retrieve the loop info&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			MyLoopInfo loop &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loops&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;top&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loops&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;endValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;endBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Create a conditional branch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; headValue &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateLoad&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			Value&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; condition &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateIsNotNull&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;headValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateCondBr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;condition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;afterBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Augement loops phi node&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;startValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;addIncoming&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;endValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;endBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Switch to the after block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			block &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;afterBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;			&#x2F;&#x2F; Create a phi node&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			IRBuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; abuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			PHINode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; headPhi &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; abuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreatePHI&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;tapeType&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			headPhi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;addIncoming&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;beforeValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;beforeBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			headPhi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;addIncoming&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;endValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;endBlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			head &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; headPhi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;			break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Close the function&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		IRBuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;block&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		builder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;CreateRetVoid&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; argc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-storage z-modifier&quot;&gt; char*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; argv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;argc &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		cerr &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Usage: &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; argv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot; bf_file&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; endl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	ifstream&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; sourceFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;argv&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	string line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getline&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;sourceFile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; source &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; line&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Setup a module and engine for JIT-ing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;	std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;string error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	InitializeNativeTarget&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; Module&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;bfcode&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; getGlobalContext&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	ExecutionEngine &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;engine &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; EngineBuilder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;setErrorStr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;setOptLevel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;CodeGenOpt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Aggressive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;create&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		cout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;No engine created: &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; error &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; endl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Compile the BF to IR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	cout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Parsing...&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; flush&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	Function&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; func &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; makeFunc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;c_str&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	cout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot; done&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; endl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; cout &amp;lt;&amp;lt; *module &amp;lt;&amp;lt; endl;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Run optimization passes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	cout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Optimizing...&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; flush&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	FunctionPassManager&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ExistingModuleProvider&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; TargetData&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getTargetData&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;())));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createVerifierPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Eliminate simple loops such as [&amp;gt;&amp;gt;++&amp;lt;&amp;lt;-]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createInstructionCombiningPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Cleanup for scalarrepl.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createLICMPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                 &#x2F;&#x2F; Hoist loop invariants&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createIndVarSimplifyPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;       &#x2F;&#x2F; Canonicalize indvars&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createLoopDeletionPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;         &#x2F;&#x2F; Delete dead loops&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Simplify code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; repeat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; repeat &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; repeat&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createGVNPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                  &#x2F;&#x2F; Remove redundancies&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createSCCPPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                 &#x2F;&#x2F; Constant prop with SCCP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createCFGSimplificationPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Merge &amp;amp; remove BBs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createInstructionCombiningPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createCondPropagationPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      &#x2F;&#x2F; Propagate conditionals&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createAggressiveDCEPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Delete dead instructions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createCFGSimplificationPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    &#x2F;&#x2F; Merge &amp;amp; remove BBs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;createDeadStoreEliminationPass&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Delete dead stores&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	pm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;run&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;func&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	cout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;done&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; endl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	cout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt; *&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;module&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; endl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Compile ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	cout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Compiling...&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; flush&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	void&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;bf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)())&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;getPointerToFunction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;func&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	cout &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot; done&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; endl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; ... and run!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;	bf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Compile with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;g++&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .&#x2F;main.cpp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-evaluation z-backticks z-shell&quot;&gt; `&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;llvm-config&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; --cppflags --ldflags --libs core jit native all&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-evaluation z-backticks z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; .&#x2F;test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;&#x2F;em&gt; The order of the arguments &lt;em&gt;is&lt;&#x2F;em&gt; important! The source file must
come &lt;em&gt;before&lt;&#x2F;em&gt; the &lt;code&gt;llvm-config&lt;&#x2F;code&gt; part or the linking will fail! I lost
about a hour on this non-intuitive behaviour.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Awesome! This is exactly what I’ve been looking for.&lt;&#x2F;p&gt;
&lt;p&gt;—  B L 2011-03-03&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A pure imperative language</title>
        <published>2010-02-16T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/pure-imperative/"/>
        <id>https://2π.com/10/pure-imperative/</id>
        
        <content type="html" xml:base="https://2π.com/10/pure-imperative/">&lt;h1 id=&quot;a-pure-imperative-language&quot;&gt;A pure imperative language&lt;&#x2F;h1&gt;
&lt;p&gt;In the previous post I developed a virtual machine for a silly language
(Brainfuck) in a silly language (C++). This post is documents my attempt
to create a language that is not silly. I’ll start with three use-cases,
show their C++ implementation and then start mutulating the C++ syntax.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;three-challenging-functions&quot;&gt;Three challenging functions&lt;&#x2F;h2&gt;
&lt;p&gt;The following three functions are my favorites when trying out a new
language. You’ll be supprised at how often one or more of these examples
are simply impossible in a language, yet they represent very common
mathematical operations.&lt;&#x2F;p&gt;
&lt;p&gt;The first challenge is recursion:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; factorial&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; fac&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I could make it more challening by requiring guaranteed &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Tail_recursion&quot;&gt;tail call
optimization&lt;&#x2F;a&gt;, but for now
let’s just leave it at supporting recursive functions.&lt;&#x2F;p&gt;
&lt;p&gt;The second challenge is multiple return values:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; divide&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; quotient&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; remainder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;  int&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; dividend&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; divisor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	quotient &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	remainder &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dividend&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;remainder &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; divisor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		remainder &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; divisor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;quotient&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The C++ solution is functional, but syntacticly it mixes inputs and
outputs.&lt;&#x2F;p&gt;
&lt;p&gt;The third challenge is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;First_Class_Functions&quot;&gt;first class
functions&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-type&quot;&gt;typedef double&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; makeDerivative&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; double&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; dx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; delegate&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; double&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that this last example is not valid
C&lt;code&gt;! In fact, I doubt there is a way to express this function in C&lt;&#x2F;code&gt;
without calling an external compiler and linking in the result.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;developing-a-solution&quot;&gt;Developing a solution&lt;&#x2F;h2&gt;
&lt;p&gt;Since this is supposed to become a practical solution, I’ll start with a
pragmatic language: C++. In a few steps I will completely disfigure this
language, hopefully for the better.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-zero-removing-the-sugar&quot;&gt;Step zero: removing the sugar&lt;&#x2F;h3&gt;
&lt;p&gt;Templates in C++ are little more than statically typed macros. Remove
them. Object oriented programming is little more than implicit passing
of a &lt;code&gt;this&lt;&#x2F;code&gt; pointer to member functions. Type inheritance and virtuals
functions are a bit more complex, but these can be simultated with first
class functions. Oh yes and remove the whole pre-processor.&lt;&#x2F;p&gt;
&lt;p&gt;We are now basically left with C again, but without a few of the
problems that C has. We can always add a new sugar coating later, but
first we’ll redesign the cake.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-one-multiple-return-values&quot;&gt;Step one: multiple return values&lt;&#x2F;h3&gt;
&lt;p&gt;The second challenge is probably the easiest, so I’ll start with this
one. Let’s extend C++ in the following way:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; quotient&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; remainder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;divide&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dividend&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; divisor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	quotient &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	remainder &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dividend&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;remainder &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; divisor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		remainder &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; divisor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;		++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;quotient&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Function call syntax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; divide&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;13&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In summary: return values are named, return values are assigned as local
variables, &lt;code&gt;return&lt;&#x2F;code&gt; no longer takes an argument, function calls take the
form &lt;code&gt;() = ();&lt;&#x2F;code&gt;. Nesting of function calls like &lt;code&gt;sqrt(sin(x)+cos(x))&lt;&#x2F;code&gt; is
no longer supported (altough this could easily be reintroduced with some
syntactic sugar).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-two-pure-functions&quot;&gt;Step two: pure functions&lt;&#x2F;h3&gt;
&lt;p&gt;For the sake of clarity and tractability, let’s make the all functions
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pure_function&quot;&gt;pure&lt;&#x2F;a&gt;. That is, all inputs
are constant or unchangable.&lt;&#x2F;p&gt;
&lt;p&gt;Pure functions make it difficult to interact with stateful objects.
These not only include objects from object-oriented programming, but
also thing such as IO operations. In fact, functions like
&lt;code&gt;currentTime()&lt;&#x2F;code&gt; and &lt;code&gt;randomNumber()&lt;&#x2F;code&gt; are by their nature impure.&lt;&#x2F;p&gt;
&lt;p&gt;One solution is to introduce an explicit state variable:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Object&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-this&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; returnValue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ObjectMemberFunction&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Object&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-language z-this&quot;&gt; this&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pipe state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; string input&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; readInput&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pipe state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;clockType state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; timeType time&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; currentTime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;clockType state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;RNG state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; number&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; randomNumber&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;RNG state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; min&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will all be hidden under a sugar coating later. I have not yet
tought about how to incorporate multi-threaded memory access into this.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-three-lambda-expressions&quot;&gt;Step three: lambda expressions&lt;&#x2F;h3&gt;
&lt;p&gt;The last challenge requires functions as values and thus the creation of
anonymous functions.&lt;&#x2F;p&gt;
&lt;p&gt;I’ll introduce the following expression to create anonymous functions&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; )&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;inputs&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;	&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;statements&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now challenge three can be implemented as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;typedef&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;function derivative&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; makeDerivative&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;function f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	derivative &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dfdx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		dfdx &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; dx&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-four-only-lambda-expressions&quot;&gt;Step four: only lambda expressions&lt;&#x2F;h3&gt;
&lt;p&gt;We are now in the situation where the following two pieces of code are
equivalent:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; addFive&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;addFive &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;double&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Redundancy in notation is never good, it reflects a discrepancy between
syntax and semantics. I’ll remove the redundancy by elliminating the
first form. All functions are to be declared via the λ expression.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-five-re-introducing-recursion&quot;&gt;Step five: re-introducing recursion&lt;&#x2F;h3&gt;
&lt;p&gt;The last step introduced a problem, we can no longer define recursive
functions! Look what happens:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;factorial &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; factorial&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem is, &lt;code&gt;factorial&lt;&#x2F;code&gt; is not yet defined when inside the function.
This is the problem of recursive anonymous lambda expressions. The
common way to solve this is using a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fixed_point_combinator&quot;&gt;fixed point
combinator&lt;&#x2F;a&gt; (see
also &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ps.uni-sb.de&#x2F;courses&#x2F;sem-prog97&#x2F;material&#x2F;YYWorks.ps&quot;&gt;this article in
lisp&lt;&#x2F;a&gt;
and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blogs.msdn.com&#x2F;madst&#x2F;archive&#x2F;2007&#x2F;05&#x2F;11&#x2F;recursive-lambda-expressions.aspx&quot;&gt;the F♯
version&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;A practical way to solve this is by introducing the &lt;code&gt;self&lt;&#x2F;code&gt; keyword for
self referencing:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;factorial &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that I am breaking my own function calling rule for the sake of
clarity. To enforce the rule one would need to explicitly introduce
temporary variables. The correct version would be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;factorial &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;λ&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;	bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; isZero&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;isZero&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;isZero&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; identity&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;		int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; prevN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;prevN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; subtract&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;prevF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;prevN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;		(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; multiply&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; prevF&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-six-syntax-change&quot;&gt;Step six: syntax change&lt;&#x2F;h3&gt;
&lt;p&gt;Since this language has become an odd one in the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Curly_bracket_programming_language&quot;&gt;curly bracket
family&lt;&#x2F;a&gt;
we might as well change all of the syntax:&lt;&#x2F;p&gt;
&lt;p&gt;Design principles:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Very simple grammar&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Strong emphasize on following common mathematical syntax&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Symetric infix operators have symetric symbols&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Assymetric infix operators have assymetric symbols, of which the
mirror image works as espected&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Functionality        Old notation               New notation&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Assignment           &lt;code&gt;x = y&lt;&#x2F;code&gt;                    &lt;code&gt;x ↤ y&lt;&#x2F;code&gt;
Anonymous tuple type &lt;code&gt;(type, type, …)&lt;&#x2F;code&gt;          &lt;code&gt;(type, type, …)&lt;&#x2F;code&gt;
Anonymous tuple      &lt;code&gt;(value, value, …)&lt;&#x2F;code&gt;        &lt;code&gt;(value, value, …)&lt;&#x2F;code&gt;
Named tuples         &lt;code&gt;(type name, type name, …) &lt;&#x2F;code&gt;(name: type, name: type
Function type        +&lt;em&gt;outputs&lt;&#x2F;em&gt; *&lt;em&gt;inputs&lt;&#x2F;em&gt; +     &lt;code&gt;→&lt;&#x2F;code&gt;
Function definition  &lt;code&gt;   {  }&lt;&#x2F;code&gt;                  +&lt;em&gt;name&lt;&#x2F;em&gt; ↤ λ &lt;em&gt;inputs&lt;&#x2F;em&gt; → &lt;em&gt;outputs&lt;&#x2F;em&gt; { &lt;em&gt;statements&lt;&#x2F;em&gt; | }
Function call        &lt;code&gt;= &lt;&#x2F;code&gt;                     &lt;code&gt;↤ &lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;em&gt;inputs&lt;&#x2F;em&gt; and &lt;em&gt;outputs&lt;&#x2F;em&gt; are anonymous tuples types when in a
function type, named tuples in a function definition and anonymous
tuples in a function call.&lt;&#x2F;p&gt;
&lt;p&gt;The factorial example now becomes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;factorial ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	isZero ↤&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;isZero&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f ↤ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f ↤ n ×&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-seven-the-if-meta-function&quot;&gt;Step seven: the &lt;em&gt;if&lt;&#x2F;em&gt; meta-function&lt;&#x2F;h3&gt;
&lt;p&gt;In the above example still contains silly syntaxt like
&lt;code&gt;if (&amp;lt;em&amp;gt;bool&amp;lt;&#x2F;em&amp;gt;) {&amp;lt;em&amp;gt;statements&amp;lt;&#x2F;em&amp;gt; } else {&amp;lt;em&amp;gt;statements&amp;lt;&#x2F;em&amp;gt; }&lt;&#x2F;code&gt;.
This can be replaced by a simple meta-function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;if&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;condition&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; then&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;output&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Depending on &lt;code&gt;condition&lt;&#x2F;code&gt; this function returns either &lt;code&gt;then&lt;&#x2F;code&gt; or &lt;code&gt;else&lt;&#x2F;code&gt;.
Now, the naïve way to employ this functions is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;factorial ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	f ↤ n ×&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	isZero ↤&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	f ↤&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;isZero&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But this will lead to infinite recursion. The correct way is to make use
of the first-class functions:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;factorial ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	then ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f ↤ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	else&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f ↤ n ×&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	isZero ↤&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; equals&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	ff ↤&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;isZero&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; then&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	f ↤&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; ff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;step-eight-the-while-meta-function&quot;&gt;Step eight: the &lt;em&gt;while&lt;&#x2F;em&gt; meta-function&lt;&#x2F;h3&gt;
&lt;p&gt;Another way to implement the factorial function is using a loop:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;factorial ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	f ↤ &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	do&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		f ↤ n × f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		n ↤ n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		repeat ↤ ni &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;repeat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But this &lt;code&gt;do { &amp;lt;em&amp;gt;statements&amp;lt;&#x2F;em&amp;gt; } while (&amp;lt;em&amp;gt;condition&amp;lt;&#x2F;em&amp;gt;)&lt;&#x2F;code&gt; polutes
the language. It can be replaced by the following meta function:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;while&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loopState&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;: (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loopState&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;loopState&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; repeat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;output&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This function starts with &lt;code&gt;loopState&lt;&#x2F;code&gt; and then itterates the function
&lt;code&gt;loop&lt;&#x2F;code&gt; on it untill this function sets &lt;code&gt;repeat&lt;&#x2F;code&gt; to false. The factorial
can now be implemented as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;factorial ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	loop ↤ λ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ni&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; fi&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; → &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;no&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; fo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; int&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; repeat&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		fo ↤ ni × fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		no ↤ ni &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		repeat ↤ ni &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	f ↤&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; loop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All the other control flow constructions such as &lt;code&gt;switch&lt;&#x2F;code&gt; and &lt;code&gt;for&lt;&#x2F;code&gt; can
be trivially rewritten using &lt;code&gt;if&lt;&#x2F;code&gt; and &lt;code&gt;while&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;to-be-continued&quot;&gt;to be continued…&lt;&#x2F;h2&gt;
&lt;p&gt;That’s enough for now. Some things for the future:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Formal grammar and type system&lt;&#x2F;li&gt;
&lt;li&gt;Parser and compiler (using &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;quex.sourceforge.net&#x2F;&quot;&gt;Quex&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;llvm.org&#x2F;&quot;&gt;LLVM&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Explicit internal and external variables to functions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Generic_programming&quot;&gt;Generics&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Homoiconic&quot;&gt;Homoiconicity&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Ability to extend parser and compiler &lt;em&gt;in language&lt;&#x2F;em&gt; and at runtime&lt;&#x2F;li&gt;
&lt;li&gt;A large coating of syntactic sugar developed in language&lt;&#x2F;li&gt;
&lt;li&gt;Arrays, list, containers, etc…&lt;&#x2F;li&gt;
&lt;li&gt;Embedded proofs and a verifying compiler&lt;&#x2F;li&gt;
&lt;li&gt;Self-hosting&lt;&#x2F;li&gt;
&lt;li&gt;Self-awareness&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Brainfuck compiler &#x2F; optimizer &#x2F; VM</title>
        <published>2010-02-09T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/brainfuck-vm/"/>
        <id>https://2π.com/10/brainfuck-vm/</id>
        
        <content type="html" xml:base="https://2π.com/10/brainfuck-vm/">&lt;h1 id=&quot;brainfuck-compiler-optimizer-vm&quot;&gt;Brainfuck compiler &#x2F; optimizer &#x2F; VM&lt;&#x2F;h1&gt;
&lt;p&gt;Last night I read
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;citeseer.ist.psu.edu&#x2F;cache&#x2F;papers&#x2F;cs&#x2F;32018&#x2F;http:zSzzSzwww.jilp.orgzSzvol5zSzv5paper12.pdf&#x2F;ertl03structure.pdf&quot;&gt;this&lt;&#x2F;a&gt;
paper by M. Ertl and David Gregg about the efficient design of virtual
machines. The majority of the paper is about the comparison between two
techniques to run trough the bytecode.&lt;&#x2F;p&gt;
&lt;p&gt;The first method is to run through the bytecode by making a big switch
statement. This method is called &quot;instruction dispatch using switch&quot;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;enum&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Instructions&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Other instructions...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-enummember&quot;&gt;        end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;        static&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Instruction program[] &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        Instruction&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; instructionPointer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; program&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(;;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; switch&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;instructionPointer&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                case&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                        &#x2F;&#x2F; Add some things...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; Other instructions...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                case&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; end&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The second method uses a GCC extension to the language called &quot;labels as
values&quot;. This allows one to take the memory addresses of goto labels. A
virtual machine could be implemented as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;        static&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; Instruction program[] &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;                &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        Instruction&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; instructionPointer &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; program&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; **&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;instructionPointer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        add&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; Add some things...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                goto&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; **++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;instructionPointer&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Other instructions...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        end&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Shorter and faster, exactly the way I like my optimizations! If you are
interested in why this implementation is faster I encourage you to read
the paper. It basically boils down to three things: no bounds checking,
no jumptable lookups and better branch prediction.&lt;&#x2F;p&gt;
&lt;p&gt;To make the virtual machine even faster the paper suggests to inline
certain combinations of instructions into &lt;em&gt;superinstructions&lt;&#x2F;em&gt;. This is
commonly known as &quot;selective inlining&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Okay, now that I know all that, I need a simple language to try all this
out. &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Brainfuck&quot;&gt;Brainfuck&lt;&#x2F;a&gt; will do nicely
with only eight language commands and a simple program state.&lt;&#x2F;p&gt;
&lt;p&gt;The first problem was how to get the labels addresses outside of the
engine functions. My solution was to create a special condition when an
empty program is entered to store the addresses in an instruction table:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; Program&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; program&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;program&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                instructionTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;L&amp;quot;&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;right&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                instructionTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;L&amp;quot;&amp;lt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;left&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                instructionTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;L&amp;quot;]&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;exitLoop&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                instructionTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;L&amp;quot;end&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; = &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;end&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With the label addresses stored I can now implement the compiler:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;Program&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; compile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; wstring&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;        InstructionTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;iterator insItt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        Program program&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        wstring&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;L&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; source&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                insItt &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; instructionTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;find&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;insItt &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; instructionTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;end&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        program&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;insItt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;).&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;second&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        program&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;instructionTable&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;L&amp;quot;end&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; program&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To the eight brainfuck instructions I added seven superinstructions. The
first four represent repeated occurrences of &lt;code&gt;[&lt;&#x2F;code&gt;, &lt;code&gt;&amp;lt;&lt;&#x2F;code&gt;, &lt;code&gt;+&lt;&#x2F;code&gt; or &lt;code&gt;-&lt;&#x2F;code&gt;, which
happens often in brainfuck. They take an argument containing the number
of repetitions. The next superinstruction implements &lt;code&gt;[-]&lt;&#x2F;code&gt;. The last two
super instructions are conditional jumps forward and backward. The
brainfuck looping instructions are transformed into pre-calculated
conditional jumps.&lt;&#x2F;p&gt;
&lt;p&gt;I then created an optimization pass that takes a program and transforms
it by applying the superinstruction replacement rules described above.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;benchmark&quot;&gt;Benchmark&lt;&#x2F;h2&gt;
&lt;p&gt;One of the more interesting brainfuck programs I found is
&lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;brainfuck-vm&#x2F;mandelbrot.bf&quot;&gt;mandelbrot&lt;&#x2F;a&gt;&lt;&#x2F;em&gt; by Erik Bosman. I used a version that
computes a 256×96 mandelbrot set. The virtual machine without
optimization pass takes 7:24 minutes to complete. With optimization pass
it takes exactly one minute.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;brainfuck-vm&#x2F;mandelbrot.png&quot; alt=&quot;A 128×48 mandelbrot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Virtual machines are easy and fast.&lt;&#x2F;p&gt;
&lt;p&gt;Oh yes, and the whole thing properly sets up an unicode compliant
input&#x2F;output and treats cell values as utf-32. So you can output all the
unicode characters from your brainfuck programs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;source-code&quot;&gt;Source code&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;brainfuck-vm&#x2F;main.cpp&quot;&gt;main.cpp&lt;&#x2F;a&gt;: The compiler. optimizer and virtual machine. In a
little under three hundred lines :)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;brainfuck-vm&#x2F;Makefile&quot;&gt;Makefile&lt;&#x2F;a&gt;: A simple Makefile.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;brainfuck-vm&#x2F;fixups.h&quot;&gt;fixups.h&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;brainfuck-vm&#x2F;fixups.cpp&quot;&gt;fixups.cpp&lt;&#x2F;a&gt;: Some C++ fixups to
make the language less unbearable. All explained in &lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;brainfuck-vm&#x2F;fixing-bugs-in-the-c-standard&quot;&gt;this
post&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Working around bugs in the C++ standard</title>
        <published>2010-01-30T00:00:00+00:00</published>
        <updated>2010-01-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/fixing-bugs-in-the-c-standard/"/>
        <id>https://2π.com/10/fixing-bugs-in-the-c-standard/</id>
        
        <content type="html" xml:base="https://2π.com/10/fixing-bugs-in-the-c-standard/">&lt;h1 id=&quot;working-around-bugs-in-the-c-standard&quot;&gt;Working around bugs in the C++ standard&lt;&#x2F;h1&gt;
&lt;p&gt;Anyone serious into high-performance computing should sooner or later
start programming in C++. This language is powerful, flexible and has a
large collection of libraries. But the language is also old and
complicated and thus full of little annoying sub-optimalities. In this
post I will explore some of those awkwardness’s and describe ways to
work around them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cross-platform-integer-types&quot;&gt;Cross platform integer types&lt;&#x2F;h2&gt;
&lt;p&gt;The first oddity in the standard is that C++ does not make any
guarantees about how many bits there are in an &lt;code&gt;int&lt;&#x2F;code&gt;. I’m
quite fond of mathematical computation and bit twiddling algorithms, so
here is the workaround:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;lt;stdint.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Remove those ugly _t&amp;#39;s…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-type&quot;&gt;typedef uint32_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-type&quot;&gt;typedef int32_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sint32&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-type&quot;&gt;typedef uint64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-storage z-type&quot;&gt;typedef int64_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;pre&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the future you can use cstdint instead of stdint.h. The cstdint
header puts everything in a namespaces, other than that I don’t think it
will differ.&lt;&#x2F;p&gt;
&lt;p&gt;Its also interesting to note how the standard library seems to combine
underscores, which I find too verbose for variable names, with mnemonics
like &lt;code&gt;mem_fn&lt;&#x2F;code&gt; and &lt;code&gt;codecvt&lt;&#x2F;code&gt;, which I find
too concise. The rest of the modern world uses CamelCase with
ReadableAndDescriptiveNames.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unicode-support&quot;&gt;Unicode support&lt;&#x2F;h2&gt;
&lt;p&gt;When programming only two text encodings are relevant: UTF-8 and
whatever the local environment considers the default encoding. When
working with western scripts or computer languages (source files, html,
etc.) UTF-8 gives the smallest encoding. Since most network and disk
operations are bandwidth limited it is also the fastest encoding in a
lot of cases.&lt;&#x2F;p&gt;
&lt;p&gt;In the case of unicode in C++ a third one comes into play, UTF-32. This
encoding stores the codepoints as 32 bit integers in the platforms
native byte order. This has the advantages that there hardly any
encoding&#x2F;decoding overhead. The idea is that characters have a fixed
length encoding, but this is an illusion since there are &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Combining_character&quot;&gt;combining
characters&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I’m still not entirely convinced that UTF-32 is the best encoding for
strings in memory. A western&#x2F;computer script encoded in UTF-32 is
roughly 4× the size of the UTF-8 encoding. Since memory bandwidth quite
limited UTF-32 might be slower to process than UTF-8. I’ll have to
benchmark this sometime.&lt;&#x2F;p&gt;
&lt;p&gt;For now it seems that C++&#x27;s native (read: least unsupported) unicode
encoding is UTF-32. These are constucted as &lt;code&gt;wchar_t*&lt;&#x2F;code&gt;
or &lt;code&gt;wstring&lt;&#x2F;code&gt;. However, you will often need to convert to
and from &lt;code&gt;char*&lt;&#x2F;code&gt; and &lt;code&gt;string&lt;&#x2F;code&gt;, for
example to decode the arguments to main. The following function does
such a decoding:&lt;&#x2F;p&gt;
&lt;p&gt;(also note how C++ has full exception handling support, but
&lt;code&gt;std::codecvt::in&lt;&#x2F;code&gt; still returns error codes).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;lt;locale&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;lt;exception&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;lt;stdexcept&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;wstring&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; decodeLocale&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-parameter z-cpp&quot;&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; encoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	typedef&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;codecvt&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;wchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; char&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type&quot;&gt;mbstate_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; converter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	uint32 length &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; encoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;	std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;locale locale&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;	const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; converter&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; facet &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; use_facet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;converter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;locale&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;	std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type&quot;&gt;mbstate_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; Bug workaround&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;	&#x2F;&#x2F; http:&#x2F;&#x2F;gcc.gnu.org&#x2F;bugzilla&#x2F;show_bug.cgi?id=28059&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;	std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;memset&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; sizeof&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type&quot;&gt;mbstate_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;	const char&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; in &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; encoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;c_str&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier z-storage z-type&quot;&gt;	const char&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; in_next &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	wchar out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	wchar&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; out_next &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;	converter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;result result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; facet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;state&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; in &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; in_next&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; out &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; length&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; out_next&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;result &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; converter&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; invalid_argument&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;The argument could not be decoded.&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;wstring&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; out_next &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Yes, this is the easiest correct way! The C++ unicode interface is
designed to be impossible to use. This seems to be a requirement for
inclusion in the standard. To show my point, compare the above with an
equivalent implementation in C#:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;using&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; System&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;using&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; System&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Encoding&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;string&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; decodeLocal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;byte&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[]&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; encoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-new&quot;&gt; new&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; String&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Encoding&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;Default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;GetChars&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;encoded&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But you wouldn’t even need such a function since all text input&#x2F;output
functions operate on String objects and these abstract away encoding
details.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;useful-output-on-stl-containers&quot;&gt;Useful output on STL containers&lt;&#x2F;h2&gt;
&lt;p&gt;Programing is so much easier if you can just dump any variable to the
output to inspect its value. For this reason most modern languages
define &lt;code&gt;ToString()&lt;&#x2F;code&gt; functions on every type which are
automatically used in such situations. As you could have guessed by now,
C++ does not offer such convenience functions by default, but it allows
you to define them.&lt;&#x2F;p&gt;
&lt;p&gt;Here is how you could implement an pretty-printer for the
&lt;code&gt;std::vector&lt;&#x2F;code&gt; type:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;template&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-cpp&quot;&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;wostream&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; operator&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;wostream&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-scope-resolution z-parameter z-cpp&quot;&gt; std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;T&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	out &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; L&amp;quot;[&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint32 i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;		out &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;		if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;			out &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; L&amp;quot;, &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;	out &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; L&amp;quot;]&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;	return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; out&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Codecup 2010: Wallhack</title>
        <published>2010-01-16T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/codecup-2010-wallhack/"/>
        <id>https://2π.com/10/codecup-2010-wallhack/</id>
        
        <content type="html" xml:base="https://2π.com/10/codecup-2010-wallhack/">&lt;h1 id=&quot;codecup-2010-wallhack&quot;&gt;Codecup 2010: Wallhack&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;codecup-2010-wallhack-1&quot;&gt;Codecup 2010 Wallhack&lt;&#x2F;h2&gt;
&lt;p&gt;This years Codecup is about a maze solving game called
&quot;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.codecup.nl&#x2F;rules_amazes.php&quot;&gt;Amazes&lt;&#x2F;a&gt;&quot;. My brother Vincent
participated in this competition with good results! He scored second
place! You can find the full results here: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.codecup.nl&#x2F;competition.php?comp=94&quot;&gt;Final
results&lt;&#x2F;a&gt; Complete source
code of his entry (2171 lines of code):
&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;10&#x2F;codecup-2010-wallhack&#x2F;Wallhack.java&quot;&gt;Wallhack.java&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Proof verification in GEB</title>
        <published>2010-01-03T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/10/proof-verification-in-geb/"/>
        <id>https://2π.com/10/proof-verification-in-geb/</id>
        
        <content type="html" xml:base="https://2π.com/10/proof-verification-in-geb/">&lt;h1 id=&quot;proof-verification-in-geb&quot;&gt;Proof verification in GEB&lt;&#x2F;h1&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Douglas_Hofstadter&quot;&gt;Hofstadter&lt;&#x2F;a&gt;&#x27;s book
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;G%C3%B6del,_Escher,_Bach&quot;&gt;Gödel, Escher, Bach&lt;&#x2F;a&gt;
he discusses a few formal systems. In this post I have translated the
two simplest of them to my simple &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;2009&#x2F;12&#x2F;simple-proof-verification-system&#x2F;&quot;&gt;proof verification
system&lt;&#x2F;a&gt;
which, as suggested by Sander’s comment, is extended with a command to
define a constant.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-miu-system&quot;&gt;The MIU-System&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C M&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Sole axiom&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ M I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Rule I&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ x I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ x I U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Rule II&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ M x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ M x x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Rule III&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ x I I I y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ x U y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Rule IV&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ x U U y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ x y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With the system defined, I can now enter the derivation of &lt;code&gt;MUIIU&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Derivation of M U I I U&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Sole axiom&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Rule II&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x ⊧ I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Rule II&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x ⊧ I I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Rule II&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x ⊧ I I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Rule I&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x ⊧ M I I I I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Rule III&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x ⊧ M&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                y ⊧ I U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Rule III&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x ⊧ M&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                y ⊧ I U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Rule II&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x ⊧ U I U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Rule IV&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                x ⊧ M U I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                y ⊧ I U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ M U I I U&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;the-pq-system&quot;&gt;The pq-System&lt;&#x2F;h2&gt;
&lt;p&gt;The pq-system is not that formal in the book, it contains expressions
such as &quot;whenever x is composed of hyphens only&quot; that are not further
specified. Luckily, it is easy to formalise these statements in my proof
language:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C q&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C -&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C ComposedOfHyphens&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;ComposedOfHyphens -&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ ComposedOfHyphens -&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;ComposedOfHyphens a b&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ ComposedOfHyphens a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ ComposedOfHyphens b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ ComposedOfHyphens a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;The Axiom&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ ComposedOfHyphens x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ x p - q x -&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;The Rule&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ ComposedOfHyphens x&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ ComposedOfHyphens y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ ComposedOfHyphens z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ x p y q z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ x p y - z -&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Complex Analysis, L-systems and Christmas</title>
        <published>2009-12-29T00:00:00+00:00</published>
        <updated>2014-03-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/12/complex-analysis-l-systems-and-christmas/"/>
        <id>https://2π.com/09/12/complex-analysis-l-systems-and-christmas/</id>
        
        <content type="html" xml:base="https://2π.com/09/12/complex-analysis-l-systems-and-christmas/">&lt;h1 id=&quot;complex-analysis-l-systems-and-christmas&quot;&gt;Complex Analysis, L-systems and Christmas&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Peano-Gosper.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Question&lt;&#x2F;em&gt;: What is the relation between &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;L-system&quot;&gt;Lindenmayer
systems&lt;&#x2F;a&gt;, complex analysis and
recursive lambda functions?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Answer&lt;&#x2F;em&gt;: Snow! (and other fractals)&lt;&#x2F;p&gt;
&lt;p&gt;Inspired by Sander’s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;shuisman.com&#x2F;?p=296&quot;&gt;recent blog post&lt;&#x2F;a&gt;
about the Koch snowflake in Mathematica I discovered a particularly
short way to implement certain L-systems in Mathematica. The basic idea
is to create an array of complex values of which the argument represents
the direction at that point. Such a list is easily created with complex
multiplication and recursive functions, which can be implemented very
concise with lambda functions. The last step is to use &lt;code&gt;Accumulate&lt;&#x2F;code&gt; to
transform this to a list of point coordinates in the complex plane and
plot this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;koch-snowflake&quot;&gt;Koch snowflake&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a=E^(Pi&#x2F;3I);{Re[#],Im[#]}&amp;amp;&#x2F;@Accumulate[Flatten[{0,a#,a^5#,-#}&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Nest[{#,a#,a^5#,#}&amp;amp;,1,3]]]]&#x2F;&#x2F;Line&#x2F;&#x2F;Graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Koch.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;penrose-snowflake&quot;&gt;Penrose snowflake&lt;&#x2F;h2&gt;
&lt;p&gt;Axiom: Forward, Turn 1&#x2F;5, Forward, Turn 1&#x2F;5, Forward, Turn 1&#x2F;5, Forward,
Turn 1&#x2F;5, Forward.&lt;&#x2F;p&gt;
&lt;p&gt;Rule: Forward, Turn 1&#x2F;5, Forward, Turn 1&#x2F;5, Forward, Reverse, Forward,
Turn -1&#x2F;10, Forward, Turn 1&#x2F;5, Forward&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a=Exp[Pi&#x2F;5I];{Re[#],Im[#]}&amp;amp;&#x2F;@Accumulate[Flatten[{0,#,a^2#,a^4#,a^6&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#,a^8#}&amp;amp;[Nest[{#,a^2#,a^4#,a^9#,a^8#,#}&amp;amp;,1,3]]]]&#x2F;&#x2F;Line&#x2F;&#x2F;Graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Penrose.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;exterior-snowflake&quot;&gt;Exterior snowflake&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a=Exp[Pi&#x2F;3I];{Re[#],Im[#]}&amp;amp;&#x2F;@Accumulate[Flatten[{0,#,a#,a^2#,a^3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#,a^4#,a^5#}&amp;amp;[Nest[{#,a#,#&#x2F;a,#}&amp;amp;,1,3]]]]&#x2F;&#x2F;Line&#x2F;&#x2F;Graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Exterior.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quadratic-koch-snowflake&quot;&gt;Quadratic Koch snowflake&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{Re[#],Im[#]}&amp;amp;&#x2F;@Accumulate[Flatten[{0,#,I#,-#,-I#}&amp;amp;[Nest[{#,-I#,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#,I#,I#,I#,#,-I#,#}&amp;amp;,1,3]]]]&#x2F;&#x2F;Line&#x2F;&#x2F;Graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Quadratic.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dragon-curve&quot;&gt;Dragon curve&lt;&#x2F;h2&gt;
&lt;p&gt;Not a snowflake, but I’m working up to something. This one uses two
substitution paths and therefore can’t use iterated lambda functions,
but iterated replacement rules work fine:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{Re[#],Im[#]}&amp;amp;&#x2F;@Accumulate[FoldList[Times,1,Flatten[Nest[#&#x2F;.{X-&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{X,I,Y,1},Y-&amp;gt;{1,X,-I,Y}}&amp;amp;,X,11]&#x2F;.{X-&amp;gt;{},Y-&amp;gt;{}}]]]&#x2F;&#x2F;Line&#x2F;&#x2F;Graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Dragon.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sierpinski-arrowhead-curve&quot;&gt;Sierpiński arrowhead curve&lt;&#x2F;h2&gt;
&lt;p&gt;Still not a snowflake…&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a=E^(Pi&#x2F;3I);{Re[#],Im[#]}&amp;amp;&#x2F;@Accumulate[FoldList[Times,1,Flatten[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Nest[#&#x2F;.{X-&amp;gt;{Y,1&#x2F;a,X,1&#x2F;a,Y},Y-&amp;gt;{X,a,Y,a,X}}&amp;amp;,X,6]&#x2F;.{X-&amp;gt;1,Y-&amp;gt;1}]]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;]&#x2F;&#x2F;Line&#x2F;&#x2F;Graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Sierpinski.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hilbert-space-filling-curve&quot;&gt;Hilbert space-filling curve&lt;&#x2F;h2&gt;
&lt;p&gt;Another non-snowflake…&lt;&#x2F;p&gt;
&lt;p&gt;Until now a &lt;em&gt;turn&lt;&#x2F;em&gt; command was always followed by a &lt;em&gt;forward&lt;&#x2F;em&gt;, which is
required for the accumulate trick. However, to implement the Hilbert
space-filling curve I need separate &lt;em&gt;turns&lt;&#x2F;em&gt; and &lt;em&gt;forwards&lt;&#x2F;em&gt;. I came with
the following idea: use a turn of zero degrees (multiply by 1) to
represent a forward, then you will get duplicate entries in the
directions list, which you can filter out with the following command:
&lt;code&gt;&amp;amp;&#x2F;@Select[Split[],Length[]&amp;gt;1&amp;amp;]&#x2F;&#x2F;Flatten&lt;&#x2F;code&gt;. I then found a
one-replacement-rule variation of the curve using conjugates of lists to
further shorten the code.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{Re[#],Im[#]}&amp;amp;&#x2F;@Accumulate[Select[Split[FoldList[Times,1,Nest[{I&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;,Conjugate[#],1,-I,#,1,#,-I,1,Conjugate[#],I}&amp;amp;,{},5]&#x2F;&#x2F;Flatten]],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Length[#]&amp;gt;1&amp;amp;]&#x2F;&#x2F;Flatten]&#x2F;&#x2F;Line&#x2F;&#x2F;Graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Hilbert.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;peano-gosper-flowsnake&quot;&gt;Peano-Gosper flowsnake&lt;&#x2F;h2&gt;
&lt;p&gt;Finally, the most difficult snowflake! Or &lt;em&gt;flowsnake&lt;&#x2F;em&gt; as it was called
by its inventors. This one involves all the tricks encountered above!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;a=E^(Pi&#x2F;3I);{Re[#],Im[#]}&amp;amp;&#x2F;@Accumulate[#[[2;;]]&amp;amp;&#x2F;@Select[Split[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FoldList[Times,1,Nest[#&#x2F;.{X-&amp;gt;{X,a,Y,1,a,a,Y,1,b,1,X,b,b,1,X,1,X,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;b,Y,1,a},Y-&amp;gt;{b,1,X,a,Y,1,Y,1,a,a,Y,1,a,1,X,b,b,1,X,b,Y}}&amp;amp;,X,4]&#x2F;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{b-&amp;gt;1&#x2F;a,X-&amp;gt;1,Y-&amp;gt;1}&#x2F;&#x2F;Flatten]],Length[#]&amp;gt;1&amp;amp;]&#x2F;&#x2F;Flatten]&#x2F;&#x2F;Line&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;12&#x2F;complex-analysis-l-systems-and-christmas&#x2F;Peano-Gosper.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;I donno… Something about &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Kolmogorov_complexity&quot;&gt;Kolmogorov
complexities&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_fractals_by_Hausdorff_dimension&quot;&gt;Hausdorff
dimensions&lt;&#x2F;a&gt;?&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Million digits of K0!</title>
        <published>2009-12-29T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/million-digits-of-k0/"/>
        <id>https://2π.com/09/million-digits-of-k0/</id>
        
        <content type="html" xml:base="https://2π.com/09/million-digits-of-k0/">&lt;h1 id=&quot;million-digits-of-k0&quot;&gt;Million digits of K0!&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;the-million-digit-round&quot;&gt;The million digit round&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;remco@server&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ~KhinchinK0-1M&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; $&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; time ..khinchin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;How&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; many thousand decimals of K0 would you like today?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Accuracy&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; is&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3322&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; kilobit,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1000&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; thousand decimals.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Calculating&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1660999&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; terms of the summation Σ&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (ζ(2n)-1)n Σ ±1k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Terms&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; need to be&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3322022&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bits accurate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Using&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; von Staudt-Clausen until n =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 120498&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Using&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; only bitshifting from n =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1047982&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Calculating&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; table of small primes…&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 21311&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; primes found.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Power&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; table requires K =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14112&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; items.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Power&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; table requires&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3322037&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bits sum accuracy.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Calculating&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; power table… 100%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 629283&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Approximate&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; size:&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 5723160&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; kB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; required&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 3442520&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; bits of accuracy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Calculating&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; factor =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (4π²)^(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SCN&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)   (&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; SCN!&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Calculating&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; S2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;SCN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; = Σ ±1k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Initialising&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; summation variables…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Summing&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; the von Staudt-Clausen terms… 100%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 144669539.373&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;Summing&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; the powtable terms… 100%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; (in&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 74445950.490&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; ms&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;K0&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; is written to K0.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;real&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    3665m34.260s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;user&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;    3660m33.890s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;sys&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;     4m23.356s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;the-verification-round&quot;&gt;The verification round&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;How&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt; many thousand decimals of K0 would you like today?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;This&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-punctuation z-definition z-string&quot;&gt; might take a few days, but I&amp;#39;ll try.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Accuracy is 3654 kilobit, 1100 thousand decimals.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Calculating 1827099 terms of the summation Σ (ζ(2n)-1)n Σ ±1k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Terms need to be 3654222 bits accurate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Using von Staudt-Clausen until n = 131361&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Using only bitshifting from n = 1152779&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Calculating table of small primes… 23056 primes found.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Power table requires K = 15384 items.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Power table requires 3654237 bits sum accuracy.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Calculating power table… 100% (in 797610 ms)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Approximate size: 6862871 kB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Factor required 3785583 bits of accuracy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Calculating factor = (4π²)^(SCN)   (2 SCN!)…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Calculating S2(SCN) = Σ ±1k&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Initialising summation variables…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Summing the von Staudt-Clausen terms… 100% (in 198981058.192 ms)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;Summing the powtable terms… 100% (in 95374658.929 ms)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;K0 is written to K0.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;real    4923m7.264s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;user    4922m10.648s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-string&quot;&gt;sys     0m0.957s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Simple proof verification system</title>
        <published>2009-12-26T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/12/simple-proof-verification-system/"/>
        <id>https://2π.com/09/12/simple-proof-verification-system/</id>
        
        <content type="html" xml:base="https://2π.com/09/12/simple-proof-verification-system/">&lt;h1 id=&quot;simple-proof-verification-system&quot;&gt;Simple proof verification system&lt;&#x2F;h1&gt;
&lt;p&gt;The incredible &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;metamath.org&#x2F;&quot;&gt;Metamath&lt;&#x2F;a&gt; project contains proofs
from the foundations of logic to ZFC set theory to real numbers to
Hilbert spaces, all in a fascinatingly simple formal proof language.&lt;&#x2F;p&gt;
&lt;p&gt;But Metamath contains a non-intuitive rule when it comes to independent
variables and I want to know if we can do without, so I’m on a mission
to find the simplest &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Automated_proof_checking&quot;&gt;proof verification
system&lt;&#x2F;a&gt; capable
of verifying all of mathematics.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-proof-language&quot;&gt;My proof language&lt;&#x2F;h2&gt;
&lt;p&gt;In my simple proof system theories consist of three parts, hypotheses,
axioms, and applications of other theories. Symbols used in the any of
the statements exist only within the scope of the theory, if you apply a
theory must provide a mapping from its symbols to expressions. This
leads to the following verification algorithm:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create an empty list, &lt;em&gt;T.hypotheses&lt;&#x2F;em&gt;, of hypotheses&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Create an empty list, &lt;em&gt;T.theorems&lt;&#x2F;em&gt;, of true statements&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Add all the hypotheses to &lt;em&gt;T.hypotheses&lt;&#x2F;em&gt; and &lt;em&gt;T.theorems&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Add all the axioms to &lt;em&gt;T.theorems&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For all applied theories &lt;em&gt;G&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;a.  Read the mapping from &lt;em&gt;G&lt;&#x2F;em&gt; statements to &lt;em&gt;T&lt;&#x2F;em&gt; statements&lt;&#x2F;p&gt;
&lt;p&gt;b.  For all statements in &lt;em&gt;G.hypotheses&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;i.  Translate to a *T* statement using the mapping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ii. Verify that the statement is in *T.theorems*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;c.  For all statements in &lt;em&gt;G.theorems&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;i.  Translate to a *T* statement using the mapping&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ii. Add the statement to *T.theorems*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Symbol  Meaning&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;code&gt;T&lt;&#x2F;code&gt;     Start of theory, followed by the theory’s name
&lt;code&gt;∧&lt;&#x2F;code&gt;     Marks a hypothesis
&lt;code&gt;⊨&lt;&#x2F;code&gt;     Marks an axiom
&lt;code&gt;∵&lt;&#x2F;code&gt;     Apply theory &lt;em&gt;name&lt;&#x2F;em&gt;
&lt;code&gt;⊧&lt;&#x2F;code&gt;     &lt;code&gt;a ⊧ b&lt;&#x2F;code&gt; means expression &lt;code&gt;b&lt;&#x2F;code&gt; substitutes &lt;code&gt;a&lt;&#x2F;code&gt;
&lt;code&gt;∴&lt;&#x2F;code&gt;     The following should now be proved (for debugging purposes)
&lt;code&gt;∎&lt;&#x2F;code&gt;     End of theory&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;Here is the implementation in C++:
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;wp-content&#x2F;uploads&#x2F;2009&#x2F;12&#x2F;Proof.cpp&quot;&gt;Proof.cpp&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Rant&lt;&#x2F;em&gt;: I once again found that
C&lt;code&gt; sucks at string operations and the Unicode support is ridiculous. The Boost libraries fix a few of these issues at the cost of really slow compilation time and incomprehensible documentation and error messages, courtesy of the template system abuse that has become a standard in C&lt;&#x2F;code&gt;.
I’m sceptical about C++x0 improving this situation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;well-formedness-of-propositional-calculus&quot;&gt;Well-formedness of propositional calculus&lt;&#x2F;h2&gt;
&lt;p&gt;I can now define a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Propositional_logic&quot;&gt;propositional logic
calculus&lt;&#x2F;a&gt;. To make
things easier I use
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Jan_%C5%81ukasiewicz&quot;&gt;Łukasiewicz&lt;&#x2F;a&gt;&#x27;s &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Polish_notation#Polish_notation_for_logic&quot;&gt;polish
notation&lt;&#x2F;a&gt;.
In this notation &quot;N &lt;em&gt;a&lt;&#x2F;em&gt;&quot; means &quot;not &lt;em&gt;a&lt;&#x2F;em&gt;&quot; or &quot;¬&lt;em&gt;a&lt;&#x2F;em&gt;&quot; and &quot;C &lt;em&gt;a&lt;&#x2F;em&gt; &lt;em&gt;b&lt;&#x2F;em&gt;&quot; means
&quot;from &lt;em&gt;a&lt;&#x2F;em&gt; follows &lt;em&gt;b&lt;&#x2F;em&gt;&quot; or &quot;&lt;em&gt;a&lt;&#x2F;em&gt; → &lt;em&gt;b&lt;&#x2F;em&gt;&quot;. There is no &quot;and&quot;, &quot;or&quot;, etc.
since they can all be defined in terms of N and C.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Well-formedness of Negation&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ Wff N a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ Wff C a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;inference-rules-axiomification&quot;&gt;Inference rules axiomification&lt;&#x2F;h2&gt;
&lt;p&gt;Now that I have the notation down and defined what well-formed formulas
are I can state the axioms. The axiomatic system I chose is the same as
that used by Metamath (see &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;us.metamath.org&#x2F;mpegif&#x2F;mmset.html&quot;&gt;this page&lt;&#x2F;a&gt; ). It’s
one of the shortest to define, but the axioms are far from intuitive.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Modus Ponens&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ C a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Principle of simplification&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ C b a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ Wff C a C b a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ C a C b a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Principle of transposition&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Negation&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                N ⊧ N&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Negation&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                N ⊧ N&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ N a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ N b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ C N a N b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ C b a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ C C N a N b C b a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Frege&amp;#39;s axiom&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ C b c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ C a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ C a c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ C a C b c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ C C a b C a c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ C C a C b c C C a b C a c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;two-proofs&quot;&gt;Two proofs&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Inference introduction&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Principle of simplification&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Modus Ponens&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ C b a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ C b a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Principle of syllogism&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ Wff c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ C a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ C b c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Well-formedness of Implication&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Inference introduction&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ C b c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Frege&amp;#39;s axiom&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                c ⊧ c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Modus Ponens&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ C a C b c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ C C a b C a c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Modus Ponens&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                Wff ⊧ Wff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ C&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ C a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ C a c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ C a c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;introduction-to-propositional-logic&quot;&gt;Introduction to propositional logic:&lt;&#x2F;h2&gt;
&lt;p&gt;In a propositional theory an expression is either Gibberish, Fickle,
Bullshit or True. Here’s how it works:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Gibberish&lt;&#x2F;em&gt;: Any statement that can’t be proved well-formed &lt;em&gt;Example:&lt;&#x2F;em&gt; 3
3 + = &#x2F; &lt;em&gt;What to do with it:&lt;&#x2F;em&gt; Ignore it, it is meaningless.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Fickle&lt;&#x2F;em&gt;: A well-formed statement that is neither True nor Bullshit
&lt;em&gt;Example:&lt;&#x2F;em&gt; See &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_statements_undecidable_in_ZFC&quot;&gt;this
list&lt;&#x2F;a&gt;,
there are no easy examples. &lt;em&gt;What to do with it:&lt;&#x2F;em&gt; Consider adding it or
its negation as an axiom to your theory, or ignore it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Bullshit&lt;&#x2F;em&gt;: A well-formed statement of which the negation can be proved
&lt;em&gt;Example:&lt;&#x2F;em&gt; 3 + 3 = 5 &lt;em&gt;What to do with it:&lt;&#x2F;em&gt; Consider its negation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;True&lt;&#x2F;em&gt;: A well-formed statement that can be proved &lt;em&gt;Example:&lt;&#x2F;em&gt; 3 + 3 = 6
&lt;em&gt;What to do with it:&lt;&#x2F;em&gt; Cherish it as discovered knowledge about your
theory.&lt;&#x2F;p&gt;
&lt;p&gt;Why this theorem verifier is bad:&lt;&#x2F;p&gt;
&lt;p&gt;A good proof verifier should accept proofs for all True statements and
not allow proofs for Bullshit. However, the proof verifier I described
apove accepts the following proof for an obvious Bullshit statement:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Implication introduction&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ C a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Simplification&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ K a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ⊨ b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;T &amp;#39;Bullshit&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Implication introduction&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                C ⊧ K&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ N a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∵ &amp;#39;Simplification&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                K ⊧ K&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                a ⊧ N a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                b ⊧ a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ∴ N a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;∎&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The cause is obvious, it is the &quot;C ⊧ K&quot; line. But how do we prevent such
fallacies from being accepted? My guess is that some of the variables
&quot;Wff C K N&quot; (i.e. the operators) need a more permanent existence, beyond
a single theory. But can this be done without introducing a lot of
complication?&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Make a global list of &quot;predefined&#x2F;constant&quot; symbols? The operators
obviously play a different role than the (variable) statements&#x2F;wff
they operate on. They say something&#x2F;give a relation about the
following wff’s, so they are metasymbols ;)&lt;&#x2F;p&gt;
&lt;p&gt;— Sander&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Source of error in K₀ calculation found</title>
        <published>2009-12-13T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/12/source-of-error-in-k0-calculation-found/"/>
        <id>https://2π.com/09/12/source-of-error-in-k0-calculation-found/</id>
        
        <content type="html" xml:base="https://2π.com/09/12/source-of-error-in-k0-calculation-found/">&lt;h1 id=&quot;source-of-error-in-k0-calculation-found&quot;&gt;Source of error in K₀ calculation found&lt;&#x2F;h1&gt;
&lt;p&gt;The Staudt-Clausen theorem requires a conversion factor between the
ζ-function and the Bernoulli numbers such that&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\zeta(2n) = f_n \left\vert B_{2n} \right\vert
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_n = \frac{\left( 2 \pi \right)^{2n}}{2 (2n)!}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since the exponentiation and factorial calculation is pretty demanding
at high precision and high &lt;em&gt;n&lt;&#x2F;em&gt; it is done by iteratively updating the
previous value:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_n = \frac{4 \pi^2}{2n (2n - 1)} f_{n-1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Or, in the more recent versions where &lt;em&gt;n&lt;&#x2F;em&gt; is decreasing:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
f_n = \frac{(2n +1) (2n + 2)}{4 \pi^2} f_{n+1}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The implementation was as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; factor *= (2n + 1) * (2n + 2) &#x2F; (2π)²&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;mpfr_div&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; twopi2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; GMP_RNDN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;mpfr_mul_ui&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; GMP_RNDN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where &lt;code&gt;twopi2&lt;&#x2F;code&gt; is set to &lt;span class=&quot;math math-inline&quot;&gt;4 \pi^2&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now, both &lt;code&gt;factor&lt;&#x2F;code&gt; and &lt;code&gt;twopi2&lt;&#x2F;code&gt; are accurate up to B bits, that is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;factor&lt;&#x2F;code&gt; &lt;span class=&quot;math math-inline&quot;&gt;= f_n (1 \pm 2^{-B})&lt;&#x2F;span&gt;
&lt;code&gt;twopi2&lt;&#x2F;code&gt; &lt;span class=&quot;math math-inline&quot;&gt;= 4\pi^2 (1 \pm 2^{-B})&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Such that the product is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
4 \pi^2 f_n (1 \pm 2^{-B})^2 = 4 \pi^2 f_n (1 \pm 2^{-B+1})
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So we lost one bit of accuracy! To compensate for this, I add N extra
bits to the accuracy of &lt;code&gt;factor&lt;&#x2F;code&gt; and &lt;code&gt;twopi2&lt;&#x2F;code&gt;, where N is the number of
iterations required. This is in fact a bit of overkill, since &lt;code&gt;twopi2&lt;&#x2F;code&gt;
stays B bits accurate and the above derivation assumed &lt;code&gt;factor&lt;&#x2F;code&gt; and
&lt;code&gt;twopi2&lt;&#x2F;code&gt; to have the same error.&lt;&#x2F;p&gt;
&lt;p&gt;The program was then tested with several different parameters and run at
1, 10, 100, 300 and 500 thousand digits of accuracy to verify that the
bug is now completely gone.&lt;&#x2F;p&gt;
&lt;p&gt;The impact of this change is about a 3% increase in the number of bits
required in &lt;code&gt;factor&lt;&#x2F;code&gt; and &lt;code&gt;twopi2&lt;&#x2F;code&gt;, there was a very slight performance
penalty, but this was easily offset by discovering that I could apply
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.remcobloemen.nl&#x2F;?p=521&quot;&gt;this&lt;&#x2F;a&gt; improvement in a few more
places.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;In conclusion,&lt;&#x2F;strong&gt; my Khinchin calculator is back in the game! At this
moment I’m running two calculations of one million and one point one
million digits on the &lt;a href=&quot;&#x2F;2009&#x2F;10&#x2F;server-on-a-shoestring-budget&quot;&gt;Qubis server&lt;&#x2F;a&gt;.
If all goes well I should have a &lt;em&gt;verified&lt;&#x2F;em&gt; set of one million K₀ digits
before the year is over!&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Check! Minor detail: The last term after the expansion is always
positive ;)&lt;&#x2F;p&gt;
&lt;p&gt;—  Sander Huisman 2009-12-24&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;@SH: I started out with the general case of a number A with a bits
accuracy and a number B with b bits accuracy:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;A(1\pm2^{-a}) \times B(1\pm2^{-b})&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;=AB(1\pm2^{-a}\pm2^{-b}\pm2^{-a-b})&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;2^{-a-b}&lt;&#x2F;span&gt; term is insignificant so can be dropped.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;=AB(1\pm2^{-a}\pm2^{-b})&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In case both number are equally accurate (worst case), then &lt;span class=&quot;math math-inline&quot;&gt;a=b&lt;&#x2F;span&gt; and:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;=AB(1\pm2^{-a}\pm2^{-a})&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;=AB(1\pm2\cdot2^{-a})&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-inline&quot;&gt;=AB(1\pm2^{-a+1})&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So we lost one bit!&lt;&#x2F;p&gt;
&lt;p&gt;PS: With &lt;span class=&quot;math math-inline&quot;&gt;(1\pm2^{-n})&lt;&#x2F;span&gt; I of course mean a number in the range
&lt;span class=&quot;math math-inline&quot;&gt;[1-2^{-n} {,} 1+2^{-n})&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;—  Remco Bloemen 2009-12-24&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;To comment on my own post, this &lt;span class=&quot;math math-inline&quot;&gt;(2*n+1)*(2*n+2)&lt;&#x2F;span&gt; factor is exactly
the reason why the program can’t be used in 32 bits, this number gets
to about 40 bits when you calculate a million digits.&lt;&#x2F;p&gt;
&lt;p&gt;—  Remco Bloemen 2009-12-24&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Looking good! Was this on purpose: &lt;span class=&quot;math math-inline&quot;&gt;(1±2^-B)^2 =&amp;gt; 1±2^(1-b)+2^(-2b) ≈ 1±2^(1-b)&lt;&#x2F;span&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;—  Sander Huisman 2009-12-24&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Monty BuRNS benchmark</title>
        <published>2009-12-07T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/monty-burns-benchmark/"/>
        <id>https://2π.com/09/monty-burns-benchmark/</id>
        
        <content type="html" xml:base="https://2π.com/09/monty-burns-benchmark/">&lt;h1 id=&quot;monty-burns-benchmark&quot;&gt;Monty BuRNS benchmark&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;initialisation&quot;&gt;Initialisation&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;conversion-tofrom-gmp&quot;&gt;Conversion tofrom GMP&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;addition&quot;&gt;Addition&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;equal-size-terms&quot;&gt;Equal size terms&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;machine-size-terms&quot;&gt;Machine size terms&lt;&#x2F;h3&gt;
&lt;h2 id=&quot;multiplication&quot;&gt;Multiplication&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;equal-size-factors&quot;&gt;Equal size factors&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;unequal-size-factors&quot;&gt;Unequal size factors&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;machine-size-factor&quot;&gt;Machine size factor&lt;&#x2F;h3&gt;
&lt;h2 id=&quot;exact-small-division&quot;&gt;Exact small division&lt;&#x2F;h2&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Brent-Pollard ρ factorisation</title>
        <published>2009-12-05T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/12/brent-pollard-rho-factorisation/"/>
        <id>https://2π.com/09/12/brent-pollard-rho-factorisation/</id>
        
        <content type="html" xml:base="https://2π.com/09/12/brent-pollard-rho-factorisation/">&lt;h1 id=&quot;brent-pollard-r-factorisation&quot;&gt;Brent-Pollard ρ factorisation&lt;&#x2F;h1&gt;
&lt;p&gt;In the previous post the Pollard ρ method was by far the fastest of the
methods tested to factor an 64 bit integer. In this post I implement an
improved version by John Pollard and Richard Brent. It is described in
this paper:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wwwmaths.anu.edu.au&#x2F;~brent&#x2F;pd&#x2F;rpb051i.pdf&quot;&gt;Richard P. Brent (1980) – An Improved Monte Carlo Factorization
Algorithm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The straightforward implementation in C++ is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; brent_pollard_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;        const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint64 m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        q &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        do&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64 i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                        &#x2F;&#x2F; y = y² + a mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max_uint64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                uint64 k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                do&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64 i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                                &#x2F;&#x2F; y = y² + a mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                        y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max_uint64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                                &#x2F;&#x2F; q = q |x-y| mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                q &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;, (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;y&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                do&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                        &#x2F;&#x2F; ys = ys² + a mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max_uint64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        ys &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;ys&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The parameter &lt;code&gt;m&lt;&#x2F;code&gt; has been fixed to &lt;code&gt;1000&lt;&#x2F;code&gt;, this seemed to be the
fastest choice.&lt;&#x2F;p&gt;
&lt;p&gt;Given a composite number &lt;code&gt;n&lt;&#x2F;code&gt; it will return a non-trivial factor of &lt;code&gt;n&lt;&#x2F;code&gt;.
To turn this method into a prime factorisation method this factor must
be further split up in factors until the numbers are prime. I develop
the function listed below to do this.&lt;&#x2F;p&gt;
&lt;p&gt;It maintains a stack of possibly composite factors and a list of prime
already discovered. It pops a possible composite from the stack, checks
its primality (with &lt;a href=&quot;&#x2F;09&#x2F;11&#x2F;miller-rabin-primality-test-now-in-64-bit&quot;&gt;this
method&lt;&#x2F;a&gt;). If the
number is prime, it is removed from all the other factors on the stack
and put on the prime list, else, the number is split using either trial
division, if it is small, or &lt;code&gt;brent_pollard_factor&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 factor &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; brent_pollard_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        do&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                uint64 m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;pop_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;is_prime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                        &#x2F;&#x2F; Remove the prime from the other factors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                uint64 k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                                        do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                                k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                                        while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                        factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        factor &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ?&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; small_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; brent_pollard_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;benchmark-and-conclusion&quot;&gt;Benchmark and conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Compared to the methods posted previously, this method can perform the
task in 0.3 s. A tenfold improvement over the previous best and three
thousand times faster than trial division. Also, the time spent in &lt;code&gt;gcd&lt;&#x2F;code&gt;
is less than 20%, much less than the previous 90%.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Integer factorization in 64 bit</title>
        <published>2009-12-05T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/12/integer-factorization-in-64-bit/"/>
        <id>https://2π.com/09/12/integer-factorization-in-64-bit/</id>
        
        <content type="html" xml:base="https://2π.com/09/12/integer-factorization-in-64-bit/">&lt;h1 id=&quot;integer-factorization-in-64-bit&quot;&gt;Integer factorization in 64 bit&lt;&#x2F;h1&gt;
&lt;p&gt;For a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Residue_number_system&quot;&gt;residue number
system&lt;&#x2F;a&gt; I am trying
to implement I need to factor 64 bit integers &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt;. They have the special
for that &lt;span class=&quot;math math-inline&quot;&gt;n+1&lt;&#x2F;span&gt; is a prime number, so they are all divisible by two and
they tend to have other small factors. Here are a few representative
examples:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
18446744073709551556 &amp;amp;= 2^2 \cdot 11 \cdot 137 \cdot 547 \cdot
5594472617641 \\ 18446744073709551532 &amp;amp;= 2^2 \cdot 43 \cdot 67
\cdot 193 \cdot 809383 \cdot 10247197 \\ 18446744073709551520 &amp;amp;=
2^5 \cdot 5 \cdot 2663 \cdot 43294085790719 \\
18446744073709551436 &amp;amp;= 2^2 \cdot 41 \cdot 101 \cdot 4051 \cdot
6199 \cdot 44347651 \\ 18446744073709551426 &amp;amp;= 2 \cdot 3 \cdot 23
\cdot 133672058505141677
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trial-division&quot;&gt;Trial division&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Trial_division&quot;&gt;Trial division&lt;&#x2F;a&gt; is the
simplest method, simply start dividing out numbers from one to
&lt;span class=&quot;math math-inline&quot;&gt;\sqrt{n}&lt;&#x2F;span&gt;. Since you will factor out the primes before any of their
composites the resulting list only contains prime factors. I also tested
a version which used a list of small primes first, before trying all
numbers, but the extra memory bandwidth was worse than the speedup from
having to try less numbers. Here is the source:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Remove the twos&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Remove other factors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;wheel-factorisation&quot;&gt;Wheel factorisation&lt;&#x2F;h2&gt;
&lt;p&gt;In the previous example I took the two out as a special case and skipped
all the odd integers. A generalisation of this trick is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Wheel_factorization&quot;&gt;wheel
factorisation&lt;&#x2F;a&gt;, where
a few small primes are taken out and a skip list is produced of numbers
that must be multiples of those small primes. The end result is a list
of numbers that contains more primes (without missing any!) than plainly
listing all odd integers.&lt;&#x2F;p&gt;
&lt;p&gt;There is a trade off between memory usage by the skip list and small
primes list and the percentage of composites that are skipped. As often
with these memory trade offs, its best to choose the size such that it
fits snugly in the cpu cache. Now that I think about it, I could
probably take 32 bit numbers for the primes and skip list, and fit twice
the amount in the cpu cache.&lt;&#x2F;p&gt;
&lt;p&gt;The small primes are produced using the Sieve of Erastosthenes I
implemented &lt;a href=&quot;&#x2F;09&#x2F;11&#x2F;sieve-of-erastosthenes-in-c-and-stl&quot;&gt;earlier&lt;&#x2F;a&gt;. This
implementation creates the largest possible wheel for a given number of
small primes, which can then be used to factor integers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;struct&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; prime_wheel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        prime_wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; uint64s small_primes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_sieve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; prime_wheel wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;prime_wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;prime_wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 max_size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; -&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        max_size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 211&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; max_size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 previous &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;                bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; include &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; factors&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                include &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;include&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; previous&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                previous &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;size &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; previous &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_factors_wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Remove the twos&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Remove prime wheel factors&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Turn the prime wheel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; j&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;fast_false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                                do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                        n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                                while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; wheel&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;deltas&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;j&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; What&amp;#39;s left must be prime or one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;brent-pollard-rho-factorisation&quot;&gt;Brent-Pollard rho factorisation&lt;&#x2F;h2&gt;
&lt;p&gt;This is John Pollard’s rho factorisation method (see
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pollard_rho&quot;&gt;wikipedia&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;planetmath.org&#x2F;encyclopedia&#x2F;PollardsRhoAlgorithm.html&quot;&gt;planet
math&lt;&#x2F;a&gt;. It
operates by iterating a random function f modulo n. This iteration must
become cyclic sometime since there are only a finite amount numbers
modulo n. The congruence relations resulting from this cycle give us
clues about factors of n.&lt;&#x2F;p&gt;
&lt;p&gt;Richard Brent has made quite a few improvements to this algorithm. The
original algorithm compares &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;x_{2i}&lt;&#x2F;span&gt; to detect a cycle, but I
implemented Brent’s improvement, which compares &lt;span class=&quot;math math-inline&quot;&gt;x_i&lt;&#x2F;span&gt; with &lt;span class=&quot;math math-inline&quot;&gt;x_j&lt;&#x2F;span&gt;, where &lt;span class=&quot;math math-inline&quot;&gt;j&lt;&#x2F;span&gt;
is the first power of two below i. Brent also suggested that one can
multiply a few differences &lt;span class=&quot;math math-inline&quot;&gt;\left\vert x_i - x_j \right\vert&lt;&#x2F;span&gt; modulo
&lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; and compute the gcd of the product and n once in a while. I did not
implement this last suggestion, but I did measure that &amp;gt;90% of the time
is spent computing gcd’s, so this would be an important improvement. I
also did not implement &lt;a href=&quot;&#x2F;09&#x2F;11&#x2F;montgomery-multiplication&quot;&gt;Montogomery reduced
multiplication&lt;&#x2F;a&gt;, which may speed up
the multiplication.&lt;&#x2F;p&gt;
&lt;p&gt;This algorithm will run indefinitely for prime numbers, so these are
checked for on start. There are also some special cases where the cycle
may be very long or where it will not result in a proper factor, so
after a while the algorithm terminates and tries again with a different
random function. I have not thought hard about the best time to
terminate and try again, so this might be sub-optimal.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F; Source: http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Binary_GCD_algorithm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Remove common twos in u and v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shift &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ++&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Remove twos from u&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        do&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; Remove twos in v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; Now u and v are both odd, so diff(u, v) is even.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; Let u = min(u, v), v = diff(u, v)&#x2F;2.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        uint64 diff &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; diff&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;v &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; shift&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;void&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; brents_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-reference z-cpp&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;is_prime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; x = x² + a mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max_uint64 &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                uint64 g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; gcd&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                        brents_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; g&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;                                brents_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        y &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Found no factors, yet n is not a prime, retry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        brents_factor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;benchmark-and-conclusion&quot;&gt;Benchmark and conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;The algorithms are compared by factoring p-1 for the thousand largest 64
bit primes:&lt;&#x2F;p&gt;
&lt;p&gt;Algorithm            Running time&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Trial division              959 s
Wheel factorisation         544 s
Brent-Pollard                 3 s&lt;&#x2F;p&gt;
&lt;p&gt;Clearly the Brent-Pollard method is the way to go, I should implement
the optimisations I suggested and think more thoroughly about the loop
termination.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The million digit attempt</title>
        <published>2009-12-02T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/12/the-million-digit-attempt/"/>
        <id>https://2π.com/09/12/the-million-digit-attempt/</id>
        
        <summary type="html">&lt;h1 id=&quot;the-million-digit-attempt&quot;&gt;The million digit attempt&lt;&#x2F;h1&gt;
&lt;p&gt;This post summarises a few runs that where made to compute many digits
of Khinchin’s constant. We succeeded at repeating the previous record of
a hundred thousand, in much less time, but failed at the million digit
attempt.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Fast Base Extension in Residue Number Systems</title>
        <published>2009-11-30T00:00:00+00:00</published>
        <updated>2014-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/fast-base-extension-in-residue-number-systems/"/>
        <id>https://2π.com/09/11/fast-base-extension-in-residue-number-systems/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/fast-base-extension-in-residue-number-systems/">&lt;h1 id=&quot;fast-base-extension-in-residue-number-systems&quot;&gt;Fast Base Extension in Residue Number Systems&lt;&#x2F;h1&gt;
&lt;p&gt;Residue number systems can make a lot of numerical operations embarrassingly
parallel. But this comes at a cost: there is no parallel division algorithm and
you need to known the size of the result upfront. In this post I&#x27;ll address the
last concern and show a &lt;span class=&quot;math math-inline&quot;&gt;O(n)&lt;&#x2F;span&gt; algorithm to extend the size should you need it.&lt;&#x2F;p&gt;
&lt;p&gt;Given a sequence of prime number &lt;span class=&quot;math math-inline&quot;&gt;m = (m_1, m_2, \dots m_n)&lt;&#x2F;span&gt; and the
product of the prime numbers &lt;span class=&quot;math math-inline&quot;&gt;M = \prod m_i&lt;&#x2F;span&gt; the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Chinese_Remainder_Theorem&quot;&gt;Chinese Remainder
Theorem&lt;&#x2F;a&gt; can be
stated as:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left[ X \right]_M =\left[ \sum_{[1,n]}^i \frac{M}{m_i} \left[X \frac{m_i}{M} \right]_{m_i} \right]_M
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x_i =\left[ X \right]_{m_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X_i =\frac{1}{m_i} \cdot \left[ x_i \cdot \frac{m_i}{M}\right]_{m_i}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left\lfloor2^{64} \cdot X_i\right\rfloor =\left\lfloor \frac{2^{64}}{m_i} \cdot \left[ x_i \cdot \frac{m_i}{M} \right]_{m_i} \right\rfloor
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is easy to proof that &lt;span class=&quot;math math-inline&quot;&gt;0 \leq X_i &amp;lt; 1&lt;&#x2F;span&gt; and that &lt;span class=&quot;math math-inline&quot;&gt;X_i M&lt;&#x2F;span&gt; is a whole
number.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X =\left[ \sum_{[0,N)}^i M \cdot X_i \right]_M
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{X}{M} =\left[ \sum_{[0,N)}^i X_i \right]_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{X}{M} + \frac{M-1}{2M} =\left[ \sum_{[0,N)}^i X_i\right]_1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
W =\left\lfloor \sum_{[0,N)}^i X_i \right\rfloor
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X = \sum_{[0,N)}^i M \cdot X_i - W \cdot M
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left[ X \right]_k = \left[ \sum_{[0,N)}^i M \cdot X_i - W \cdot M \right]_k
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Parity of modular operations</title>
        <published>2009-11-29T00:00:00+00:00</published>
        <updated>2014-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/parity-of-modular-operations/"/>
        <id>https://2π.com/09/11/parity-of-modular-operations/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/parity-of-modular-operations/">&lt;h1 id=&quot;parity-of-modular-operations&quot;&gt;Parity of modular operations&lt;&#x2F;h1&gt;
&lt;!-- ![](ab-mod-17.png) --&gt;
&lt;p&gt;For a problem I am trying to solve I want to find out if I can quickly
calculate the odd&#x2F;even parity of an inverse modulo a large prime. That
is, I want to know:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left( a^{m-2} \mod m \right) \mod 2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Where &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; is typically less than a hundred thousand and &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; is a 64 bit
prime.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;parity-of-modular-multiplication&quot;&gt;Parity of modular multiplication&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s first investigate the related question of the parity of the
modular product:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left( a \cdot b \mod m \right) \mod 2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now, if &lt;span class=&quot;math math-inline&quot;&gt;a&lt;&#x2F;span&gt; or &lt;span class=&quot;math math-inline&quot;&gt;b&lt;&#x2F;span&gt; is zero then the parity will also be zero. The other case
is however more interesting. Lets plot the parity for a few small primes
&lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-3.png&quot; alt=&quot;ab-mod-3&quot; &#x2F;&gt;, &lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-5.png&quot; alt=&quot;ab-mod-5&quot; &#x2F;&gt;,
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-7.png&quot; alt=&quot;ab-mod-7&quot; &#x2F;&gt;, &lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-11.png&quot; alt=&quot;ab-mod-11&quot; &#x2F;&gt;,
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-13.png&quot; alt=&quot;ab-mod-13&quot; &#x2F;&gt;, &lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-17.png&quot; alt=&quot;ab-mod-17&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now a few things can be noticed, first that the whole thing is symmetric
over the diagonal, a consequence of the commutativity of multiplication.
Second, there are two anti-symmetries: the left half is the exact
opposite of the right and the top half is the exact opposite of the
bottom half. This leads to the relation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
&amp;amp;\left(a \cdot b \mod m \right) \\ &amp;amp;\equiv \left( (m - a) \cdot b + 1\mod m \right)\mod 2 \\ &amp;amp;\equiv \left(- a \cdot b + 1 \mod m \right)\mod 2
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The explanation is that a negative number gets subtracted from m, which
is odd, such that the result has its parity flipped.&lt;&#x2F;p&gt;
&lt;p&gt;Another peculiarity in the pattern is that there seems to be some kind
of grid xor-ed with the image. This grid corresponds to a &lt;span class=&quot;math math-inline&quot;&gt;\cdot b \mod
2&lt;&#x2F;span&gt; and can be xored out:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-17-a.png&quot; alt=&quot;ab-mod-17-a&quot; &#x2F;&gt;
&lt;span class=&quot;math math-inline&quot;&gt;\bigoplus&lt;&#x2F;span&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-17-b.png&quot; alt=&quot;ab-mod-17-b&quot; &#x2F;&gt;
&lt;span class=&quot;math math-inline&quot;&gt;=&lt;&#x2F;span&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;ab-mod-17-c.png&quot; alt=&quot;ab-mod-17-c&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The pattern that remains consists of hyperbolas corresponding to the
number of &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;&#x27;s that need to be subtracted to compute the &lt;span class=&quot;math math-inline&quot;&gt;\mod m&lt;&#x2F;span&gt;. Since &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;
is odd each additional subtraction results in a parity flip.&lt;&#x2F;p&gt;
&lt;p&gt;The top left half of the hyperbola pattern appears reasonably well
behaved, the rest appears distorted due to aliasing, but that is not a
problem, since these can be calculated using the anti-symmetries. I
verified that the top-left quarter stays well behaved for a few large
primes &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Unfortunately, I can’t see a faster way to calculate hyperbolas than to
perform an division, so speeding up the multiplication seems to be a
dead end.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;NOTE(2018).&lt;&#x2F;strong&gt; The hyperbola pattern is similar to a Hadamard matrix.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;parity-of-modular-exponentiation&quot;&gt;Parity of modular exponentiation&lt;&#x2F;h2&gt;
&lt;p&gt;Next attempt, maybe some structure emerges in the exponentiation
process. So let’s investigate&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\left( a ^ b \mod m \right) \mod 2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Again, first the small primes:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-3.png&quot; alt=&quot;a-pow-b-mod-3&quot; &#x2F;&gt;,
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-5.png&quot; alt=&quot;a-pow-b-mod-5&quot; &#x2F;&gt;,
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-7.png&quot; alt=&quot;a-pow-b-mod-7&quot; &#x2F;&gt;,
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-11.png&quot; alt=&quot;a-pow-b-mod-11&quot; &#x2F;&gt;,
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-13.png&quot; alt=&quot;a-pow-b-mod-13&quot; &#x2F;&gt;,
&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-17.png&quot; alt=&quot;a-pow-b-mod-17&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It’s seems almost, but not entirely, random, like a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Rule_30&quot;&gt;cellular
automaton&lt;&#x2F;a&gt; or a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;RANDU&quot;&gt;broken pseudo
random generator&lt;&#x2F;a&gt;. Especially the
next-to-last one, &lt;span class=&quot;math math-inline&quot;&gt;a^b \mod 13&lt;&#x2F;span&gt; seems to have a repeating pattern in it.
Investigating some larger primes for &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; I stumbled upon 281, which has
the following pattern:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-281.png&quot; alt=&quot;a-pow-b-mod-281&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There is clearly a grid of white lines going on in this pattern. To
investigate this further I took the discrete cosine transform:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-281-F.png&quot; alt=&quot;a-pow-b-mod-281-F&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A pattern of vertical lines emerges, which means that there should be a
lot of correlation between the columns of the pattern.&lt;&#x2F;p&gt;
&lt;p&gt;Now lets take a prime number that does not have a white line grid, such
as the next number, 283. It’s pattern is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-283.png&quot; alt=&quot;a-pow-b-mod-283&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This pattern does seem completely random, however, when we apply the
cosine transform the vertical lines re-appear, although less pronounced:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;parity-of-modular-operations&#x2F;a-pow-b-mod-283-F.png&quot; alt=&quot;a-pow-b-mod-283-F&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This seems to happen for every prime I try, and I can’t currently
explain where it comes from. It seems that the length of the pattern is
a divisor of &lt;span class=&quot;math math-inline&quot;&gt;\varphi(m)&lt;&#x2F;span&gt; and thus related to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fermats_little_theorem&quot;&gt;Fermat’s little
theorem&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Eulers_theorem&quot;&gt;Euler’s theorem&lt;&#x2F;a&gt;, I should
study this further sometime, but for now it doesn’t seem likely that
this will result in faster computation of modular exponentiation
parities.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;blockquote&gt;
&lt;p&gt;A mathematician, like a painter or poet, is a maker of patterns. If
his patterns are more permanent than theirs, it is because they are
made with ideas.&lt;&#x2F;p&gt;
&lt;p&gt;—G. H. Hardy, A Mathematician’s Apology&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;For now there does not seem to be a simple pattern in the parity of
modular operations that can be exploited.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bignum representations</title>
        <published>2009-11-28T00:00:00+00:00</published>
        <updated>2014-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/bignum-representations/"/>
        <id>https://2π.com/09/11/bignum-representations/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/bignum-representations/">&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\gdef\mod#1{[{#1}]}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;bignum-representations&quot;&gt;Bignum representations&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;montgomery-residue-number-system-monty-burns&quot;&gt;Montgomery Residue Number System (Monty BuRNS)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\mathcal{M} = \left\{ m_i \vert m_i \mathrm{\;is\; prime},\; i
\in [0,N-1] \right\}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\displaystyle M = \prod_{\mathcal{M}}^{m} m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x_i = X\cdot2^{64} \mod m_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
z_i = x_i + y_i \mod m_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
z_i = x_i \cdot y_i \mod m_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
z_i = x_i y_i^{-1} \mod m_i
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;positional-notation&quot;&gt;Positional notation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
X_n = \left\lfloor x b^{-n} \right\rfloor \mod b
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = \sum_{[0,N]}^{n} X_n b^n
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;advantages&quot;&gt;Advantages&lt;&#x2F;h3&gt;
&lt;p&gt;GMP!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;disadvantages&quot;&gt;Disadvantages&lt;&#x2F;h3&gt;
&lt;p&gt;Not easily distributable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;chinese-remainder-theorem&quot;&gt;Chinese remainder theorem&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;advantages-1&quot;&gt;Advantages&lt;&#x2F;h3&gt;
&lt;p&gt;Easy to make distributable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;disadvantages-1&quot;&gt;Disadvantages&lt;&#x2F;h3&gt;
&lt;p&gt;No GMP!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Miller-Rabin primality test (now in 64 bit!)</title>
        <published>2009-11-27T00:00:00+00:00</published>
        <updated>2014-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/miller-rabin-primality-test-now-in-64-bit/"/>
        <id>https://2π.com/09/11/miller-rabin-primality-test-now-in-64-bit/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/miller-rabin-primality-test-now-in-64-bit/">&lt;h1 id=&quot;miller-rabin-primality-test-now-in-64-bit&quot;&gt;Miller-Rabin primality test (now in 64 bit!)&lt;&#x2F;h1&gt;
&lt;p&gt;In the &lt;a href=&quot;&#x2F;09&#x2F;11&#x2F;miller-rabin-primality-test-for-32-bit&quot;&gt;previous post&lt;&#x2F;a&gt; I
showed an implementation of Miller-Rabin that overflowed when the number
was more that 32 bits. In this post I present a way to fix this.&lt;&#x2F;p&gt;
&lt;p&gt;I could remember an instruction I used before, &lt;code&gt;mulq&lt;&#x2F;code&gt; which does 128 bit
multiplication. It multiplies two 64 bit number and stores the least
significant 64 bits in &lt;code&gt;rax&lt;&#x2F;code&gt; and the significant half in &lt;code&gt;rdx&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Now we still need to reduce this number modulo &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt;. Originally I planned
to create a table of &lt;span class=&quot;math math-inline&quot;&gt;2^n\!\!\mod m&lt;&#x2F;span&gt;, use the bits of &lt;code&gt;rdx&lt;&#x2F;code&gt; to add
them and then add &lt;code&gt;rax % m&lt;&#x2F;code&gt;. But after consulting this &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.cs.cmu.edu&#x2F;~fp&#x2F;courses&#x2F;15213-s06&#x2F;misc&#x2F;asm64-handout.pdf&quot;&gt;x86-64
manual&lt;&#x2F;a&gt;
I found out about &lt;code&gt;divq&lt;&#x2F;code&gt;, which takes a 128 bit number stored in
&lt;code&gt;rdx:rax&lt;&#x2F;code&gt;, a 64 bit number &lt;span class=&quot;math math-inline&quot;&gt;m&lt;&#x2F;span&gt; and p	roduces the quotient and remainder.
The whole thing can be coded as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Modular multiplication&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The first factor, a &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The second factor, b &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @return&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The reduced product, a b mod m &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Perform 128 multiplication and division&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; q = ⌊a b &#x2F; m⌋&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; r = a b mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;mulq %3;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;            &amp;quot;divq %4;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;=a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;=d&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should work fast, but I still need to look into &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Montgomery_reduction&quot;&gt;Montgomery
reduction&lt;&#x2F;a&gt;. Perhaps I
should benchmark the two.&lt;&#x2F;p&gt;
&lt;p&gt;Modular exponentiation can now be implemented using &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Exponentiation_by_squaring&quot;&gt;exponentiation by
squaring&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Modular exponentiation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The base, b &amp;lt; m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The exponent&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The reduced power of a, a^b mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        r &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the Miller-Rabin test becomes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Miller-Rabin probabilistic primality testing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number to test for  primality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The witness for primality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; True iff when n is a k-stong pseudoprime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Factor n-1 as d*2^s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Verify x = k^(d 2^i) mod n != 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; pow&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-- &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;                &#x2F;&#x2F; x = x^2 mod n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Together with the prime sieve I created
&lt;a href=&quot;&#x2F;09&#x2F;11&#x2F;sieve-of-erastosthenes-in-c-and-stl.html&quot;&gt;earlier&lt;&#x2F;a&gt; a fast
probablilistic prime checking procedure can be developed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-modifier&quot;&gt;const&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_sieve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;20&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Miller-Rabin probabilistic primality testing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number to test for  primality&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; False when n is not a prime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; is_prime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Handle small primes fast&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;();&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                uint64 p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Do a few Miller-Rabin rounds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;int&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; small_primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Assume prime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This algorithm correctly identifies the first ten primes less than
&lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt;. But then again, so does a single Miller-Rabin round with &lt;span class=&quot;math math-inline&quot;&gt;K= 17&lt;&#x2F;span&gt;.
Perhaps I should implement the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Baillie%E2%80%93PSW_primality_test&quot;&gt;Baillie-PSW&lt;&#x2F;a&gt;
algorithm, there are &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.trnicely.net&#x2F;misc&#x2F;bpsw.html&quot;&gt;rumours&lt;&#x2F;a&gt;
that it has no false positives for 64 bits!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Montgomery multiplication (in 64 bit)</title>
        <published>2009-11-27T00:00:00+00:00</published>
        <updated>2014-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/montgomery-multiplication/"/>
        <id>https://2π.com/09/11/montgomery-multiplication/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/montgomery-multiplication/">&lt;h1 id=&quot;montgomery-multiplication-in-64-bit&quot;&gt;Montgomery multiplication (in 64 bit)&lt;&#x2F;h1&gt;
&lt;p&gt;I looked at the wonderful concept of &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Montgomery_reduction&quot;&gt;Montgomery
reduction&lt;&#x2F;a&gt;. At the
start I didn’t think such a complicated algorithm could be faster than a
single &lt;code&gt;divq&lt;&#x2F;code&gt; instruction. But it was! By more than six times!&lt;&#x2F;p&gt;
&lt;p&gt;To compare the algorithms I contrived a small program
(&lt;a href=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;11&#x2F;montgomery-multiplication&#x2F;mul_monty.cpp&quot;&gt;mul_monty.cpp&lt;&#x2F;a&gt;) to calculate a lot of modular
exponents, which in turn use even more multiplications. This was then
run with no calculation, calculation using &lt;code&gt;divq&lt;&#x2F;code&gt; and calculation with
Montgomery multiplication. All three loops compute the Montogomery
conversion too take that out of the comparison.&lt;&#x2F;p&gt;
&lt;p&gt;Method          Time&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Empty loop    0.37 s
&lt;code&gt;divq&lt;&#x2F;code&gt;       38.02 s
Montgomery    6.19 s&lt;&#x2F;p&gt;
&lt;p&gt;So Montgomery multiplication is about six times faster. Lesson learned:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;&#x2F;strong&gt;:  One instruction can be slower than many lines of code.&lt;&#x2F;p&gt;
&lt;p&gt;Here is how to convert to Monty form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x&amp;#39; = x\; 2^{64} \mod m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Converts from modular to Montgomery reduced form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number in a mod m form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to R = 2⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; a 2⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mod_to_monty&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;mul_asm&lt;&#x2F;code&gt; function is the original &lt;code&gt;divq&lt;&#x2F;code&gt; based multiplication. It
might seem silly to depend on the original method to improve it, but
remember that this conversion only happens sporadically in comparison to
multiplication.&lt;&#x2F;p&gt;
&lt;p&gt;And here is how to convert back to modular form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
x = x&amp;#39;\, 2^{-64} \mod m&amp;lt;
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Converts from Montgomery reduced form to modular&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The number in x = aR mod m  form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to r = 2⁻⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus, must be m &amp;gt; 2⁶³&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; a 2⁻⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; monty_to_mod&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                a &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, what you have been waiting for: the multiplication! The task is to
calculate &lt;span class=&quot;math math-inline&quot;&gt;p = a b \mod m&lt;&#x2F;span&gt; or rather, its Monty form:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
p&amp;#39; = a b 2^{64} \mod m
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The parameters given are:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
a&amp;#39; &amp;amp;= a\, 2^{64} \mod m \\
b&amp;#39; &amp;amp;= b\, 2^{64} \mod m
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The first step is to calculate (with 128 bits)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
t = a&amp;#39; b&amp;#39; = a b\, 2^{128} \mod m^2
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now, if this number is divisible by &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt; the we can simply bit shift
&lt;span class=&quot;math math-inline&quot;&gt;t&lt;&#x2F;span&gt; and return this result as &lt;span class=&quot;math math-inline&quot;&gt;p&amp;#39;&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;g&lt;&#x2F;span&gt; is not a divisible by &lt;span class=&quot;math math-inline&quot;&gt;2^{64}&lt;&#x2F;span&gt; we can make it divisible by adding a
(128 bit) number &lt;span class=&quot;math math-inline&quot;&gt;v&lt;&#x2F;span&gt; to it. The great Montgomery trick is to choose this
number such that &lt;span class=&quot;math math-inline&quot;&gt;v \mod m = 0&lt;&#x2F;span&gt;. It turns out that with:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\begin{aligned}
k &amp;amp;= \left(-m\right)^{-1} \mod 2^{64} \\
u &amp;amp;= t k \mod 2^{64} \\ v &amp;amp;= u m
\end{aligned}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We obtain the number &lt;span class=&quot;math math-inline&quot;&gt;v&lt;&#x2F;span&gt; we want!&lt;&#x2F;p&gt;
&lt;p&gt;Now all that remains is to compute &lt;span class=&quot;math math-inline&quot;&gt;t + v&lt;&#x2F;span&gt; and bit shift this result. And
since we know the least significant bits will be zero with a carry this
can be done using 64 bit arithmetic.&lt;&#x2F;p&gt;
&lt;p&gt;All in all the algorithm can be implemented as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;&#x2F;&#x2F;&#x2F; Multiplication with Montgomery reduction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The first factor in Monty form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The second factor in Monty form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to R = 2⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; r&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to r = 2⁻⁶⁴ mod m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; Fixed to k = (-m)⁻¹ mod 2⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @param&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The modulus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment&quot;&gt;&#x2F;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt; @returns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment&quot;&gt; The product in Monty form: a b 2⁻⁶⁴ mod 2⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; mul_monty&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; th 2⁶⁴ + tl = a b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 th&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;mulq %3&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;=a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;tl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;=d&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;th&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; If t is a multiple of 2⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; then return the quotient&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;tl &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; th&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; u = t n  mod  2⁶⁴&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 u &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tl &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; vh 2⁶⁴ + vl = u m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 vh&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; vl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;        asm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;mulq %3;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;=a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;=d&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vh&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) :&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;a&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;, &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;rm&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; a = vh + th + 1 (take care of overflow)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; vh &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; th &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; th&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                p &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; R&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Miller Rabin primality test (for 32 bit)</title>
        <published>2009-11-25T00:00:00+00:00</published>
        <updated>2014-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/miller-rabin-primality-test-for-32-bit/"/>
        <id>https://2π.com/09/11/miller-rabin-primality-test-for-32-bit/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/miller-rabin-primality-test-for-32-bit/">&lt;h1 id=&quot;miller-rabin-primality-test-for-32-bit&quot;&gt;Miller Rabin primality test (for 32 bit)&lt;&#x2F;h1&gt;
&lt;p&gt;As an exercise I implemented the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Miller%E2%80%93Rabin_primality_test&quot;&gt;Miller-Rabin&lt;&#x2F;a&gt;
primality test in plain C++. It turns out this algorithms lends itself
for a true festival of operators, so I couldn’t resist making the code
very dense:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt; uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        uint64 s&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Factor n-1 as d 2^s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; !&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                d &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; x = k^d mod n using exponentiation by squaring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; The squaring overflows for n &amp;gt;= 2^32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; k &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&amp;gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;e &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;b &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; b&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;        &#x2F;&#x2F; Verify k^(d 2^[0…s-1]) mod n != 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;s&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-- &amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; %&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;x &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;==&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt; false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That’s it! Now, the algorithm will overflow for &lt;span class=&quot;math math-inline&quot;&gt;n \geq 2^{32}&lt;&#x2F;span&gt; but I
intend to use it to find 64-bit primes, so I’ll have to work on that.&lt;&#x2F;p&gt;
&lt;p&gt;Interestingly, the &quot;primes page&quot; claims that
(&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;primes.utm.edu&#x2F;prove&#x2F;prove2_3.html&quot;&gt;source&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;p&gt;If &lt;span class=&quot;math math-inline&quot;&gt;n &amp;lt; 4759123141&lt;&#x2F;span&gt; is a &lt;span class=&quot;math math-inline&quot;&gt;2&lt;&#x2F;span&gt;, &lt;span class=&quot;math math-inline&quot;&gt;7&lt;&#x2F;span&gt; and &lt;span class=&quot;math math-inline&quot;&gt;61&lt;&#x2F;span&gt;-SPRP, then &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is prime.&lt;&#x2F;p&gt;
&lt;p&gt;(A number &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; is called “ &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;-SPRP” or “strong probable-prime base &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt; ”
if it passes Miller Rabin with this &lt;span class=&quot;math math-inline&quot;&gt;k&lt;&#x2F;span&gt;)&lt;&#x2F;p&gt;
&lt;p&gt;Since &lt;span class=&quot;math math-inline&quot;&gt;4759123141&lt;&#x2F;span&gt; is greater that &lt;span class=&quot;math math-inline&quot;&gt;2^{32}&lt;&#x2F;span&gt; we can use this to implement
a fast and &lt;em&gt;exact&lt;&#x2F;em&gt; function to determine whether some 32 bit number is
prime. I special cased the first several primes to improve performance
and made the whole thing into an incomprehensible operator soup, just
like the Miller-Rabin implementation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; isPrime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint32&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;73&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;!&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;11&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;13&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;17&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;19&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;23&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;29&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;31&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;37&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;41&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;43&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;47&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;53&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;59&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;61&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;67&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;71&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;73&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-false&quot;&gt;false&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;        MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;        &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;MillerRabin&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>MPFR is missing a mpfr_ui_div_ui</title>
        <published>2009-11-24T00:00:00+00:00</published>
        <updated>2014-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/mpfr-is-missing-a-mpfr-ui-div-ui/"/>
        <id>https://2π.com/09/11/mpfr-is-missing-a-mpfr-ui-div-ui/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/mpfr-is-missing-a-mpfr-ui-div-ui/">&lt;h1 id=&quot;mpfr-is-missing-a-mpfr-ui-div-ui&quot;&gt;MPFR is missing a &quot;mpfr_ui_div_ui&quot;&lt;&#x2F;h1&gt;
&lt;p&gt;Strangely, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.mpfr.org&#x2F;&quot;&gt;MPFR&lt;&#x2F;a&gt; is lacking a &lt;code&gt;mpfr_ui_div_ui&lt;&#x2F;code&gt;
function, that is, a function that calculates the fraction of two small
unsigned integers to very high accuracy. Until now I’ve been calculating
it like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;mpfr_set_ui&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;invprime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; prime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; GMP_RNDN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;mpfr_ui_div&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;invprime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; invprime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; GMP_RNDN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which is very slow! The reason is probably that the &lt;code&gt;mpfr_ui_div&lt;&#x2F;code&gt; is
calculated using all bits in &lt;code&gt;invprime&lt;&#x2F;code&gt;, even though most of them are
zero. A much faster method is to prepare a two-bit &lt;code&gt;one&lt;&#x2F;code&gt; constant like
this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-support z-type&quot;&gt;mpfr_t&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;mpfr_init2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;mpfr_set_ui&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; GMP_RNDN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and then do this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;mpfr_div_ui&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;invprime&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; one&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;],&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; GMP_RNDN&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sieve of Erastosthenes in C++ and STL</title>
        <published>2009-11-23T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/sieve-of-erastosthenes-in-c-and-stl/"/>
        <id>https://2π.com/09/11/sieve-of-erastosthenes-in-c-and-stl/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/sieve-of-erastosthenes-in-c-and-stl/">&lt;h1 id=&quot;sieve-of-erastosthenes-in-c-and-stl&quot;&gt;Sieve of Erastosthenes in C++ and STL&lt;&#x2F;h1&gt;
&lt;p&gt;The von Staudt-Clausen implementation in one of my previous posts
required a list of small primes. A fast way to calculate them is using
the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sieve_of_Eratosthenes&quot;&gt;Sieve of
Erastosthenes&lt;&#x2F;a&gt;.
Here’s an efficient implementation in C++ and STL:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; prime_sieve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-type&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;bool&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; sieve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        vector&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;reserve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;floor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;boost&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;math&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;expint&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;log&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;        primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64 i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                if&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;sieve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                        continue&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;                for&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;uint64 m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m &lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                        sieve&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;[(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;m&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-true&quot;&gt; true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt;push_back&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; primes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This implementation employs a number of well known tricks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Using a packed bitmap to store the list of numbers. This one is
easy, since &lt;code&gt;vector&amp;lt;bool&amp;gt;&lt;&#x2F;code&gt; is one of the best examples of template
specialization.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Reserving space for the prime list. The &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Logarithmic_integral_function&quot;&gt;logarithmic
integral&lt;&#x2F;a&gt;
function provides a tight upper bound for the number of primes, this
prevents a reallocations. (Well, it’s not always an upper bound, see
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Skewes%E2%80%99_number&quot;&gt;Skewes&#x27; number&lt;&#x2F;a&gt;, but
it is for &lt;span class=&quot;math math-inline&quot;&gt;x &amp;lt; 1.397\!\cdot\!10^{316}&lt;&#x2F;span&gt;, which can not be attained
in 64 bits). This line can be removed to drop the boost dependency.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Skipping all even numbers. The only even prime, two, is special
cased and the loop is run two steps at a time.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;For every prime &lt;span class=&quot;math math-inline&quot;&gt;p&lt;&#x2F;span&gt; only multiples &lt;span class=&quot;math math-inline&quot;&gt;\geq p^2&lt;&#x2F;span&gt; are marked, since the
other numbers have smaller prime factors and are already marked&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The previous trick also ensures that the algorithm stops marking as
soon as the loop reaches &lt;span class=&quot;math math-inline&quot;&gt;\sqrt{\mathrm{max}}&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;There’s no separate prime collecting phase, primes are pushed on the
list as soon as they are found. Don’t know if this is really faster
if you take cache locality into account, but it gives a nice and
short implementation.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you need something faster than this, you could look into the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sieve_of_Atkin&quot;&gt;Sieve
of Atkin&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;cr.yp.to&#x2F;primegen.html&quot;&gt;D. J.
Bernsteins implementation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Web-of-Trust in Axiomatic systems</title>
        <published>2009-11-22T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/web-of-trust-in-axiomatic-systems/"/>
        <id>https://2π.com/09/web-of-trust-in-axiomatic-systems/</id>
        
        <content type="html" xml:base="https://2π.com/09/web-of-trust-in-axiomatic-systems/">&lt;h1 id=&quot;web-of-trust-in-axiomatic-systems&quot;&gt;Web-of-Trust in Axiomatic systems&lt;&#x2F;h1&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Even faster ζ(2n) calculation!</title>
        <published>2009-11-10T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/even-faster-zeta-calculation/even-faster-zeta-calculation/"/>
        <id>https://2π.com/09/11/even-faster-zeta-calculation/even-faster-zeta-calculation/</id>
        
        <summary type="html">&lt;h1 id=&quot;even-faster-z-2n-calculation&quot;&gt;Even faster ζ(2n) calculation!&lt;&#x2F;h1&gt;
&lt;p&gt;In the previous post I benchmarked several algorithms for computing
&lt;span class=&quot;math math-inline&quot;&gt;ζ(2n)&lt;&#x2F;span&gt;. All of them where, at some point, an improvement over the
implementation in mpfr. At very high &lt;span class=&quot;math math-inline&quot;&gt;n&lt;&#x2F;span&gt; nothing seemed to come even
near the series summation with recycled powers method, but this method
is impossibly slow at the start. So we used Harvey’s method to bridge
the gap.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Fast ζ(2n) calculation</title>
        <published>2009-11-06T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/fast-zeta-calculation/fast-zeta-calculation/"/>
        <id>https://2π.com/09/11/fast-zeta-calculation/fast-zeta-calculation/</id>
        
        <summary type="html">&lt;h1 id=&quot;fast-z-2n-calculation&quot;&gt;Fast ζ(2n) calculation&lt;&#x2F;h1&gt;
&lt;p&gt;In this post I will show a few very fast algorithms for computing
consecutive approximations of &lt;span class=&quot;math math-inline&quot;&gt;ζ(2n)&lt;&#x2F;span&gt;, derive my own superior algorithm
for high n and produce a hybrid strategy for generating the zeta series
required to compute Khinchin’s constant.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Efficient calculation of Khinchin&#x27;s constant</title>
        <published>2009-11-05T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/efficient-calculation-of-khinchins-constant/"/>
        <id>https://2π.com/09/11/efficient-calculation-of-khinchins-constant/</id>
        
        <content type="html" xml:base="https://2π.com/09/11/efficient-calculation-of-khinchins-constant/">&lt;h1 id=&quot;efficient-calculation-of-khinchin-s-constant&quot;&gt;Efficient calculation of Khinchin&#x27;s constant&lt;&#x2F;h1&gt;
&lt;p&gt;In the &lt;a href=&quot;&#x2F;09&#x2F;11&#x2F;calculating-khinchins-constant&quot;&gt;previous post&lt;&#x2F;a&gt; we (me,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;twitter.com&#x2F;shuisman&quot;&gt;Sander&lt;&#x2F;a&gt; &amp;amp;
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;blog.phikwadraat.nl&#x2F;&quot;&gt;Sander&lt;&#x2F;a&gt;) set upon ourselves the challenge
to beat Xavier Gour­don’s 1997 record of hundred and ten thousand digits
of Khinchin’s constant. This quickly diverted into a challenge of
calculating the Riemann Zeta function (again, see
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Riemann_zeta_function&quot;&gt;wikipedia&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;mathworld.wolfram.com&#x2F;RiemannZetaFunction.html&quot;&gt;mathworld&lt;&#x2F;a&gt; for
more info).&lt;&#x2F;p&gt;
&lt;!-- --&gt;
&lt;p&gt;Khinchin’s constant, &lt;span class=&quot;math math-inline&quot;&gt;K_0&lt;&#x2F;span&gt; and the Zeta function &lt;span class=&quot;math math-inline&quot;&gt;ζ&lt;&#x2F;span&gt; are related by the
following identity:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\ln K_0 = \frac{1}{\ln{2}} \sum_{[1,\infty]}^{n} \frac{\zeta(2n) -1}{n} \sum_{[1, 2n-1]}^{k} \frac{(-1)^{k+1}}{k}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;analysing-bounds-and-limits&quot;&gt;Analysing bounds and limits&lt;&#x2F;h2&gt;
&lt;p&gt;The inner series is an alternating harmonic series and has the following
limit:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\lim_{n \to \infty} \sum_{[1, 2n-1]}^{k} \frac{(-1)^{k+1}}{k} = \ln{2}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since we are taking two terms at a time this series it is strictly
increasing and &lt;span class=&quot;math math-inline&quot;&gt;\ln{2}&lt;&#x2F;span&gt; is also an upper bound.&lt;&#x2F;p&gt;
&lt;p&gt;An upper bound for &lt;span class=&quot;math math-inline&quot;&gt;ζ&lt;&#x2F;span&gt; can be easily seen from the series definition,
&lt;span class=&quot;math math-inline&quot;&gt;\zeta(2n) - 1 &amp;lt; \frac{2}{2^{2n}}&lt;&#x2F;span&gt;. Combing these results gives an
upper bound for the terms in the outer series:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\frac{\zeta(2n) -1}{n} \sum_{[1, 2n-1]}^{k} \frac{(-1)^{k+1}}{k} &amp;lt; \frac{\ln{4}}{n 4^n}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This expression also allows us to calculate an upper bound for the
cutoff error, i.e. the error we introduce by not summing to &lt;span class=&quot;math math-inline&quot;&gt;n=\infty&lt;&#x2F;span&gt;
but stopping at &lt;span class=&quot;math math-inline&quot;&gt;n=N&lt;&#x2F;span&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
\sum_{[N, \infty]} \frac{\ln{4}}{n 4^n} &amp;lt; \ln{4} \sum_{[N,
\infty]} \frac{1}{4^n} = \frac{\ln{16}}{3 \cdot 4^N}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If we now take the binary logarithm of this number we know how many
fractional bits we get &lt;em&gt;at least&lt;&#x2F;em&gt; correct when summing up to &lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt;. In fact,
since &lt;span class=&quot;math math-inline&quot;&gt;\ln{2} \ln K_0 \approx 1&lt;&#x2F;span&gt;, we know the total number of bits we
get correct:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
-\log_2 \left( \frac{\ln{16}}{3 \cdot 4^N} \right) = 2 N + \log_2 3 - \log_2 \ln{16}
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Or, put differently, to obtain &lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt; bits of &lt;span class=&quot;math math-inline&quot;&gt;K_0&lt;&#x2F;span&gt; we must sum up to (but not
including):&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
N =\frac{1}{2}\left(B - \log_2 3 + \log_2 \ln{16}\right) &amp;lt; \left\lceil\frac{B}{2}\right\rceil + 1
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The uncertainty of the sum is the sum of the uncertainties of the terms.
So if we need an accuracy of &lt;span class=&quot;math math-inline&quot;&gt;2^{-B}&lt;&#x2F;span&gt; for the sum, we can divide this
accuracy evenly over the terms, giving each an accuracy of &lt;span class=&quot;math math-inline&quot;&gt;\frac{1}{N}&lt;&#x2F;span&gt;
&lt;span class=&quot;math math-inline&quot;&gt;2^{-B}&lt;&#x2F;span&gt;. So the precision (in bits) of the terms is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
B_{term} = \left\lceil B + \log_2 N \right\rceil
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;span class=&quot;math math-inline&quot;&gt;ζ&lt;&#x2F;span&gt; can be less accurate, since it will be multiplied by &lt;span class=&quot;math math-inline&quot;&gt;\ln 2 &amp;lt; 1&lt;&#x2F;span&gt;
and divided by n, this amounts to an required accuracy of:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
B_{zeta}(n) = \left\lceil B_{term} - \log_2 n -\log_2 \ln{2} \right\rceil
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-million-digit-goal&quot;&gt;The million digit goal&lt;&#x2F;h2&gt;
&lt;p&gt;To calculate &lt;span class=&quot;math math-inline&quot;&gt;K_0&lt;&#x2F;span&gt; accurate up to a million digits we require the
following:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Parameter&lt;&#x2F;th&gt;&lt;th&gt;value&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;B&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;3 321 929&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;N&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;1 666 966&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;B_{term}&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;3 321 950&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class=&quot;math math-inline&quot;&gt;B_{zeta}(n)&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;td&gt;3 321 951 … 3 321 930&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The problem can now be restated as: &lt;strong&gt;How does one calculate &lt;span class=&quot;math math-inline&quot;&gt;ζ(2) …
ζ(2N)&lt;&#x2F;span&gt; fast and accurate up to &lt;span class=&quot;math math-inline&quot;&gt;B_{zeta}(n)&lt;&#x2F;span&gt; bits?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Calculating Khinchin&#x27;s constant</title>
        <published>2009-11-01T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/11/calculating-khinchins-constant/"/>
        <id>https://2π.com/09/11/calculating-khinchins-constant/</id>
        
        <summary type="html">&lt;h1 id=&quot;calculating-khinchin-s-constant&quot;&gt;Calculating Khinchin&#x27;s constant&lt;&#x2F;h1&gt;
&lt;p&gt;Today I and two friends decided that Xavier Gourdon’s 1997 result of 110
000 digits of Khinchin’s constant, &lt;span class=&quot;math math-inline&quot;&gt;K_0&lt;&#x2F;span&gt; could be improved. Khinchin’s
constant is the result of an interesting theorem on the properties of
continued fraction expansion, you can read more about &lt;span class=&quot;math math-inline&quot;&gt;K_0&lt;&#x2F;span&gt; on the usual
sources, &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Khinchin%E2%80%99s_constant&quot;&gt;wikipedia&lt;&#x2F;a&gt;
and &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;mathworld.wolfram.com&#x2F;KhinchinsConstant.html&quot;&gt;mathworld&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;</summary>
        
    </entry>
    <entry xml:lang="en">
        <title>Crossover design and simulation</title>
        <published>2009-10-25T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/crossover-design-and-simulation/"/>
        <id>https://2π.com/09/crossover-design-and-simulation/</id>
        
        <content type="html" xml:base="https://2π.com/09/crossover-design-and-simulation/">&lt;h1 id=&quot;crossover-design-and-simulation&quot;&gt;Crossover design and simulation&lt;&#x2F;h1&gt;
&lt;p&gt;A friend asked me to design a crossover for his new speakers. I have
done this before for my own speakers, which turned out beautifully. I
did this using a MatlabOctave simulation of the entire system of
filters &lt;em&gt;and&lt;&#x2F;em&gt; speakers. Unfortunatly, I lost this simulation, so join me
in recreating it!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;speaker-drivers&quot;&gt;Speaker drivers&lt;&#x2F;h2&gt;
&lt;p&gt;Woofer: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;www.eminence-speaker.comproaudio_speaker_detail.asp?web_detail_link=KAPPA-12A&amp;amp;speaker_size=12&amp;amp;SUB_CAT_ID=2&quot;&gt;Eminence Kappa
12&lt;&#x2F;a&gt;
Rms power handling: 450 W, Sensitivity: 99.3 dB Frequency range: 62 Hz –
4.2 kHz&lt;&#x2F;p&gt;
&lt;p&gt;Tweeter: &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;www.monacor.detypo3index.php?id=84&amp;amp;L=1&amp;amp;artid=3309&amp;amp;spr=EN&amp;amp;typ=full&quot;&gt;Monacor
MHD-240&lt;&#x2F;a&gt;
Rms power handling: 40 W Sensitivity: 107 dB Frequency range: 1.5 kHz –
20 kHz&lt;&#x2F;p&gt;
&lt;h2 id=&quot;filter-design&quot;&gt;Filter design&lt;&#x2F;h2&gt;
&lt;p&gt;Using an &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;www.diyaudioandvideo.comCalculatorXOver&quot;&gt;online filter
generator&lt;&#x2F;a&gt; I got
initial values of C = 5.68 µF and L = 0.36 mH for a first order
Butterworth at 3.5 kHz.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;200910251259_123.jpg&quot; alt=&quot;Filter circuit schema&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The response of this filter is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;first-filter-gain.png&quot; alt=&quot;Butterworth crossover gain&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Looks good doesn’t it? The crossover point is nicely at 3.5 kHz and
there is the typical +3 dB hump of a Butterworth crossover with coherent
speakers, which is very smooth and should pose a problem. Unfortunately,
the graph represents voltages on the terminals, not sound pressures in
the room and this is where things get complicated. Brace yourself for a
quest to simulate how these speakers would actually sound!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sensitivity&quot;&gt;Sensitivity&lt;&#x2F;h2&gt;
&lt;p&gt;One parameter I have not yet used is the sensitivity. This number
represents how efficiently the speaker converts energy into sound and is
measured as the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.orgwikiSound_pressure_level&quot;&gt;sound pressure
level&lt;&#x2F;a&gt; of the speaker
at one meter distance when supplied with a signal of 2.83 V_{RMS}.&lt;&#x2F;p&gt;
&lt;p&gt;This means that a signal of 2.83 V_{RMS} in the woofer will produce a
sound level of 99.3 dB whereas the tweeter would produce a loud 107 dB.
If I take this difference into account the speakers would sound more
like:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;sensitivity-response.png&quot; alt=&quot;Sensitivity response&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is of course unacceptable, the treble is much to loud! Luckily,
this can be fixed by putting a resistor in series with the tweeter to
dampen it a bit. A value of 11 Ω in series with the 8 Ω tweeters should
drop it by about 8 dB. Simulating this results in:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;sensitivity-corrected-response.png&quot; alt=&quot;Sensitivity corrected response&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Aaarggh! The crossover point has shifted to 2 kHz and the hump has
increased to 5 dB! The high-pass hasn’t shifted down 7dB as I had hoped,
instead it just got flatter and shifted left a bit (compare the graphs).
The explanation is that the resistor interacts with the filter and
changes it’s properties. Clearly the naive use-values-from-a-website
approach does not work for crossovers. Let’s go all in and take as much
into account as we can.&lt;&#x2F;p&gt;
&lt;p&gt;First, the amplifier. This is easy since audio amplifiers are almost
perfect voltage sources, their internal resistance can be ignored, even
when they are connected to demanding 4 Ω loads. The impedance of the
cables from the amplifier to the speakers will also be ignored, I just
can’t see how it would significant enough to produce and audible effect.
That said, there are so-called audiophiles that demand nothing less than
tube amplifiers (which audibly distort the sound in a pleasant way) and
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;www.analysis-plus.comprod_goldcable.html&quot;&gt;golden cables&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The next thing connected directly to the cables is my filter, which I
simulate in full detail. Connected to the filter are the speakers. They
can be simulated using their
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.orgwikiThieleSmall&quot;&gt;ThieleSmall&lt;&#x2F;a&gt; parameters,
but this is only accurate at low frequencies.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;simulating-with-spl-and-impedance-curves&quot;&gt;Simulating with SPL and impedance curves&lt;&#x2F;h2&gt;
&lt;p&gt;To accurately simulate the response of the speaker drivers I use the SPL
curves, this can be seen as sensitivity measured for each frequency (the
sensitivity varies enormously with frequency, the stated sensitivity is
some average over the &quot;usable range&quot;). The SPL curves for any good
speakers can be found on the manufacturers site, for the given drivers
they are:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;woofer.png&quot; alt=&quot;SPL and impedance curve for the woofer&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;tweeter.png&quot; alt=&quot;SPL and impedance curve for the tweeter&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The second curve on the graphs is the impedance, it shows how the
resistance of the speaker changes with the frequency. The stated 8 Ω is
a roughly the minimal resistance in the usable range. Eminence seems to
cheat a bit by going as low as 6 Ω, this could in theory harm an
amplifier designed for 8 Ω, but pro audio amplifiers are very rugged, so
don’t worry.&lt;&#x2F;p&gt;
&lt;p&gt;I digitized these curves using
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;digitizer.sourceforge.net&quot;&gt;Engauge&lt;&#x2F;a&gt;. This gives me a nice set
of numbers to calculate with in
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;www.gnu.orgsoftwareoctave&quot;&gt;Octave&lt;&#x2F;a&gt; (using the
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;qtoctave.wordpress.comwhat-is-qtoctave&quot;&gt;QtOctave&lt;&#x2F;a&gt; GUI).&lt;&#x2F;p&gt;
&lt;p&gt;I then redeveloped the simulation I made and lost half a year ago, the
source is at the end of this post. The result of the simulation for the
filter with C = 5.68 µF, L = 0.36 mH and R = 11 Ω is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;SPL-impedance-response.png&quot; alt=&quot;Simulated SPL response&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Wow! What a mess! Clearly the SPL and speaker impedance have a large
effect on the filter. It almost looks as if the woofer has no filter at
all! Let’s look at the voltages across the terminals and just take the
stated sensitivities instead of the full SPL curves:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;Simulated-filter-response.png&quot; alt=&quot;Simulated filter response&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now things become clearer, the woofers low pass has shifted a few
octaves to the right, just like the the tweeters high pass shifted left
when I added the resistor. This filter needs a &lt;em&gt;lot&lt;&#x2F;em&gt; of tuning.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tuning-the-filter&quot;&gt;Tuning the filter&lt;&#x2F;h2&gt;
&lt;p&gt;I tuned the filter by trying out various value of the components,
sticking to the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.orgwikiPreferred_numbers&quot;&gt;preferred
numbers&lt;&#x2F;a&gt; from the E12
series. The advantage of these numbers is that they are easy to tune
with and components with these values are readily available.&lt;&#x2F;p&gt;
&lt;p&gt;After some heavy tuning, a filter with C = 1.0 µF, L = 1.5 mH and R = 12
Ω gives the flattest response:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;crossover-design-and-simulation&#x2F;Fine-tuned-response.png&quot; alt=&quot;Fine tuned response&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But the response is still not very good, if I increase L to dampen the
woofers hump at 2.3 kHz it also shifts much of the mid range down. Maybe
I should design a second order filter, the higher slope would allow me
to tune the hump more precisely.&lt;&#x2F;p&gt;
&lt;p&gt;Furthermore, there are a lot of things not taken into account which are
relevant; the enclosure response, the phase response of everything, the
ThieleSmall parameters, speaker alignment, off-axis response, etc. The
version I lost also calculated the phase of the filter and the power
dissipation in the resistor and drivers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;source&quot;&gt;Source&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% Simple crossover filters for speakers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% Author: Remco Bloemen, 2009&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;clear;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% Filter components&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;C = 1.0E-6 ; % Farad&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;R = 12; % Ohm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;L = 1.5E-3; % Henry&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% Create a frequency space&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;N = 100;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;f = logspace(log10(40), log10(22e3), N);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;omega = 2 * pi * f;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% Load the SPL and impedance curves&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;load &amp;#39;S_tweeter.csv&amp;#39;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;S_tweeter = interp1(S_tweeter(:,1), S_tweeter(:,2), f);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;load &amp;#39;S_woofer.csv&amp;#39;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;S_woofer = interp1(S_woofer(:,1), S_woofer(:,2), f);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;load &amp;#39;R_tweeter.csv&amp;#39;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;R_tweeter = interp1(R_tweeter(:,1), R_tweeter(:,2), f);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;load &amp;#39;R_woofer.csv&amp;#39;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;R_woofer = interp1(R_woofer(:,1), R_woofer(:,2), f);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% Calculate the circuit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;U_in = 2.83 * ones(1, N);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Z_C = 1 . (i * omega * C);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Z_R = R * ones(1, N);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Z_L = i * omega * L;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;I_tweeter = U_in . (Z_R + R_tweeter + Z_C);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;I_woofer = U_in . (R_woofer + Z_L);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;U_tweeter = abs(I_tweeter .* R_tweeter);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;U_woofer = abs(I_woofer .* R_woofer);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% Calculate the SPL curves, add coherently&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spl_tweeter = S_tweeter + 20 * log10(U_tweeter . 2.83);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spl_woofer = S_woofer + 20 * log10(U_woofer . 2.83);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;spl = 20 * log10(10.^(spl_tweeter  20) + 10.^(spl_woofer  20));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;figure; hold on;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;title(&amp;#39;Fine-tuned response&amp;#39;);xlabel(&amp;#39;Frequency [Hz]&amp;#39;); ylabel(&amp;#39;Sound pressure level [dB re]&amp;#39;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grid on; xlim([40, 22e3]); ylim([80, 110]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;set(gca, &amp;#39;XTick&amp;#39;, [40,60,80,100,150,200,300,400,600,800,1000,1500,2000,3000,4000,6000,8000,1e4,15e3,2e4]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;semilogx(f, spl_tweeter,&amp;#39;r&amp;#39;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;semilogx(f, spl_woofer,&amp;#39;b&amp;#39;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;semilogx(f, spl, &amp;#39;linewidth&amp;#39;, 2, &amp;#39;color&amp;#39;, [0,0,0]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Nice tutorial! You have used some new programs too. I’ll check them
out. To reduce the bump in the middle: have you tried switching + and&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;of the tweeter?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;—  Fred van Dam 2010-03-18&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Thanks! Switching the + and - would be equivalent to a 180 degree
phase shift. Now, if the tweeter and woofer are completely in phase,
you can just add the amplitudes, if they are 180 degree out of phase,
you need to subtract them.&lt;&#x2F;p&gt;
&lt;p&gt;The problem is, in real life, the phase difference also depends on the
physical distance between the drivers, which in turn depends on your
cabinet design, your listening position and the frequency. At 3 kHz it
takes only 5 centimetres of difference for a 180 degree phase shift.&lt;&#x2F;p&gt;
&lt;p&gt;So in this case (I didn’t have the cabinet design) I have completely
no knowledge about the phase relation between the tweeter and the
woofer. It’s been a while, but I believe I treated them as
uncorrelated signals (i.e. no-phase relation). I think this is a
reasonable assumption, considering that these are party speakers, to
be listened from various positions.&lt;&#x2F;p&gt;
&lt;p&gt;—  Remco Bloemen 2010-03-18&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Radio Remco (using a Racal-Dana 9084)</title>
        <published>2009-10-19T00:00:00+00:00</published>
        <updated>2014-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/radio-remco/"/>
        <id>https://2π.com/09/radio-remco/</id>
        
        <content type="html" xml:base="https://2π.com/09/radio-remco/">&lt;h1 id=&quot;radio-remco-using-a-racal-dana-9084&quot;&gt;Radio Remco (using a Racal-Dana 9084)&lt;&#x2F;h1&gt;
&lt;p&gt;Today at the university they were cleaning out some of the old equipment
that had been laying on shelves for years. Someone tipped me that the
Racal-Dana 9084 Synthesised Signal Generator was a particularly
interesting piece of equipment, so I tied it to my bicycle and rode
home.&lt;&#x2F;p&gt;
&lt;p&gt;To my surprise the generator worked immediately on connecting it to
mains and switching it on. I quickly hooked up a scope to play with it.
I even measured if the reference signal generator was accurate, since
the last time it was calibrated (according to the sticker) was before I
was born. It was exactly 1.000 MHz, so well within the accuracy of my
scope.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;radio-remco&#x2F;200910191835_103.jpg&quot; alt=&quot;Racal-Dana 9084 on 94 MHz FM&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rigging-a-fm-radio-transmitter&quot;&gt;Rigging a FM radio transmitter&lt;&#x2F;h2&gt;
&lt;p&gt;Since the generator has an AM and FM modulator and could cover the AM
radio band and much of the FM radio band it seemed natural to try this
out. Sticking a wire of about half a meter in the centre of the BNC
outlet as a makeshift antenna. I first tried AM with an internal 1kHz
test-tone signal, which I could somewhat receive on a radio and then
switched to FM at 94 MHz, which worked beautifully.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;radio-remco&#x2F;200910192118_108.jpg&quot; alt=&quot;Jimmy rigged FM radio signal producer&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The next step was to create an audio signal and start broadcasting! I
took some more cables and crocodile connectors and connected the
headphone out to the input of the modulator. Put Banarama – Venus in a
loop (love the baseline at the start of the song) and started
broadcasting. At one point I played a 19 kHz sine through the signal,
which made the FM stereo indicator light up :). Sound quality was very
decent, even though I did not boost the high frequencies as is
apparently the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;en.wikipedia.orgwikiFM_radio&quot;&gt;standard
practice&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I had perfect reception at the neighbours when transmitting at 30 mV.
But even on 1 V there was no reception on a friends radio-enabled
cellphone in his house 900 m from here. Seems quite obvious in
retrospect.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;measuring-peak-output-power&quot;&gt;Measuring peak output power&lt;&#x2F;h2&gt;
&lt;p&gt;Time to measure the peak output of the transmitter. Since the output is
labelled 50 Ω I shorted it with a 56 Ω resistor and measured the root
means squared voltage while increasing the signal strength. The dial
went all the way to 1 V rms. And then I discovered a button labelled
“×2”, pushed it, and the signal shot to 2.16 V rms :D. The signal and
generator appeared completely unimpressed by continuous load, so I
estimate it’ll run the same on 50 Ω. This results in a total power of:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;math math-display&quot;&gt;
P = \frac{U^2}{R} = \frac{2.16^2}{50} = 93 mW
&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Quite nice for a device never meant to be a transmitter of any kind.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;radio-remco&#x2F;200910192126_113.jpg&quot; alt=&quot;10 MHz at full blast&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;2%CF%80.com&#x2F;09&#x2F;radio-remco&#x2F;200910192127_115.jpg&quot; alt=&quot;Improvised power measuring device. Improvised power measuring device: The transmitter is loaded with an 56 Ω resistor and the root mean squared voltage is measured with a scope.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Since my neighbours are about 10 m away and my friend lives 900 m away I
should expect to require 10 &lt;span class=&quot;math math-inline&quot;&gt;\cdot \log_{10} {\frac{900^2}{10^2}} =
39 dB&lt;&#x2F;span&gt; more transmitting power. I was transmitting at 30 mV and could go
up to 2.16 V so I had &lt;span class=&quot;math math-inline&quot;&gt;10 \cdot \log_{10}{\frac{2.16^2}{0.03^2}} =
37 dB&lt;&#x2F;span&gt; of headroom, just &lt;span class=&quot;math math-inline&quot;&gt;2 dB&lt;&#x2F;span&gt; short of reaching my friend!&lt;&#x2F;p&gt;
&lt;p&gt;Surely I must be able to reach my friend if I build a simple bi-pole
antenna.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hi - Nice to read your article, especially as there is a better than
50-50 chance that I tested the unit originally. I worked at Racal from
1977 and was the test department engineer assigned to the project. The
unit was a really good performer at the time, but we felt that it was
a mistake to stop short of the top of the FM broadcast band as an
engineer would be more likely to buy a unit if they could test their
tuner with it!&lt;&#x2F;p&gt;
&lt;p&gt;Hope it keeps going for you,&lt;&#x2F;p&gt;
&lt;p&gt;Bob&lt;&#x2F;p&gt;
&lt;p&gt;—  Bob Miller 2010-04-24&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Hallo Remco, Leuk te lezen over je radio experimenten, al denk ik dat
je ze beter op een andere frequentie en met een machtiging daarvoor
zou kunnen uitvoeren…… :-) Ik heb sinds kort ook een Racal 9084 en ben
op zoek naar de documentatie hiervan. Kun jij me verder helpen?&lt;&#x2F;p&gt;
&lt;p&gt;—  Henry Vredegoor 2011-02-02&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;@Henry: Ik heb er helaas ook geen documentatie bij, wel veel naar
gegoogled. De fabrikant bestaat al een tijdje niet meer, dus support
is moeilijk te krijgen. Maar met wat kennis en proberen is de voorkant
van het apparaat redelijk te begrijpen.&lt;&#x2F;p&gt;
&lt;p&gt;Een zendmachtiging maak ik mij niet zo druk om, dit apparaat heeft
minder vermogen dan een FM-babyfoon en ik zet het apparaat maar heel
kort aan.&lt;&#x2F;p&gt;
&lt;p&gt;—  Remco Bloemen 2011-02-03&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I have one of these sig gen’s it was working wonderfully for a long
time, then one day the freq readout started flashing and the freq is
way off, I guess this means the synth has lost lock. Any idea’s as to
what the problem may be and how to fix it ?&lt;&#x2F;p&gt;
&lt;p&gt;Chris&lt;&#x2F;p&gt;
&lt;p&gt;—  Chris Cain 2011-05-07&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>USB DMX 512 Transceiver</title>
        <published>2009-10-17T00:00:00+00:00</published>
        <updated>2014-03-03T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/10/usb-dmx512-transceiver/"/>
        <id>https://2π.com/09/10/usb-dmx512-transceiver/</id>
        
        <content type="html" xml:base="https://2π.com/09/10/usb-dmx512-transceiver/">&lt;h1 id=&quot;usb-dmx-512-transceiver&quot;&gt;USB DMX 512 Transceiver&lt;&#x2F;h1&gt;
&lt;p&gt;The dimmer pack I build (and will blog about soon) supports &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;DMX512&quot;&gt;DMX
512&lt;&#x2F;a&gt; as a controlling protocol.
However, professional light controlling equipment is &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bax-shop.nl&#x2F;dmx-lichtsturingen&#x2F;bekijk-alle-producten.html&quot;&gt;quite
expensive&lt;&#x2F;a&gt;
and limited in functionality. So I went with the open source solution,
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;qlc&#x2F;&quot;&gt;Q Light Controller&lt;&#x2F;a&gt; (QLC). Now I
only need a way to connect the software to the hardware.&lt;&#x2F;p&gt;
&lt;p&gt;The way to go is with an &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bax-shop.nl&#x2F;dmx-software&#x2F;bekijk-alle-producten.html?DescOrderBy=0&amp;amp;keyword=0&amp;amp;keyword1=0&amp;amp;keyword2=0&amp;amp;orderby=product_price&amp;amp;prijsklasse=0&quot;&gt;USB-DMX
transceiver&lt;&#x2F;a&gt;.
Yet these still cost at least €100, which seems too much for what you
get. After some research I found that most of the cheaper and DIY
transceivers use a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ftdichip.com&#x2F;FTProducts.htm&quot;&gt;FTDI chip&lt;&#x2F;a&gt;.
I just happen to have one of those! It came in &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.voti.nl&#x2F;usb-1&#x2F;n_index.html&quot;&gt;a
kit&lt;&#x2F;a&gt;. Now it was easy to build
the &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.enttec.com&#x2F;index.php?main_menu=Products&amp;amp;pn=70303&amp;amp;show=downloads&quot;&gt;Enttec Open DMX USB
Interface&lt;&#x2F;a&gt;.
All in all less than two hours to build and assemble. And one hour to
debug and discover that the DMX cable I used had a fractured lead.&lt;&#x2F;p&gt;
&lt;p&gt;And yes, I’m well aware that the DMX standard explicitly requires a
five-pin connector. The reason I went for three-pin is because I had
those laying around. In fact, I shopped around for five pins in
Enschede, but it would have cost more than the entire transceiver.&lt;&#x2F;p&gt;
&lt;p&gt;It works wonderfully with the generic FTDI driver distributed with QLC.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Photo’s of the finished transceiver&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO:&lt;&#x2F;strong&gt; These photo&#x27;s must be somewhere.&lt;&#x2F;p&gt;
&lt;p&gt;USB-DMX Top View, Top view of the USB-DMX512 tranceiver.&lt;&#x2F;p&gt;
&lt;p&gt;USB-DMX Front View, View of the USB side.&lt;&#x2F;p&gt;
&lt;p&gt;USB-DMX DMX side., View of the DMX side, showing the non-standard
connector everyone uses.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Semitone Diamond 20 channel dimmer pack</title>
        <published>2009-10-17T00:00:00+00:00</published>
        <updated>2014-03-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/semitone-diamond-20-channel-dimmer-pack/"/>
        <id>https://2π.com/09/semitone-diamond-20-channel-dimmer-pack/</id>
        
        <content type="html" xml:base="https://2π.com/09/semitone-diamond-20-channel-dimmer-pack/">&lt;h1 id=&quot;semitone-diamond-20-channel-dimmer-pack&quot;&gt;Semitone Diamond 20 channel dimmer pack&lt;&#x2F;h1&gt;
&lt;p&gt;I have build a fully functioning &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.engbedded.com&#x2F;semitone&#x2F;diamond&quot;&gt;Semitone
Diamond&lt;&#x2F;a&gt; 20 channel dimmer
pack.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Server on a shoestring budget</title>
        <published>2009-10-15T00:00:00+00:00</published>
        <updated>2009-10-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Remco Bloemen
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://2π.com/09/10/server-on-a-shoestring-budget/"/>
        <id>https://2π.com/09/10/server-on-a-shoestring-budget/</id>
        
        <content type="html" xml:base="https://2π.com/09/10/server-on-a-shoestring-budget/">&lt;h1 id=&quot;server-on-a-shoestring-budget&quot;&gt;Server on a shoestring budget&lt;&#x2F;h1&gt;
&lt;p&gt;This is the story of the first &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.qubis.nl&quot;&gt;Qubis&lt;&#x2F;a&gt; server.
Build on a shoestring budget, yet I’m convinced it’ll out preform most
of the other equipment in its rack. And it looks better! :)&lt;&#x2F;p&gt;
&lt;p&gt;After rigorously going through &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;tweakers.net&#x2F;pricewatch&quot;&gt;tweakers
pricewatch&lt;&#x2F;a&gt; to find the absolute
cheapest components and suppliers the following configuration was
decided:&lt;&#x2F;p&gt;
&lt;p&gt;+--------------------------+--------------------------+--------------------------+
| Component                | Product                  | Price                    |
+==========================+==========================+==========================+
| Case                     | Chieftec 2U Rackmount    | € 156.72                 |
|                          | 360W                     |                          |
+--------------------------+--------------------------+--------------------------+
| Motherboard              | [Asrock                  | € 61.50                  |
|                          | A780FullHD](http:&#x2F;&#x2F;www.a |                          |
|                          | srock.com&#x2F;mb&#x2F;overview.as |                          |
|                          | p?Model=A780FullHD)      |                          |
+--------------------------+--------------------------+--------------------------+
| Processor                | [Amd Phenom II X4        | € 173.53                 |
|                          | 940](http:&#x2F;&#x2F;www.youtube. |                          |
|                          | com&#x2F;watch?v=wB0JodKgZ0A) |                          |
+--------------------------+--------------------------+--------------------------+
| Memory                   | OCZ 4GB DDR2             | € 58.50                  |
+--------------------------+--------------------------+--------------------------+
| Harddisk                 | 3×WD 500GB               | € 158.85                 |
+--------------------------+--------------------------+--------------------------+
| Video card               | ATI RV610                | onboard                  |
+--------------------------+--------------------------+--------------------------+
| Network card             | RTL8168B 1Gb             | onboard                  |
+--------------------------+--------------------------+--------------------------+
| Raid controller          | Linux software raid      | Free                     |
+--------------------------+--------------------------+--------------------------+
| Software                 | [Gentoo                  | Free                     |
|                          | Linux](http:&#x2F;&#x2F;www.gentoo |                          |
|                          | .org&#x2F;)                   |                          |
+--------------------------+--------------------------+--------------------------+
| Hosting                  | [2U 19&quot; 100 Mb&#x2F;s 1       | € 59.– (monthly)         |
|                          | Tb&#x2F;month](https:&#x2F;&#x2F;www.tr |                          |
|                          | ansip.nl&#x2F;pro&#x2F;colocation&#x2F; |                          |
|                          | )                        |                          |
+--------------------------+--------------------------+--------------------------+&lt;&#x2F;p&gt;
&lt;p&gt;That’s how you build a quad core 3.0 GHz server with 4 GB ram and 1 TB
raid-5 for just over € 600.&lt;&#x2F;p&gt;
&lt;p&gt;Now, you may wonder how low-budget consumer components will perform in a
server setting, particularly software raid, onboard network controller
and the non-scsi harddisks. Well, I think most of those doubts are
unfounded, software raid is
&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;jeremy.zawodny.com&#x2F;blog&#x2F;archives&#x2F;008696.html&quot;&gt;safer&lt;&#x2F;a&gt; and
performance is either &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.linux.com&#x2F;news&#x2F;hardware&#x2F;servers&#x2F;8222-benchmarking-hardware-raid-vs-linux-kernel-software-raid&quot;&gt;slightly
less&lt;&#x2F;a&gt;
or &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.chemistry.wustl.edu&#x2F;~gelb&#x2F;castle_raid.html&quot;&gt;slightly
better&lt;&#x2F;a&gt; depending
on your configuration. And this beast has much performance to spare!&lt;&#x2F;p&gt;
&lt;p&gt;Regarding the hardware quality and failure: Instead of very expensive
components such as redundant powers supplies, etc. it is far more
efficient to create redundancy by using multiple servers (scatter around
the globe for good measure). Admittedly, there is currently only one
server, but we don’t depend on it for anything mission critical.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Special touch:.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Spray painted our logo on the front.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Print the outline of the logo unscaled.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Spray glue on back of the paper sheet &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.bison.nl&#x2F;NL&#x2F;nl&#x2F;view.do?UID=af993e0fc2c7dd2dc07c2c&quot;&gt;Bison
lijmspray&lt;&#x2F;a&gt;
will do fine.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Stick the sheet to the surface to be painted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Trace the outlines with an &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;X-acto_knife&quot;&gt;x-acto
knife&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Remove paper on areas to be painted.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Use the cheapest car spray paint from your local hobby market in the
brightest color you can find (bonus point for fluorescent colors).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Remove the paper after the paint has become tacky, it should only
leave some glue traces.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Remove glue traces with solvent after the paint has fully set.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;There you have it, perfect logo’s every time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Some pictures of the finished and installed server:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Qubis Server in rack, De eerste Qubis server, net geplaatst in het rack
van TransIP.&lt;&#x2F;p&gt;
&lt;p&gt;One of the many rack alleys, Just one of the many rack alleys at
TransIP.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
