All the codes below are python with SageMath.
K = GF(101)
# y^2=x^3+3
E = EllipticCurve(K,[0,0,0,0,3])
G = E(1,2) # <G> is subgroup of order 17, 17*G=inf
for i in range(1,18):
print(i*G)
(1 : 2 : 1)
(68 : 74 : 1)
(26 : 45 : 1)
(65 : 98 : 1)
(12 : 32 : 1)
(32 : 42 : 1)
(91 : 35 : 1)
(18 : 49 : 1)
(18 : 52 : 1)
(91 : 66 : 1)
(32 : 59 : 1)
(12 : 69 : 1)
(65 : 3 : 1)
(26 : 56 : 1)
(68 : 27 : 1)
(1 : 99 : 1)
(0 : 1 : 0)
embedding degree
The degree of the extension field of characteristic
If r is relatively prime to the charactersitc p of the field, then there will be exactly
extension field
Find an irreducible polynomial of degree
# use the twisted curve technique from pairing for beginner
# to get another generator of order 17 (G2)
# (36, 31*u)
mod(36^3,101)+3 == mod(31^2,101)*(-2) # x^3+3 = y^2 mod 101
True
# define field extention F_{101^2} over F_101 with irreducible poly x^2+2
del(x)
x=var("x")
K2.<u> = GF(101^2, modulus=x^2 + 2,name='x')
# elliptic curve over F_{101^2}
E2=EllipticCurve(K2,[0,0,0,0,3])
P=E2(36,31*u)
2*P
(90 : 82*u : 1)
trusted setup
a circuit with
suppose secret random number
Statement
(Pythagorean Triangle) Find
General form of plonk circuit is
The Pythagorean circuit becomes
In matrix form we have:
a | b | c | q_L | q_R | q_O | q_M | q_C |
---|---|---|---|---|---|---|---|
3 | 3 | 9 | 0 | 0 | -1 | 1 | 0 |
4 | 4 | 16 | 0 | 0 | -1 | 1 | 0 |
5 | 5 | 25 | 0 | 0 | -1 | 1 | 0 |
9 | 16 | 25 | 1 | 1 | -1 | 0 | 0 |
where
polynomial interpolation
We need subgroup of order
For polynomial
Notice
omega=matrix(GF(17),[[1,1,1,1],[1,4,16,13],[1,16,1,16],[1,13,16,4]])
omega.inverse()
[13 13 13 13]
[13 16 4 1]
[13 4 13 4]
[13 1 4 16]
Thus all the polynomials for each row are:
copy constraint
From
encode permutation from copy constraint as polynomial
If we use
# fine the polynomial by apply inverse FFT
H=[1,4,16,13] # values of S_{sigma1}(x) before permutation
H1=[2,8,15,9] # values of S_{sigma2}(x) before permutation
H2=[3,12,14,5]
perm = Permutation('(1,2)(16,15)(4,8)(13,3)(9,12)(14,5)') # permutation on the evaluation domain of polynomials
val = [[perm(i)] for i in H] # values of S_{sigma1}(x) after permutation
val1 = [[perm(i)] for i in H1] # values of S_{sigma2}(x) after permutation
val2 = [[perm(i)] for i in H2]
p=omega.inverse()*matrix(GF(17),val)
p1=omega.inverse()*matrix(GF(17),val1)
p2=omega.inverse()*matrix(GF(17),val2)
print(p.transpose())
print(p1.transpose())
print(p2.transpose())
[ 7 13 10 6]
[ 4 0 13 1]
[ 6 7 3 14]
# check the polynomial evaluation on [1,omega,omega^2,omega^3]
perm = Permutation('(1,2)(16,15)(4,8)(13,3)(9,12)(14,5)')
H=[1,4,16,13]
H1=[2,8,15,9]
H2=[3,12,14,5]
R.<t>=PolynomialRing(GF(17))
p1=7+13*t+10*t^2+6*t^3
l1=[int(p1(x)) for x in H]
print(l1,[perm(i) for i in H]) # should equal
p2=4+13*t^2+t^3
l2=[int(p2(x)) for x in H]
print(l2,[perm(i) for i in H1]) # should equal
p3=6+7*t+3*t^2+14*t^3
l3=[int(p3(x)) for x in H]
print(l3,[perm(i) for i in H2])
[2, 8, 15, 3] [2, 8, 15, 3]
[1, 4, 16, 12] [1, 4, 16, 12]
[13, 9, 5, 14] [13, 9, 5, 14]
commit a,b,c
With
Generating random numbers in
Finally, we commit them with SRS
def commit_to_curve(coeff, base):
commitment = 0*base;
s = 2 # secret value
for i in range(len(coeff)):
commitment += coeff[i]*(s^i*base)
return commitment
a=[14,6,3,3,4,7]
b=[12,9,14,13,12,11]
c=[4,6,11,4,2,16]
comm_a = commit_to_curve(a,G)
comm_b = commit_to_curve(b,G)
comm_c = commit_to_curve(c,G)
print(comm_a,comm_b,comm_c)
(91 : 66 : 1) (26 : 45 : 1) (91 : 35 : 1)
Generate
# commitment of z(x)
omega=matrix(GF(17),[[1,1,1,1],[1,4,16,13],[1,16,1,16],[1,13,16,4]])
acc=omega.inverse()*matrix(GF(17),[[1],[3],[9],[4]])
coeff_z = [10,5,8,14,7,11,14]
commit_to_curve(coeff_z,G)
(32 : 59 : 1)
Compute quotient challenge
Then split into degree
Output
We have
And the commitment
omega=matrix(GF(17),[[1,1,1,1],[1,4,16,13],[1,16,1,16],[1,13,16,4]])
R.<x>=PolynomialRing(GF(17))
# Lagrange polynomial L_1(x)
L_1=omega.inverse()*matrix(GF(17),[[1],[0],[0],[0]])
l1=13+13*x+13*x^2+13*x^3
a = 14+6*x+3*x^2+3*x^3+4*x^4+7*x^5
b =12+9*x+14*x^2+13*x^3+12*x^4+11*x^5
c=4+6*x+11*x^2+4*x^3+2*x^4+16*x^5
q_L=13+x+4*x^2+16*x^3
q_R =13+x+4*x^2+16*x^3
q_O = 16
q_M=5+16*x+13*x^2+x^3
z = 10+5*x+8*x^2+14*x^3+7*x^4+11*x^5+14*x^6
zomega = 10+3*x+9*x^2+12*x^3+7*x^4+10*x^5+3*x^6
sig1=7+13*x+10*x^2+6*x^3
sig2=4+13*x^2+x^3
sig3=6+7*x+3*x^2+14*x^3
t1=(a*b*q_M + a*q_L +b*q_R+c*q_O)
t2=(a+12*x+13)*(b+12*2*x+13)*(c+12*3*x+13)*z*15
t3=(a+12*sig1+13)*(b+12*sig2+13)*(c+12*sig3+13)*zomega*15
t4=(z-1)*l1*15*15
final=t1+t2-t3+t4
t=final/(x^4-1)
t
11*x^17 + 7*x^16 + 2*x^15 + 16*x^14 + 6*x^13 + 15*x^12 + x^11 + 10*x^10 + 2*x^9 + x^8 + 8*x^7 + 13*x^6 + 13*x^5 + 9*x^3 + 13*x^2 + 16*x + 11
tlow=[11,16,13,9,0,13]
tmid=[13,8,1,2,10,1]
thi=[15,6,16,2,7,11]
tlow=commit_to_curve(tlow,G)
tmid=commit_to_curve(tmid,G)
thi=commit_to_curve(thi,G)
print(tlow,tmid,thi)
(12 : 32 : 1) (26 : 45 : 1) (91 : 66 : 1)
Linearization. Compute evaluation challenge
Compute opening evaluations
Compute linearization polynomial (linear w.r.p commitment values):
The definition of
Compute linearization evaluation
Supose
Output
Compute opening challenge
Compute opening proof polynomial
Compute opening proof polynomial
Output
Given
FF=GF(17)
omega=FF(4);zeta=FF(5)
v=FF(12);tbar=FF(1);abar=FF(15);bbar=FF(13);cbar=FF(5);
sig1bar=FF(1);sig2bar=FF(12);zomega=FF(15);rbar=FF(15)
R.<x>=PolynomialRing(GF(17))
tlow=11+16*x+13*x^2+9*x^3+13*x^5
tmid=13+8*x+x^2+2*x^3+10*x^4+x^5
thi=15+6*x+16*x^2+2*x^3+7*x^4+11*x^5
r=16*x+9*x^2+13*x^3+8*x^4+15*x^5+16*x^6
sig1=7+13*x+10*x^2+6*x^3
sig2=4+13*x^2+x^3
z = 10+5*x+8*x^2+14*x^3+7*x^4+11*x^5+14*x^6
term1=tlow+zeta^6*tmid+zeta^12*thi-tbar
term2=v*(r-rbar)
term3=v^2*(a-abar)+v^3*(b-bbar)+v^4*(c-cbar)
term4=v^5*(sig1-sig1bar)+v^6*(sig2-sig2bar)
Wz=(term1+term2+term3+term4)/(x-zeta)
Wzw=(z-zomega)/(x-zeta*omega)
wz=[16,13,2,9,3,5]
wzw=[13,14,2,13,2,14]
c1=commit_to_curve(wz,G)
c2=commit_to_curve(wzw,G)
print(c1,c2)
(91 : 35 : 1) (65 : 98 : 1)
In our case,
R.<x>=PolynomialRing(GF(17))
omega=matrix(GF(17),[[1,1,1,1],[1,4,16,13],[1,16,1,16],[1,13,16,4]])
qm=omega.inverse()*matrix(GF(17),[[1],[1],[1],[0]]) #[ 5 16 13 1]
commit_to_curve([ 5, 16, 13, 1],G) # [q_M]=(12,69)
(12 : 69 : 1)
Let's check steps
Let's check
Let's check
The other terms are easy to check as well.
FF=GF(17)
zeta=FF(5)
#4.
zh=zeta^4-1
#5.
l1=(zeta^4-1)/(4*(zeta-1)) #l1=5
#7.
alpha=FF(15);beta=FF(12);gamma=FF(13)
[a,b,c,sig1,sig2,zw,r]=[FF(x) for x in [15,13,5,1,12,15,15]]
t=(r-(a+beta*sig1+gamma)*(b+beta*sig2+gamma)*(c+gamma)*alpha-l1*alpha^2)/zh
#8
zeta=5;alpha=15;beta=12;gamma=13;l1=5
[a,b,c,sig1,sig2,zw,r] = [15,13,5,1,12,15,15]
k1=2;k2=3;v=12;u=4;qm=E(12,69);ql=E(32,42);qr=E(32,42);qo=E(1,99)
ssig1=E(68,74);ssig2=E(65,3);ssig3=E(18,49)
z=E(32,59)
dn1=a*b*v*qm+a*v*ql+b*v*qr+c*v*qo
dn2a=(a+beta*zeta+gamma)*(b+beta*k1*zeta+gamma)*(c+beta*k2*zeta+gamma)*alpha*v+l1*alpha^2*v+u
dn2=dn2a*z
dn3a=(a+beta*sig1+gamma)*(b+beta*sig2+gamma)*a*v*beta*zw
dn3=dn3a*ssig3
D=dn1+dn2+dn3 # (0:1:0)=inf
#9.
n=4
[ca,cb,cc,cz,ctlo,ctmid,cthi,cwz,cwzw]=[E(91,66),E(26,45),E(91,35),E(32,59),E(12,32),E(26,45),E(91,66),E(91,35),E(65,98)]
F=ctlo+zeta^(n+2)*ctmid+zeta^(2*n+4)*cthi+D+v^2*ca+v^3*cb+v^4*cc+v^5*ssig1+v^6*ssig2
#10.
t=1
Es=t+v*r+v^2*a+v^3*b+v^4*c+v^5*sig1+v^6*sig2+u*zw
E0=Es*G
#11.
left1=cwz+u*cwzw
left2=2*G
w=4
right1=zeta*cwz+u*zeta*w*cwzw+F-E0
right2=G
# 11.
K = GF(101)
# y^2=x^3+3
E = EllipticCurve(K,[0,0,0,0,3])
# define field extention F_{101^2} over F_101 with irreducible poly x^2+2
# x is poluted so we need to reset them before define K2
del(x)
x=var("x")
K2.<u> = GF(101^2, modulus=x^2 + 2,name='x')
# elliptic curve over F_{101^2}
E2=EllipticCurve(K2,[0,0,0,0,3])
P=E2(36,31*u)
2*P
public
plonk
zkp