From 88b955ec99c06188041c0fe1fce41620dd0b6cc6 Mon Sep 17 00:00:00 2001 From: thomaslavaur Date: Fri, 19 Jul 2024 13:04:37 +0200 Subject: [PATCH] rename main template properly and remove useless file --- .../anemoi/Anemoi 2-to-1.ipynb | 1025 ----------------- .../leadership_anemoi_sha.circom | 4 +- .../leadership_poseidon.circom | 4 +- .../leadership_poseidon_sha.circom | 4 +- 4 files changed, 6 insertions(+), 1031 deletions(-) delete mode 100644 Proof of Leadership/anemoi/Anemoi 2-to-1.ipynb diff --git a/Proof of Leadership/anemoi/Anemoi 2-to-1.ipynb b/Proof of Leadership/anemoi/Anemoi 2-to-1.ipynb deleted file mode 100644 index 1cdbc3a..0000000 --- a/Proof of Leadership/anemoi/Anemoi 2-to-1.ipynb +++ /dev/null @@ -1,1025 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "50885b34", - "metadata": {}, - "outputs": [], - "source": [ - "# BLS12-381 Base field\n", - "BLS12_381_BASEFIELD = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab\n", - "# BLS12-381 Scalar field\n", - "BLS12_381_SCALARFIELD = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001\n", - "\n", - "# BLS12-377 Base field = BW6_761 Scalar field\n", - "BLS12_377_BASEFIELD = 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001\n", - "# BLS12-377 Scalar field = Ed_on_bls_12_377 Base field\n", - "BLS12_377_SCALARFIELD = 0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001\n", - "\n", - "# BN-254 Base field\n", - "BN_254_BASEFIELD = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47\n", - "# BN-254 Scalar field\n", - "BN_254_SCALARFIELD = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001\n", - "\n", - "# Pallas Base field = Vesta Scalar field\n", - "PALLAS_BASEFIELD = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001\n", - "\n", - "# Vesta Base field = Pallas Scalar field\n", - "VESTA_BASEFIELD = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001\n", - "\n", - "# Small Goldilocks field\n", - "GOLDILOCKS_64_FIELD = 0xffffffff00000001" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "23180928", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "c309f191", - "metadata": {}, - "outputs": [], - "source": [ - "from sage.all import *\n", - "import hashlib\n", - "import itertools\n", - "\n", - "\n", - "COST_ALPHA = {\n", - " 3 : 2, 5 : 3, 7 : 4, 9 : 4,\n", - " 11 : 5, 13 : 5, 15 : 5, 17 : 5,\n", - " 19 : 6, 21 : 6, 23 : 6, 25 : 6,\n", - " 27 : 6, 29 : 7, 31 : 7, 33 : 6,\n", - " 35 : 7, 37 : 7, 39 : 7, 41 : 7,\n", - " 43 : 7, 45 : 7, 47 : 8, 49 : 7,\n", - " 51 : 7, 53 : 8, 55 : 8, 57 : 8,\n", - " 59 : 8, 61 : 8, 63 : 8, 65 : 7,\n", - " 67 : 8, 69 : 8, 71 : 9, 73 : 8,\n", - " 75 : 8, 77 : 8, 79 : 9, 81 : 8,\n", - " 83 : 8, 85 : 8, 87 : 9, 89 : 9,\n", - " 91 : 9, 93 : 9, 95 : 9, 97 : 8,\n", - " 99 : 8, 101 : 9, 103 : 9, 105 : 9,\n", - " 107 : 9, 109 : 9, 111 : 9, 113 : 9,\n", - " 115 : 9, 117 : 9, 119 : 9, 121 : 9,\n", - " 123 : 9, 125 : 9, 127 : 10,\n", - "}\n", - "\n", - "ALPHA_BY_COST = {\n", - " c : [x for x in range(3, 128, 2) if COST_ALPHA[x] == c]\n", - " for c in range(2, 11)\n", - "}\n", - "\n", - "PI_0 = 1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679\n", - "PI_1 = 8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196\n", - "\n", - "def get_prime(N):\n", - " result = (1 << N) - 1\n", - " while not is_prime(result):\n", - " result -= 2\n", - " return result\n", - "\n", - "\n", - "def get_n_rounds(s, l, alpha):\n", - " r = 0\n", - " complexity = 0\n", - " kappa = {3:1, 5:2, 7:4, 9:7, 11:9}\n", - " assert alpha in kappa\n", - " while complexity < 2**s:\n", - " r += 1\n", - " complexity = binomial(\n", - " 4*l*r + kappa[alpha],\n", - " 2*l*r\n", - " )**2\n", - " r += 2 # considering the second model\n", - " r += min(5,l+1) # security margin\n", - " \n", - " return max(8, r)\n", - "\n", - "\n", - "# Linear layer generation\n", - "\n", - "def is_mds(m):\n", - " # Uses the Laplace expansion of the determinant to calculate the (m+1)x(m+1) minors in terms of the mxm minors.\n", - " # Taken from https://github.com/mir-protocol/hash-constants/blob/master/mds_search.sage.\n", - "\n", - " # 1-minors are just the elements themselves\n", - " if any(any(r == 0 for r in row) for row in m):\n", - " return False\n", - "\n", - " N = m.nrows()\n", - " assert m.is_square() and N >= 2\n", - "\n", - " det_cache = m\n", - "\n", - " # Calculate all the nxn minors of m:\n", - " for n in range(2, N+1):\n", - " new_det_cache = dict()\n", - " for rows in itertools.combinations(range(N), n):\n", - " for cols in itertools.combinations(range(N), n):\n", - " i, *rs = rows\n", - "\n", - " # Laplace expansion along row i\n", - " det = 0\n", - " for j in range(n):\n", - " # pick out c = column j; the remaining columns are in cs\n", - " c = cols[j]\n", - " cs = cols[:j] + cols[j+1:]\n", - "\n", - " # Look up the determinant from the previous iteration\n", - " # and multiply by -1 if j is odd\n", - " cofactor = det_cache[(*rs, *cs)]\n", - " if j % 2 == 1:\n", - " cofactor = -cofactor\n", - "\n", - " # update the determinant with the j-th term\n", - " det += m[i, c] * cofactor\n", - "\n", - " if det == 0:\n", - " return False\n", - " new_det_cache[(*rows, *cols)] = det\n", - " det_cache = new_det_cache\n", - " return True\n", - "\n", - "def M_2(x_input, b):\n", - " x = x_input[:]\n", - " x[0] += b*x[1]\n", - " x[1] += b*x[0]\n", - " return x\n", - "\n", - "def M_3(x_input, b):\n", - " x = x_input[:]\n", - " t = x[0] + b*x[2]\n", - " x[2] += x[1]\n", - " x[2] += b*x[0]\n", - " x[0] = t + x[2]\n", - " x[1] += t\n", - " return x\n", - "\n", - "\n", - "def M_4(x_input, b):\n", - " x = x_input[:]\n", - " x[0] += x[1]\n", - " x[2] += x[3]\n", - " x[3] += b*x[0]\n", - " x[1] = b*(x[1] + x[2])\n", - " x[0] += x[1]\n", - " x[2] += b*x[3]\n", - " x[1] += x[2]\n", - " x[3] += x[0]\n", - " return x\n", - "\n", - "def lfsr(x_input, b):\n", - " x = x_input[:]\n", - " l = len(x)\n", - " for r in range(0, l):\n", - " t = sum(b**(2**i) * x[i] for i in range(0, l))\n", - " x = x[1:] + [t]\n", - " return x\n", - "\n", - "def circulant_mds_matrix(field, l, coeff_upper_limit=None):\n", - " if coeff_upper_limit == None:\n", - " coeff_upper_limit = l+1\n", - " assert(coeff_upper_limit > l)\n", - " for v in itertools.combinations_with_replacement(range(1,coeff_upper_limit), l):\n", - " mat = matrix.circulant(list(v)).change_ring(field)\n", - " if is_mds(mat):\n", - " return(mat)\n", - " # In some cases, the method won't return any valid matrix,\n", - " # hence the need to increase the limit further.\n", - " return circulant_mds_matrix(field, l, coeff_upper_limit+1)\n", - "\n", - "def get_mds(field, l):\n", - " if l == 1:\n", - " return identity_matrix(field, 1)\n", - " if l <= 4: # low addition case\n", - " a = field.multiplicative_generator()\n", - " b = field.one()\n", - " t = 0\n", - " while True:\n", - " # we construct the matrix\n", - " mat = []\n", - " b = b*a\n", - " t += 1\n", - " for i in range(0, l):\n", - " x_i = [field.one() * (j == i) for j in range(0, l)]\n", - " if l == 2:\n", - " mat.append(M_2(x_i, b))\n", - " elif l == 3:\n", - " mat.append(M_3(x_i, b))\n", - " elif l == 4:\n", - " mat.append(M_4(x_i, b))\n", - " mat = Matrix(field, l, l, mat).transpose()\n", - " if is_mds(mat):\n", - " return mat\n", - " else: # circulant matrix case\n", - " return circulant_mds_matrix(field, l)\n", - "\n", - "# AnemoiPermutation class\n", - "\n", - "class AnemoiPermutation:\n", - " def __init__(self,\n", - " q=None,\n", - " alpha=None,\n", - " mat=None,\n", - " n_rounds=None,\n", - " n_cols=1,\n", - " security_level=128):\n", - " if q == None:\n", - " raise Exception(\"The characteristic of the field must be specified!\")\n", - " self.q = q\n", - " self.prime_field = is_prime(q) # if true then we work over a\n", - " # prime field with\n", - " # characteristic just under\n", - " # 2**N, otherwise the\n", - " # characteristic is 2**self\n", - " self.n_cols = n_cols # the number of parallel S-boxes in each round\n", - " self.security_level = security_level\n", - "\n", - " # initializing the other variables in the state:\n", - " # - q is the characteristic of the field\n", - " # - g is a generator of the multiplicative subgroup\n", - " # - alpha is the main exponent (in the center of the Flystel)\n", - " # - beta is the coefficient in the quadratic subfunction\n", - " # - gamma is the constant in the second quadratic subfunction\n", - " # - QUAD is the secondary (quadratic) exponent\n", - " # - from_field is a function mapping field elements to integers\n", - " # - to_field is a function mapping integers to field elements\n", - " self.F = GF(self.q)\n", - " if self.prime_field:\n", - " if alpha != None:\n", - " if gcd(alpha, self.q-1) != 1:\n", - " raise Exception(\"alpha should be co-prime with the characteristic!\")\n", - " else:\n", - " self.alpha = alpha\n", - " else:\n", - " self.alpha = 3\n", - " while gcd(self.alpha, self.q-1) != 1:\n", - " self.alpha += 1\n", - " self.QUAD = 2\n", - " self.to_field = lambda x : self.F(x)\n", - " self.from_field = lambda x : Integer(x)\n", - " else:\n", - " self.alpha = 3\n", - " self.QUAD = 3\n", - " self.to_field = lambda x : self.F.fetch_int(x)\n", - " self.from_field = lambda x : x.integer_representation()\n", - " self.g = self.F.multiplicative_generator()\n", - " self.beta = self.g\n", - " self.delta = self.g**(-1)\n", - " self.alpha_inv = inverse_mod(self.alpha, self.q-1)\n", - "\n", - " # total number of rounds\n", - " if n_rounds != None:\n", - " self.n_rounds = n_rounds\n", - " else:\n", - " self.n_rounds = get_n_rounds(self.security_level,\n", - " self.n_cols,\n", - " self.alpha)\n", - "\n", - " # Choosing constants: self.C and self.D are built from the\n", - " # digits of pi using an open butterfly\n", - " self.C = []\n", - " self.D = []\n", - " pi_F_0 = self.to_field(PI_0 % self.q)\n", - " pi_F_1 = self.to_field(PI_1 % self.q)\n", - " for r in range(0, self.n_rounds):\n", - " pi_0_r = pi_F_0**r\n", - " self.C.append([])\n", - " self.D.append([])\n", - " for i in range(0, self.n_cols):\n", - " pi_1_i = pi_F_1**i\n", - " pow_alpha = (pi_0_r + pi_1_i)**self.alpha\n", - " self.C[r].append(self.g * (pi_0_r)**2 + pow_alpha)\n", - " self.D[r].append(self.g * (pi_1_i)**2 + pow_alpha + self.delta)\n", - " self.mat = get_mds(self.F, self.n_cols)\n", - "\n", - "\n", - " def __str__(self):\n", - " result = \"Anemoi instance over F_{:d} ({}), n_rounds={:d}, n_cols={:d}, s={:d}\".format(\n", - " self.q,\n", - " \"odd prime field\" if self.prime_field else \"characteristic 2\",\n", - " self.n_rounds,\n", - " self.n_cols,\n", - " self.security_level\n", - " )\n", - " result += \"\\nalpha={}, beta={}, \\ndelta={}\\nM_x=\\n{}\\ninv_alpha={}\\n\".format(\n", - " self.alpha,\n", - " self.beta,\n", - " self.delta,\n", - " self.mat,\n", - " self.alpha_inv\n", - " )\n", - " result += \"C={}\\nD={}\".format(\n", - " [[self.from_field(x) for x in self.C[r]] for r in range(0, self.n_rounds)],\n", - " [[self.from_field(x) for x in self.D[r]] for r in range(0, self.n_rounds)],\n", - " )\n", - " return result\n", - "\n", - "\n", - " # !SECTION! Sub-components\n", - "\n", - " def evaluate_sbox(self, _x, _y):\n", - " x, y = _x, _y\n", - " x -= self.beta*y**self.QUAD\n", - " y -= x**self.alpha_inv\n", - " x += self.beta*y**self.QUAD + self.delta\n", - " return x, y\n", - "\n", - " def linear_layer(self, _x, _y):\n", - " x, y = _x[:], _y[:]\n", - " x = self.mat*vector(x)\n", - " y = self.mat*vector(y[1:] + [y[0]])\n", - "\n", - " # Pseudo-Hadamard transform on each (x,y) pair\n", - " y += x\n", - " x += y\n", - " return list(x), list(y)\n", - "\n", - "\n", - " # !SECTION! Evaluation\n", - "\n", - " def eval_with_intermediate_values(self, _x, _y):\n", - " x, y = _x[:], _y[:]\n", - " result = [[x[:], y[:]]]\n", - " for r in range(0, self.n_rounds):\n", - " for i in range(0, self.n_cols):\n", - " x[i] += self.C[r][i]\n", - " y[i] += self.D[r][i]\n", - " x, y = self.linear_layer(x, y)\n", - " for i in range(0, self.n_cols):\n", - " x[i], y[i] = self.evaluate_sbox(x[i], y[i])\n", - " result.append([x[:], y[:]])\n", - " # final call to the linear layer\n", - " x, y = self.linear_layer(x, y)\n", - " result.append([x[:], y[:]])\n", - " return result\n", - "\n", - "\n", - " def input_size(self):\n", - " return 2*self.n_cols\n", - "\n", - "\n", - " def __call__(self, _x):\n", - " if len(_x) != self.input_size():\n", - " raise Exception(\"wrong input size!\")\n", - " else:\n", - " x, y = _x[:self.n_cols], _x[self.n_cols:]\n", - " u, v = self.eval_with_intermediate_values(x, y)[-1]\n", - " return u + v # concatenation, not a sum\n", - "\n", - "\n", - " # !SECTION! Writing full system of equations\n", - "\n", - " def get_polynomial_variables(self):\n", - " x_vars = []\n", - " y_vars = []\n", - " all_vars = []\n", - " for r in range(0, self.n_rounds+1):\n", - " x_vars.append([\"X{:02d}{:02d}\".format(r, i) for i in range(0, self.n_cols)])\n", - " y_vars.append([\"Y{:02d}{:02d}\".format(r, i) for i in range(0, self.n_cols)])\n", - " all_vars += x_vars[-1]\n", - " all_vars += y_vars[-1]\n", - " pol_ring = PolynomialRing(self.F, (self.n_rounds+1)*2*self.n_cols, all_vars)\n", - " pol_gens = pol_ring.gens()\n", - " result = {\"X\" : [], \"Y\" : []}\n", - " for r in range(0, self.n_rounds+1):\n", - " result[\"X\"].append([])\n", - " result[\"Y\"].append([])\n", - " for i in range(0, self.n_cols):\n", - " result[\"X\"][r].append(pol_gens[self.n_cols*2*r + i])\n", - " result[\"Y\"][r].append(pol_gens[self.n_cols*2*r + i + self.n_cols])\n", - " return result\n", - "\n", - "\n", - " def verification_polynomials(self, pol_vars):\n", - " equations = []\n", - " for r in range(0, self.n_rounds):\n", - " # the outputs of the open flystel are the state variables x, y at round r+1\n", - " u = pol_vars[\"X\"][r+1]\n", - " v = pol_vars[\"Y\"][r+1]\n", - " # the inputs of the open flystel are the state variables\n", - " # x, y at round r after undergoing the constant addition\n", - " # and the linear layer\n", - " x, y = pol_vars[\"X\"][r], pol_vars[\"Y\"][r]\n", - " x = [x[i] + self.C[r][i] for i in range(0, self.n_cols)]\n", - " y = [y[i] + self.D[r][i] for i in range(0, self.n_cols)]\n", - " x, y = self.linear_layer(x, y)\n", - " for i in range(0, self.n_cols):\n", - " equations.append(\n", - " (y[i]-v[i])**self.alpha + self.beta*y[i]**self.QUAD - x[i]\n", - " )\n", - " equations.append(\n", - " (y[i]-v[i])**self.alpha + self.beta*v[i]**self.QUAD + self.delta - u[i]\n", - " )\n", - " return equations\n", - "\n", - "\n", - " def print_verification_polynomials(self):\n", - " p_vars = self.get_polynomial_variables()\n", - " eqs = self.verification_polynomials(p_vars)\n", - " variables_string = \"\"\n", - " for r in range(0, self.n_rounds+1):\n", - " variables_string += str(p_vars[\"X\"][r])[1:-1] + \",\" + str(p_vars[\"Y\"][r])[1:-1] + \",\"\n", - " print(variables_string[:-1].replace(\" \", \"\"))\n", - " print(self.q)\n", - " for f in eqs:\n", - " print(f)\n", - "\n", - "\n", - "\n", - "# !SECTION! Modes of operation\n", - "\n", - "\n", - "def jive(P, b, _x):\n", - " if b < 2:\n", - " raise Exception(\"b must be at least equal to 2\")\n", - " if P.input_size() % b != 0:\n", - " raise Exception(\"b must divide the input size!\")\n", - " c = P.input_size()/b # length of the compressed output\n", - " # Output size check: we allow the output size to be 3 bits shorter than\n", - " # the theoretical target, as commonly used finite fields usually have a\n", - " # characteristic size slightly under 2**256.\n", - " if c * P.F.cardinality().nbits() < 2 * P.security_level - 3:\n", - " raise Exception(f\"digest size is too small for the targeted security level!\")\n", - " x = _x[:]\n", - " u = P(x)\n", - " compressed = []\n", - " for i in range(0, c):\n", - " compressed.append(sum(x[i+c*j] + u[i+c*j]\n", - " for j in range(0, b)))\n", - " return compressed\n", - "\n", - "\n", - "def sponge_hash(P, r, h, _x):\n", - " x = _x[:]\n", - " if P.input_size() <= r:\n", - " raise Exception(\"rate must be strictly smaller than state size!\")\n", - " # Digest size and capacity check: we allow the digest size to be 3 bits\n", - " # shorter than the theoretical target, as commonly used finite fields\n", - " # usually have a characteristic size slightly under 2**256.\n", - " if h * P.F.cardinality().nbits() < 2 * P.security_level - 3:\n", - " raise Exception(f\"digest size is too small for the targeted security level!\")\n", - " capacity = P.input_size() - r\n", - " if capacity * P.F.cardinality().nbits() < 2 * P.security_level - 3:\n", - " raise Exception(f\"capacity is too small for the targeted security level!\")\n", - "\n", - " # message padding (and domain separator computation)\n", - " if len(x) % r == 0 and len(x) != 0:\n", - " sigma = 1\n", - " else:\n", - " sigma = 0\n", - " x += [1]\n", - " # if x is still not long enough, append 0s\n", - " if len(x) % r != 0:\n", - " x += (r - (len(x) % r))*[0]\n", - " padded_x = [[x[pos+i] for i in range(0, r)]\n", - " for pos in range(0, len(x), r)]\n", - " # absorption phase\n", - " internal_state = [0] * P.input_size()\n", - " for pos in range(0, len(padded_x)):\n", - " for i in range(0, r):\n", - " internal_state[i] += padded_x[pos][i]\n", - " internal_state = P(internal_state)\n", - " if pos == len(padded_x)-1:\n", - " # adding sigma if it is the last block\n", - " internal_state[-1] += sigma\n", - " # squeezing\n", - " digest = []\n", - " pos = 0\n", - " while len(digest) < h:\n", - " digest.append(internal_state[pos])\n", - " pos += 1\n", - " if pos == r:\n", - " pos = 0\n", - " internal_state = P(internal_state)\n", - " return digest\n", - "\n", - "\n", - "# !SECTION! Tests\n", - "\n", - "def check_polynomial_verification(n_tests=10, q=2**63, alpha=3, n_rounds=3, n_cols=1):\n", - " A = AnemoiPermutation(q=q, alpha=alpha, n_rounds=n_rounds, n_cols=n_cols)\n", - " # formal polynomial variables and equations\n", - " p_vars = A.get_polynomial_variables()\n", - " eqs = A.verification_polynomials(p_vars)\n", - " A.print_verification_polynomials()\n", - " # for n_tests random inputs, we check that the equations are\n", - " # coherent with the actual intermediate values\n", - " print(\"\\n ======== Verification:\")\n", - " print(A)\n", - " print(\"{} equations in {} variables.\".format(\n", - " len(eqs),\n", - " (A.n_rounds+1) * 2 * A.n_cols,\n", - " ))\n", - " for t in range(0, n_tests):\n", - " # generate random input\n", - " x = [A.to_field(randint(0, A.q - 1))\n", - " for i in range(0, A.n_cols)]\n", - " y = [A.to_field(randint(0, A.q - 1))\n", - " for i in range(0, A.n_cols)]\n", - " # generate intermediate values, formal polynomial variables,\n", - " # and equations\n", - " iv = A.eval_with_intermediate_values(x, y)\n", - " p_vars = A.get_polynomial_variables()\n", - " eqs = A.verification_polynomials(p_vars)\n", - " # obtain variable assignment from the actual evaluation\n", - " assignment = {}\n", - " for r in range(0, A.n_rounds+1):\n", - " for i in range(0, A.n_cols):\n", - " assignment[p_vars[\"X\"][r][i]] = iv[r][0][i]\n", - " assignment[p_vars[\"Y\"][r][i]] = iv[r][1][i]\n", - " # printing the value of the equations for the actual\n", - " # intermediate states\n", - " print(\"\\n--- \", t, \"(all values except the input should be 0)\")\n", - " print(\"input: \", x, y)\n", - " for r in range(0, A.n_rounds):\n", - " polynomial_values = [eqs[r*2*A.n_cols + i].subs(assignment)\n", - " for i in range(0, 2*A.n_cols)]\n", - " print(\"round {:3d}: {}\\n {}\".format(\n", - " r,\n", - " polynomial_values[0::2],\n", - " polynomial_values[1::2]\n", - " ))\n", - "\n", - "\n", - "def test_jive(n_tests=10,\n", - " q=2**63, alpha=3,\n", - " n_rounds=None,\n", - " n_cols=1,\n", - " b=2,\n", - " security_level=32):\n", - " A = AnemoiPermutation(q=q, alpha=alpha, n_rounds=n_rounds, n_cols=n_cols, security_level=security_level)\n", - " print(A)\n", - " for t in range(0, n_tests):\n", - " # generate random input\n", - " x = [A.to_field(randint(0, A.q - 1))\n", - " for i in range(0, A.n_cols)]\n", - " y = [A.to_field(randint(0, A.q - 1))\n", - " for i in range(0, A.n_cols)]\n", - " print(\"x = {}\\ny = {}\\nAnemoiJive_{}(x,y) = {}\".format(\n", - " x,\n", - " y,\n", - " b,\n", - " jive(A, b, x + y)\n", - " ))\n", - "\n", - "\n", - "def test_sponge(n_tests=10,\n", - " q=2**63,\n", - " alpha=3,\n", - " n_rounds=None,\n", - " n_cols=1,\n", - " b=2,\n", - " security_level=32):\n", - " A = AnemoiPermutation(q=q, alpha=alpha, n_rounds=n_rounds, n_cols=n_cols, security_level=security_level)\n", - " print(A)\n", - " for t in range(0, n_tests):\n", - " # generate random input of length t\n", - " x = [A.to_field(randint(0, A.q - 1))\n", - " for i in range(0, t)]\n", - " print(\"x = {}\\nAnemoiSponge(x) = {}\".format(\n", - " x,\n", - " sponge_hash(A, 2, 2, x)\n", - " ))\n", - "\n", - "def generate_test_vectors_jive(P, b, n):\n", - " assert n >= 4, \"The number of test vectors should be greater than 4.\"\n", - " m = hashlib.sha512(str(P).encode())\n", - " m.update(\"Jive test vectors\".encode())\n", - " m.update(f\"B={b}\".encode())\n", - " seed = Integer(m.digest().hex(), 16)\n", - "\n", - " inputs = []\n", - " outputs = []\n", - " inputs.append([P.F(0) for _ in range(P.input_size())])\n", - " inputs.append([P.F(1) for _ in range(P.input_size())])\n", - " inputs.append([P.F(0) for _ in range(P.n_cols)] + [P.F(1) for _ in range(P.n_cols)])\n", - " inputs.append([P.F(1) for _ in range(P.n_cols)] + [P.F(0) for _ in range(P.n_cols)])\n", - " for i in range(n - 4):\n", - " input = []\n", - " for _ in range(P.input_size()):\n", - " input.append(P.to_field(seed))\n", - " m.update(str(seed).encode())\n", - " seed = Integer(m.digest().hex(), 16)\n", - " inputs.append(input)\n", - " for input in inputs:\n", - " outputs.append(jive(P, b, input))\n", - "\n", - " print(\n", - " \"Test vectors for Anemoi instance over F_{:d}, n_rounds={:d}, n_cols={:d}, s={:d}\".format(\n", - " P.q,\n", - " P.n_rounds,\n", - " P.n_cols,\n", - " P.security_level)\n", - " )\n", - " return (inputs, outputs)\n", - "\n", - "\n", - "def generate_test_vectors_sponge(P, r, h, n):\n", - " assert n >= 4, \"The number of test vectors should be greater than 4.\"\n", - " m = hashlib.sha512(str(P).encode())\n", - " m.update(\"Sponge test vectors\".encode())\n", - " m.update(f\"R={r}\".encode())\n", - " m.update(f\"H={h}\".encode())\n", - " seed = Integer(m.digest().hex(), 16)\n", - "\n", - " inputs = []\n", - " outputs = []\n", - " inputs.append([P.F(0) for _ in range(P.input_size())])\n", - " inputs.append([P.F(1) for _ in range(P.input_size())])\n", - " inputs.append([P.F(0) for _ in range(P.n_cols)] + [P.F(1) for _ in range(P.n_cols)])\n", - " inputs.append([P.F(1) for _ in range(P.n_cols)] + [P.F(0) for _ in range(P.n_cols)])\n", - " for i in range(n - 4):\n", - " input = []\n", - " for _ in range(i+1):\n", - " input.append(P.to_field(seed))\n", - " m.update(str(seed).encode())\n", - " seed = Integer(m.digest().hex(), 16)\n", - " inputs.append(input)\n", - " for input in inputs:\n", - " outputs.append(sponge_hash(P, r, h, input))\n", - "\n", - " print(\n", - " \"Test vectors for Anemoi instance over F_{:d}, n_rounds={:d}, n_cols={:d}, s={:d}\".format(\n", - " P.q,\n", - " P.n_rounds,\n", - " P.n_cols,\n", - " P.security_level)\n", - " )\n", - " return (inputs, outputs)\n", - "\n", - "\n", - "def generate_test_vectors_sbox(P, n):\n", - " assert n >= 4, \"The number of test vectors should be greater than 4.\"\n", - " m = hashlib.sha512(str(P).encode())\n", - " m.update(\"S-Box test vectors\".encode())\n", - " seed = Integer(m.digest().hex(), 16)\n", - "\n", - " inputs = []\n", - " outputs = []\n", - " inputs.append([P.F(0) for _ in range(P.input_size())])\n", - " inputs.append([P.F(1) for _ in range(P.input_size())])\n", - " inputs.append([P.F(0) for _ in range(P.n_cols)] + [P.F(1) for _ in range(P.n_cols)])\n", - " inputs.append([P.F(1) for _ in range(P.n_cols)] + [P.F(0) for _ in range(P.n_cols)])\n", - "\n", - " for _ in range(n - 4):\n", - " input = []\n", - " for _ in range(P.input_size()):\n", - " input.append(P.to_field(seed))\n", - " m.update(str(seed).encode())\n", - " seed = Integer(m.digest().hex(), 16)\n", - " inputs.append(input)\n", - " for input in inputs:\n", - " x = [0 for i in range(P.n_cols)]\n", - " y = [0 for i in range(P.n_cols)]\n", - " for i in range(P.n_cols):\n", - " x[i], y[i] = P.evaluate_sbox(input[i], input[P.n_cols + i])\n", - " x.extend(y)\n", - " outputs.append(x)\n", - "\n", - " return (inputs, outputs)\n", - "\n", - "\n", - "def generate_test_vectors_mds(P, n):\n", - " assert n >= 4, \"The number of test vectors should be greater than 4.\"\n", - " m = hashlib.sha512(str(P).encode())\n", - " m.update(\"MDS test vectors\".encode())\n", - " seed = Integer(m.digest().hex(), 16)\n", - "\n", - " inputs = []\n", - " outputs = []\n", - " inputs.append([P.F(0) for _ in range(P.input_size())])\n", - " inputs.append([P.F(1) for _ in range(P.input_size())])\n", - " inputs.append([P.F(0) for _ in range(P.n_cols)] + [P.F(1) for _ in range(P.n_cols)])\n", - " inputs.append([P.F(1) for _ in range(P.n_cols)] + [P.F(0) for _ in range(P.n_cols)])\n", - " for _ in range(n - 4):\n", - " input = []\n", - " for _ in range(P.input_size()):\n", - " input.append(P.to_field(seed))\n", - " m.update(str(seed).encode())\n", - " seed = Integer(m.digest().hex(), 16)\n", - " inputs.append(input)\n", - " for input in inputs:\n", - " x,y = P.linear_layer(input[0:P.n_cols], input[P.n_cols:])\n", - " x.extend(y)\n", - " outputs.append(x)\n", - "\n", - " return (inputs, outputs)\n", - "\n", - "\n", - "if __name__ == \"__main__\":\n", - "\n", - " # These are the first circulant matrices being found by the circulant_mds_matrix()\n", - " # method above. These are precomputed for faster initiatialization of large Anemoi\n", - " # instances.\n", - " CIRCULANT_FP5_MDS_MATRIX = matrix.circulant([1, 1, 3, 4, 5])\n", - " CIRCULANT_FP6_MDS_MATRIX = matrix.circulant([1, 1, 3, 4, 5, 6])\n", - " CIRCULANT_FP7_MDS_MATRIX = matrix.circulant([1, 2, 3, 5, 5, 6, 7])\n", - " CIRCULANT_FP8_MDS_MATRIX = matrix.circulant([1, 2, 3, 5, 7, 8, 8, 9])\n", - " CIRCULANT_FP9_MDS_MATRIX = matrix.circulant([1, 3, 5, 6, 8, 9, 9, 10, 11])\n", - " CIRCULANT_FP10_MDS_MATRIX = matrix.circulant([1, 2, 5, 6, 8, 11, 11, 12, 13, 14])\n", - "\n", - " # 128-bit security level instantiations\n", - "\n", - " A_BLS_12_381_BASEFIELD_1_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_381_BASEFIELD,\n", - " n_cols=1,\n", - " security_level=128\n", - " )\n", - " A_BLS_12_381_BASEFIELD_2_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_381_BASEFIELD,\n", - " n_cols=2,\n", - " security_level=128\n", - " )\n", - " A_BLS_12_381_BASEFIELD_3_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_381_BASEFIELD,\n", - " n_cols=3,\n", - " security_level=128\n", - " )\n", - "\n", - " A_JUBJUB_BASEFIELD_1_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_381_SCALARFIELD,\n", - " n_cols=1,\n", - " security_level=128\n", - " )\n", - " A_JUBJUB_BASEFIELD_2_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_381_SCALARFIELD,\n", - " n_cols=2,\n", - " security_level=128\n", - " )\n", - " A_JUBJUB_BASEFIELD_3_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_381_SCALARFIELD,\n", - " n_cols=3,\n", - " security_level=128\n", - " )\n", - "\n", - " A_BLS_12_377_BASEFIELD_1_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_377_BASEFIELD,\n", - " n_cols=1,\n", - " security_level=128\n", - " )\n", - " A_BLS_12_377_BASEFIELD_2_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_377_BASEFIELD,\n", - " n_cols=2,\n", - " security_level=128\n", - " )\n", - " A_BLS_12_377_BASEFIELD_3_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_377_BASEFIELD,\n", - " n_cols=3,\n", - " security_level=128\n", - " )\n", - "\n", - " A_ED_ON_BLS_12_377_BASEFIELD_1_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_377_SCALARFIELD,\n", - " n_cols=1,\n", - " security_level=128\n", - " )\n", - " A_ED_ON_BLS_12_377_BASEFIELD_2_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_377_SCALARFIELD,\n", - " n_cols=2,\n", - " security_level=128\n", - " )\n", - " A_ED_ON_BLS_12_377_BASEFIELD_3_COL_128_BITS = AnemoiPermutation(\n", - " q=BLS12_377_SCALARFIELD,\n", - " n_cols=3,\n", - " security_level=128\n", - " )\n", - "\n", - " A_BN_254_BASEFIELD_1_COL_128_BITS = AnemoiPermutation(\n", - " q=BN_254_BASEFIELD,\n", - " n_cols=1,\n", - " security_level=128\n", - " )\n", - " A_BN_254_BASEFIELD_2_COL_128_BITS = AnemoiPermutation(\n", - " q=BN_254_BASEFIELD,\n", - " n_cols=2,\n", - " security_level=128\n", - " )\n", - " A_BN_254_BASEFIELD_3_COL_128_BITS = AnemoiPermutation(\n", - " q=BN_254_BASEFIELD,\n", - " n_cols=3,\n", - " security_level=128\n", - " )\n", - "\n", - " A_BN_254_SCALARFIELD_1_COL_128_BITS = AnemoiPermutation(\n", - " q=BN_254_SCALARFIELD,\n", - " n_cols=1,\n", - " security_level=128\n", - " )\n", - " A_BN_254_SCALARFIELD_2_COL_128_BITS = AnemoiPermutation(\n", - " q=BN_254_SCALARFIELD,\n", - " n_cols=2,\n", - " security_level=128\n", - " )\n", - " A_BN_254_SCALARFIELD_3_COL_128_BITS = AnemoiPermutation(\n", - " q=BN_254_SCALARFIELD,\n", - " n_cols=3,\n", - " security_level=128\n", - " )\n", - "\n", - " A_PALLAS_BASEFIELD_1_COL_128_BITS = AnemoiPermutation(\n", - " q=PALLAS_BASEFIELD,\n", - " n_cols=1,\n", - " security_level=128\n", - " )\n", - " A_PALLAS_BASEFIELD_2_COL_128_BITS = AnemoiPermutation(\n", - " q=PALLAS_BASEFIELD,\n", - " n_cols=2,\n", - " security_level=128\n", - " )\n", - " A_PALLAS_BASEFIELD_3_COL_128_BITS = AnemoiPermutation(\n", - " q=PALLAS_BASEFIELD,\n", - " n_cols=3,\n", - " security_level=128\n", - " )\n", - "\n", - " A_VESTA_BASEFIELD_1_COL_128_BITS = AnemoiPermutation(\n", - " q=VESTA_BASEFIELD,\n", - " n_cols=1,\n", - " security_level=128\n", - " )\n", - " A_VESTA_BASEFIELD_2_COL_128_BITS = AnemoiPermutation(\n", - " q=VESTA_BASEFIELD,\n", - " n_cols=2,\n", - " security_level=128\n", - " )\n", - " A_VESTA_BASEFIELD_3_COL_128_BITS = AnemoiPermutation(\n", - " q=VESTA_BASEFIELD,\n", - " n_cols=3,\n", - " security_level=128\n", - " )\n", - "\n", - " A_GOLDILOCKS_64_FIELD_4_COL_128_BITS = AnemoiPermutation(\n", - " q=GOLDILOCKS_64_FIELD,\n", - " n_cols=4,\n", - " security_level=128\n", - " )\n", - " A_GOLDILOCKS_64_FIELD_5_COL_128_BITS = AnemoiPermutation(\n", - " q=GOLDILOCKS_64_FIELD,\n", - " mat=CIRCULANT_FP5_MDS_MATRIX,\n", - " n_cols=5,\n", - " security_level=128)\n", - " A_GOLDILOCKS_64_FIELD_6_COL_128_BITS = AnemoiPermutation(\n", - " q=GOLDILOCKS_64_FIELD,\n", - " mat=CIRCULANT_FP6_MDS_MATRIX,\n", - " n_cols=6,\n", - " security_level=128)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4de5d23c", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "55940b58", - "metadata": {}, - "outputs": [], - "source": [ - "A_2 = AnemoiPermutation(q=BLS12_381_SCALARFIELD, alpha=None, n_rounds=None, n_cols=1, security_level=128)\n", - "A_4 = AnemoiPermutation(q=BLS12_381_SCALARFIELD, alpha=None, n_rounds=None, n_cols=2, security_level=128)\n", - "A_8 = AnemoiPermutation(q=BLS12_381_SCALARFIELD, alpha=None, n_rounds=None, n_cols=4, security_level=128)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "1714dd8a", - "metadata": {}, - "outputs": [], - "source": [ - "def h4(a,b,c,d):\n", - " return jive(A_4,4,[a,b,c,d])[0]\n", - "def h2(x,y):\n", - " return jive(A_2,2,[x,y])[0]\n", - "def h16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p):\n", - " return jive(A_4,16,[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p])[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "6fb511da", - "metadata": {}, - "outputs": [], - "source": [ - "F = FiniteField(52435875175126190479447740508185965837690552500527637822603658699938581184513)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "d149c137", - "metadata": {}, - "outputs": [], - "source": [ - "node = [F(52420321241384999566064542292299095305016967400362460415188733797566759865039)]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "1d57e955", - "metadata": {}, - "outputs": [], - "source": [ - "for i in range(32):\n", - " node.append(h2(node[len(node)-1],node[len(node)-1]))" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "cec930f7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[52420321241384999566064542292299095305016967400362460415188733797566759865039,\n", - " 34858305496126338994157940030491986528979209212364450444400553912850765881266,\n", - " 10060298215913168229635200403977750691324230455100780417729785627050381309370,\n", - " 37657570155741197049656950100032789787730277025585639680171537327433013443461,\n", - " 43105655934034421310242811462621484525299779534316435151634983301958386590294,\n", - " 26995182859207480491682003956450588969914099749120925411176915838714895859597,\n", - " 20506505055020577941071867474645787663044384365345823626928150837203592376386,\n", - " 28572094676551257704272872821343757206000648895775506512709995566916218827978,\n", - " 42524234163555570540586430006594798114476518357138366521973315347172229388899,\n", - " 41720788377705156799884270768728291039459929734546201246522570875378721139734,\n", - " 19457067441998710724584163548533636242139735070911298751448507771105190878240,\n", - " 8747845488093882108955302281707201874091653422842805672577538032173082380577,\n", - " 32991277692425495249603612794268597446471245662501917149041880681619316027114,\n", - " 30655955250074575922973891541584280309476230618462427477515213028232262267669,\n", - " 27589362888766877196787781531059520230924205436220782390585594394025165647971,\n", - " 15645944042222251287613100624160349973331200688824660057615726288833818756514,\n", - " 41103122236802131675820266308354013027201078225983702886429283924123677508556,\n", - " 3604164466072625520894970148301026556144753129448476532101785358537506096936,\n", - " 10585966731059558810772490617844611395546337996000903904158639165815316582412,\n", - " 44787298630363239445106426135114786217694920972141104035413355784967544392580,\n", - " 11772976849012656283054200415125989128435331342580385899899773526676914980414,\n", - " 15197006870489803770703282231645241096319546397552004839565531786070275618798,\n", - " 36398756779607558742883648673215853033540478201191947706475043044754192649893,\n", - " 38951794974737200048927570198923950704267440020829757596996165598475390602125,\n", - " 15900802340706488974605017961329535810615710838998007293710791187420339373597,\n", - " 35832135664352859533862622204762117961594057848987503662357696301651717440970,\n", - " 3937682840062878094199919914593715602931688125476849557109656097454977607844,\n", - " 19836996935489067263887759688182600655629071982397596249304526919529389472797,\n", - " 8093543369109841781730274069993144570875885414940499814911886408152141385107,\n", - " 28356127876292249971214936516736218558068803693719384306823563563957757910724,\n", - " 41961713207670554534854109355161769432029683361231582286797275988443399524548,\n", - " 8869703232174461463933555757474727782885662615993846320574348981267130192493,\n", - " 19862493525506141505206198326555704277551523209826035871691450692641445027728]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "h2(node[len(node)-1],node[len(node)-1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e3109be1", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "SageMath 9.5", - "language": "sage", - "name": "sagemath" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/Proof of Leadership/leadership_anemoi_sha.circom b/Proof of Leadership/leadership_anemoi_sha.circom index 9d6040f..0698402 100644 --- a/Proof of Leadership/leadership_anemoi_sha.circom +++ b/Proof of Leadership/leadership_anemoi_sha.circom @@ -231,7 +231,7 @@ template membership_checker(){ } -template anemoi_proof_of_leadership(){ +template anemoi_sha_proof_of_leadership(){ signal input epoch_nonce; //F_p (BLS12-381 scalar field) signal input slot_number; //F_p (BLS12-381 scalar field) signal input t0; // Precomputed threshold elements in F_p @@ -314,4 +314,4 @@ template anemoi_proof_of_leadership(){ } -component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = anemoi_proof_of_leadership(); \ No newline at end of file +component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = anemoi_sha_proof_of_leadership(); \ No newline at end of file diff --git a/Proof of Leadership/leadership_poseidon.circom b/Proof of Leadership/leadership_poseidon.circom index 69ff6c7..1da5912 100644 --- a/Proof of Leadership/leadership_poseidon.circom +++ b/Proof of Leadership/leadership_poseidon.circom @@ -215,7 +215,7 @@ template membership_checker(){ } -template anemoi_proof_of_leadership(){ +template poseidon_proof_of_leadership(){ signal input epoch_nonce; //F_p (BLS12-381 scalar field) signal input slot_number; //F_p (BLS12-381 scalar field) signal input t0; // Precomputed threshold elements in F_p @@ -298,4 +298,4 @@ template anemoi_proof_of_leadership(){ } -component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = anemoi_proof_of_leadership(); \ No newline at end of file +component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = poseidon_proof_of_leadership(); \ No newline at end of file diff --git a/Proof of Leadership/leadership_poseidon_sha.circom b/Proof of Leadership/leadership_poseidon_sha.circom index 44ff1cb..45935f4 100644 --- a/Proof of Leadership/leadership_poseidon_sha.circom +++ b/Proof of Leadership/leadership_poseidon_sha.circom @@ -232,7 +232,7 @@ template membership_checker(){ } -template anemoi_proof_of_leadership(){ +template poseidon_sha_proof_of_leadership(){ signal input epoch_nonce; //F_p (BLS12-381 scalar field) signal input slot_number; //F_p (BLS12-381 scalar field) signal input t0; // Precomputed threshold elements in F_p @@ -315,4 +315,4 @@ template anemoi_proof_of_leadership(){ } -component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = anemoi_proof_of_leadership(); \ No newline at end of file +component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = poseidon_sha_proof_of_leadership(); \ No newline at end of file