From a40e9b6cc442b7e504179cbc0131f21e5451b6f8 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Thu, 8 Jun 2023 12:02:58 +0200 Subject: [PATCH] add ccs-plonk.sage Also rename r1cs-ccs.sage to ccs-r1cs.sage, so both r1cs & plonk scripts are printed together in the directory. --- ccs-plonk.sage | 127 +++++++++++++++++++++++++++++++++ r1cs-ccs.sage => ccs-r1cs.sage | 0 2 files changed, 127 insertions(+) create mode 100644 ccs-plonk.sage rename r1cs-ccs.sage => ccs-r1cs.sage (100%) diff --git a/ccs-plonk.sage b/ccs-plonk.sage new file mode 100644 index 0000000..53bc554 --- /dev/null +++ b/ccs-plonk.sage @@ -0,0 +1,127 @@ +# Plonk-CCS (https://eprint.iacr.org/2023/552) Sage prototype + +# utils +def matrix_vector_product(M, v): + n = M.nrows() + r = [F(0)] * n + for i in range(0, n): + for j in range(0, M.ncols()): + r[i] += M[i][j] * v[j] + return r +def hadamard_product(a, b): + n = len(a) + r = [None] * n + for i in range(0, n): + r[i] = a[i] * b[i] + return r +def vec_add(a, b): + n = len(a) + r = [None] * n + for i in range(0, n): + r[i] = a[i] + b[i] + return r +def vec_elem_mul(a, s): + r = [None] * len(a) + for i in range(0, len(a)): + r[i] = a[i] * s + return r +# end of utils + + +# can use any finite field, using a small one for the example +F = GF(101) +# F = GF(21888242871839275222246405745257275088696311157297823662689037894645226208583) + + +# The following CCS instance values have been provided by Carlos +# (https://github.com/CPerezz) and Edu (https://github.com/ed255), +# and this sage script was made to check the CCS relation. + +## Checks performed by this Plonk/CCS instance: +# - binary check for x0, x1 +# - 2*x2 + 2*x3 == x4 +M0 = matrix([ + [F(0), 1, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 0], + [0, 0, 0, 1, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 1], + ]) +M1 = matrix([ + [F(0), 1, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0], + [0, 0, 0, 0, 0, 0, 1], + ]) +M2 = matrix([ + [F(0), 1, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 0, 0, 0, 1], + ]) +M3 = matrix([ + [F(1), 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + ]) +M4 = matrix([ + [F(0), 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [2, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + ]) +M5 = matrix([ + [F(0), 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [2, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + ]) +M6 = matrix([ + [F(-1), 0, 0, 0, 0, 0, 0], + [-1, 0, 0, 0, 0, 0, 0], + [-1, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + ]) +M7 = matrix([ + [F(0), 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + ]) + +z = [F(1), 0, 1, 2, 3, 10, 42] + +print("z:", z) + +assert len(z) == M0.ncols() + +# CCS parameters +n = M0.ncols() # == len(z) +m = M0.nrows() +t=8 +q=5 +d=3 +S = [[3,0,1], [4,0], [5,1], [6,2], [7]] +c = [1, 1, 1, 1, 1] + +M = [M0,M1,M2,M3,M4,M5,M6,M7] + +print("CCS values:") +print("n: %s, m: %s, t: %s, q: %s, d: %s" % (n, m, t, q, d)) +print("M:", M) +print("z:", z) +print("S:", S) +print("c:", c) + +# check CCS relation (this is agnostic to Plonk, for any CCS instance) +r = [F(0)] * m +for i in range(0, q): + hadamard_output = [F(1)]*m + for j in S[i]: + hadamard_output = hadamard_product(hadamard_output, + matrix_vector_product(M[j], z)) + + r = vec_add(r, vec_elem_mul(hadamard_output, c[i])) + +print("\nCCS relation check (∑ cᵢ ⋅ ◯ Mⱼ z == 0):", r == [0]*m) +assert r == [0]*m diff --git a/r1cs-ccs.sage b/ccs-r1cs.sage similarity index 100% rename from r1cs-ccs.sage rename to ccs-r1cs.sage