This repository contains an experimental implementation of the syzygy distinguisher presented in https://eprint.iacr.org/2024/1193 (see https://github.com/randriam/syzygies for legacy magma code).
This is a toy implementation of the algorithm described in: Albano & La Scala's paper
We are interested in computing the linear strand of a graded module over a polynomial ring until a given
Let
Let
Let
Then
Alternatively, the
The
Such a thing can be done by constructing the macaulay matrix
The procedure is as follows:
- First, construct at a minimal cost the matrices
$T$ and$\bar{T}$ that correspond to the simplified system described by the macaulay matrix$M$ :
-
Then, compute
$Ker(\bar{T})$ and extend it to$Ker(M_{red}) = Vec \left< (-T\times x | x), x \in Ker(\bar{T}) \right>$ (multiply by -T and concatenate) and then permute columns back to obtain$Ker(M)$ -
Finally, iterate:
$m \leftarrow \#(f_i)_i$ $(e_i)_i \leftarrow (f_i)_i$ $n \leftarrow \#(L'_i)_i$ $(f_j)_j \leftarrow (\sum_{i=1}^nL_{ij}'f_i)_j$
Notations are almost the same as the one from Albano & La Scala:
- The order was switched to the lexicographical ordering as it seems more natural and we didn't see any reason to keep the order Albano & La Scala introduced :
$(h, k) < (h' , k' )$ iff$(k > k')\lor\left((k = k') \land (h < h')\right)$ becomes$(h, k) < (h' , k' )$ iff$(h < h')\lor\left((h = h') \land (k < k')\right)$ - As a consequence, the notation of matrix B is adjusted. Now, B is read from left to right and is required to be in Left Row Echelon Form.
You just need sage math.
In a sage interpreter, run :
from linear_strand import *
G = matrix(GF(3),
[[1, 0, 0, 0, 0, 0, 2, 0, 1, 2, 1],
[0, 1, 0, 0, 0, 0, 1, 2, 2, 2, 1],
[0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1],
[0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 2],
[0, 0, 0, 0, 1, 0, 2, 1, 2, 2, 0],
[0, 0, 0, 0, 0, 1, 0, 2, 1, 2, 2]])
golay = CodeStrand(G)
dist = golay.compute(r=4)
print(dist)This example compute the linear strand of the (10, 5) Reed-Solomon code.
The matrix A is the M23 macaulay matrix, the first matrix we iterate on to get further syzygies.
In this example, the entire matrix is constructed before applying the procedure described in Albano & La Scala step by step.
This is Nicolas's implementation.
Only the solution columns of the system are constructed, transvections that can be deduced from reading the matrix B are "done" directly when constructing the matrix of the system. This version could be converted in a sparse/multithreaded one quiet easily.
code_ideal.py, expanded_matrix.py, linear_strand.py, macaulay_matrix.py, order.py, projects.sage, utils.py
This is Pierre's implementation.
Currently it contains a dense version that construct the entire matrix and it should be adapted to construct only the solution columns and exploit sparsness.
code_ideal.py: compute the square of the code and Macaulay23 matrix.expanded_matrix.py: compute the expanded matrix and runkosz_syz_matsmethod.linear_strand.py: Toy syzygy distinguisher, with Albano & La Scala method.macaulay_matrix.py: matrix constructions, operations and reduction.order.py: monomial orders, rows and columns permutation.projects.py: examples of computations.utils.py: usefull stuff.
It is currently quite slow and should only be considered as a toy/demonstrator. Nevertheless, we believe it could be drastically improved:
- The
block_ideal_elimmethod currently takes 1/4 of the running time. However, the transvections can be determined by analyzing B (not yet implemented), so the matrix after these transvections can be built straightforwardly, avoiding the call to the naiveblock_ideal_elimmethod. - The
block_forward_substitutionmethod currently takes about 1/4 to 1/3 of the running time. Since this involves only linear algebra and block operations, it could be parallelized/multithreaded.
- parallelization/multiprocessing
- GPU
- dense/sparse algebra
- predictable execution flow
- predictable memory-access pattern
- characteristic of the field
- use
numpyandnumba