# GLV Multiplication This note explains the scalar decomposition step on the efficient EC multiplication algorithm proposed in this [article](https://www.iacr.org/archive/crypto2001/21390189.pdf). Some implementations of the algorithm: - [Python implementation](https://github.com/demining/CryptoDeepTools/blob/9dfd594126117e07fc51a77a7c613180eb662f18/07EndomorphismSecp256k1/endomorphism.py#L145) - [Go implementation](https://github.com/ConsenSys/gnark-crypto/blob/8f7ca09273c24ed9465043566906cbecf5dcee91/ecc/utils.go#L141) - [Rust implementation](https://github.com/privacy-scaling-explorations/halo2curves/pull/24) - In-circuit implementation in halo2wrong [PR](https://github.com/davidnevadoc/halo2wrong/tree/test/endo-scalar-mul) Here is a good explanation of the whole algorithm along with an implementation: [bitcoin secp impl](https://github.com/bitcoin-core/secp256k1/blob/1b21aa51752958138aab3f750afdb7549f82ca89/src/scalar_impl.h#L75). $\newcommand{sF}{\mathbb{F}_n}$ $\newcommand{zz}{\mathbb{Z}\times\mathbb{Z}}$ $\newcommand{g}{\gamma}$ $\newcommand{b}{\beta}$ ## Scalar decomposition The following homomorphism is defined: $$ \begin{aligned} f: \zz & \to \sF \\ (i,j) & \mapsto i + \lambda j \end{aligned} $$ where $\lambda$ is the endoscalar of the curve. The problem of decomposing a given scalar $k \in \sF$ consists of finding a pair $(k_1, k_2) \in \zz$ s.t. $f(k_1, k_2) = k$. The key of the problem is to find the shortest vector possible that satisfies this relation. First we precompute 2 vectors $\g, \b$ such that $f(\g) = f(\b) = 0$. The problem now turns into finding a vector $v$ in the lattice generated by $[\b, \g]$ that is close to $(k, 0)$. With such vector $v$ we easily compute $$ (k_1, k_2) := (k, 0) - v $$ which is short, ($\leq \max{(\lVert\b\rVert, \lVert\g\rVert)}$) and satisfies our fist condition, since $$ f((k_1, k_2)) = f((k, 0)) - f(v) = k $$ Let $v := t_1 \cdot \b + t_2 \cdot \g$. We solve the system $$ \begin{pmatrix} \b_1 & \g_1 \\ \b_2 & \g_2 \end{pmatrix} \begin{pmatrix} t_1 \\ t_2 \end{pmatrix} = \begin{pmatrix} k \\ 0 \end{pmatrix} $$ $$ \begin{pmatrix} t_1 \\ t_2 \end{pmatrix} = \frac{1}{d} \begin{pmatrix} \g_2 & - \g_1 \\ -\b_2 & \b_1 \end{pmatrix} \begin{pmatrix} k \\ 0 \end{pmatrix} $$ where $d$ is the determinant of the $[\g, \b]$ matrix. We get $$ \begin{align} t_1 =& \frac{1}{d} \cdot k \cdot \g_2 \\ t_2 =& -\frac{1}{d} \cdot k \cdot \b_2 \end{align} $$ Due to the determinant division, these values lie on $\mathbb{Q}$. We round them to their closest integer value to obtain a point in the $[\b, \g]$-generated lattice. Now we have: $$ \begin{pmatrix} k_1 \\ k_2 \end{pmatrix} = \begin{pmatrix} k \\ 0 \end{pmatrix} - \begin{pmatrix} \b_1 & \g_1 \\ \b_2 & \g_2 \end{pmatrix} \begin{pmatrix} \lfloor t_1 \rceil \\ \lfloor t_2 \rceil \end{pmatrix} $$ We will only compute $-k_2$: $$ -k_2 = \b_2 \cdot \lfloor t_1 \rceil + \g_2 \cdot \lfloor t_2 \rceil $$ Then we use the original definition $k = k_1 + \lambda k_2$ to compute $k_1$: $$ k_1 = k + \lambda (-k_2) $$ Finally, instead of returning $k_1, k_2$, this algorithm will return $-k_i$ or $k_i$ choosing the one with a lower absolute value. The choice is indicated with some flags. The output then is `(k_1, k_1_neg, k_2, k_2_neg)`.