|
|
@ -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 |