@ -0,0 +1,112 @@ |
|||||
|
# R1CS-to-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) |
||||
|
|
||||
|
# R1CS matrices for: x^3 + x + 5 = y (example from article |
||||
|
# https://www.vitalik.ca/general/2016/12/10/qap.html ) |
||||
|
A = matrix([ |
||||
|
[F(0), 1, 0, 0, 0, 0], |
||||
|
[0, 0, 0, 1, 0, 0], |
||||
|
[0, 1, 0, 0, 1, 0], |
||||
|
[5, 0, 0, 0, 0, 1], |
||||
|
]) |
||||
|
B = matrix([ |
||||
|
[F(0), 1, 0, 0, 0, 0], |
||||
|
[0, 1, 0, 0, 0, 0], |
||||
|
[1, 0, 0, 0, 0, 0], |
||||
|
[1, 0, 0, 0, 0, 0], |
||||
|
]) |
||||
|
C = matrix([ |
||||
|
[F(0), 0, 0, 1, 0, 0], |
||||
|
[0, 0, 0, 0, 1, 0], |
||||
|
[0, 0, 0, 0, 0, 1], |
||||
|
[0, 0, 1, 0, 0, 0], |
||||
|
]) |
||||
|
|
||||
|
print("R1CS matrices:") |
||||
|
print("A:", A) |
||||
|
print("B:", B) |
||||
|
print("C:", C) |
||||
|
|
||||
|
|
||||
|
z = [F(1), 3, 35, 9, 27, 30] |
||||
|
print("z:", z) |
||||
|
|
||||
|
assert len(z) == A.ncols() |
||||
|
|
||||
|
n = A.ncols() # == len(z) |
||||
|
m = A.nrows() |
||||
|
# l = len(io) # not used for now |
||||
|
|
||||
|
# check R1CS relation |
||||
|
Az = matrix_vector_product(A, z) |
||||
|
Bz = matrix_vector_product(B, z) |
||||
|
Cz = matrix_vector_product(C, z) |
||||
|
print("\nR1CS relation check (Az ∘ Bz == Cz):", hadamard_product(Az, Bz) == Cz) |
||||
|
assert hadamard_product(Az, Bz) == Cz |
||||
|
|
||||
|
|
||||
|
# Translate R1CS into CCS: |
||||
|
print("\ntranslate R1CS into CCS:") |
||||
|
|
||||
|
# fixed parameters (and n, m, l are direct from R1CS) |
||||
|
t=3 |
||||
|
q=2 |
||||
|
d=2 |
||||
|
S1=[0,1] |
||||
|
S2=[2] |
||||
|
S = [S1, S2] |
||||
|
c0=1 |
||||
|
c1=-1 |
||||
|
c = [c0, c1] |
||||
|
|
||||
|
M = [A, B, C] |
||||
|
|
||||
|
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 |
||||
|
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 |