narodnik 5 лет назад
Родитель
Сommit
181108ca90

+ 26 - 0
doc/halo1-arithmetization.md

@@ -86,3 +86,29 @@ r(X, 1) s'(X, Y) &= && \; \vec{a_1} X X^{-1} Y^N u_1(Y) + \vec{a_2} X^2 X^{-2} Y
 & && + \cdots \\
 & && + \cdots \\
 &= && \; \sum_{i = 1}^N \vec{a_i} \cdot Y^N u_i(Y) + \sum_{i = 1}^N \vec{b_i} \cdot Y^N v_i(Y) + \sum_{i = 1}^N \vec{c_i} \cdot (Y^N w_i(Y) - Y^i - Y^{-i})
 &= && \; \sum_{i = 1}^N \vec{a_i} \cdot Y^N u_i(Y) + \sum_{i = 1}^N \vec{b_i} \cdot Y^N v_i(Y) + \sum_{i = 1}^N \vec{c_i} \cdot (Y^N w_i(Y) - Y^i - Y^{-i})
 \end{alignat*}
 \end{alignat*}
+
+# Simplified Example
+
+Let $x = 4, y = 6$ then $xy = 24$, and $\vec{a} = (4), \vec{b} = (6), \vec{c} = (24)$ with no linear constraints (all selectors set to zero).
+
+$$r(X, Y) = 4XY + 6X^{-1}Y^{-1} + 24 X^{-2} Y^{-2}$$
+$$t(X, Y) = r(X, 1) r(X, Y) - X^{N + 1} Y - X^{N + 1} Y^{-1}$$
+$$r(X, 1) = 4X + 6X^{-1} + 24 X^{-2}$$
+\begin{alignat*}{2}
+r(X, 1) r(X, Y) &= && \; 4X (4XY + 6X^{-1}Y^{-1} + 24 X^{-2} Y^{-2}) \\
+& && + 6X^{-1} (4XY + 6X^{-1}Y^{-1} + 24 X^{-2} Y^{-2}) \\
+& && + 24X^{-2} (4XY + 6X^{-1}Y^{-1} + 24 X^{-2} Y^{-2}) \\
+&= && \; 16X^2 Y + 24 Y^{-1} + 96 X^{-1} Y^{-2} \\
+& && + 24Y + 36 X^{-2} Y^{-1} + 144 X^{-3} Y^{-2} \\
+& && + 96 X^{-1} Y + 144 X^{-3} Y^{-1} + 576 X^{-4} Y^{-2} \\
+r(X, 1) (- X^{N + 1} Y - X^{N + 1} Y^{-1}) &= && \; 4X (- X^{N + 1} Y - X^{N + 1} Y^{-1}) \\
+& && + 6X^{-1} (- X^{N + 1} Y - X^{N + 1} Y^{-1}) \\
+& && + 24 X^{-2} (- X^{N + 1} Y - X^{N + 1} Y^{-1}) \\
+&= && \; - 4X^{N + 2} Y - 4X^{N + 2} Y^{-1}) \\
+& && - 6X^N Y - 6X^N Y^{-1} \\
+& && - 24 X^{N - 1} Y - 24 X^{N - 1} Y^{-1}) \\
+&= && \; - 4X^3 Y - 4X^3 Y^{-1}) \\
+& && - 6X Y - 6X Y^{-1} \\
+& && - 24 Y - 24 Y^{-1} \\
+\end{alignat*}
+

+ 24 - 5
scripts/halo/groth_poly_commit.py

@@ -3,7 +3,7 @@
 # This file was *autogenerated* from the file groth_poly_commit.sage
 # This file was *autogenerated* from the file groth_poly_commit.sage
 from sage.all_cmdline import *   # import sage library
 from sage.all_cmdline import *   # import sage library
 
 
-_sage_const_0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 = Integer(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001); _sage_const_0x00 = Integer(0x00); _sage_const_0x05 = Integer(0x05); _sage_const_0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 = Integer(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000); _sage_const_0x02 = Integer(0x02); _sage_const_0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 = Integer(0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001); _sage_const_1000 = Integer(1000); _sage_const_110 = Integer(110); _sage_const_2 = Integer(2); _sage_const_56 = Integer(56); _sage_const_89 = Integer(89); _sage_const_6543 = Integer(6543); _sage_const_77 = Integer(77)
+_sage_const_0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 = Integer(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001); _sage_const_0x00 = Integer(0x00); _sage_const_0x05 = Integer(0x05); _sage_const_0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 = Integer(0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000); _sage_const_0x02 = Integer(0x02); _sage_const_0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001 = Integer(0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001); _sage_const_1000 = Integer(1000); _sage_const_1 = Integer(1); _sage_const_110 = Integer(110); _sage_const_2 = Integer(2); _sage_const_56 = Integer(56); _sage_const_89 = Integer(89); _sage_const_6543 = Integer(6543); _sage_const_0 = Integer(0); _sage_const_77 = Integer(77)
 import numpy as np
 import numpy as np
 from collections import namedtuple
 from collections import namedtuple
 
 
@@ -45,8 +45,19 @@ def dot_product(x, y):
             result += int(x_i) * y_i
             result += int(x_i) * y_i
     return result
     return result
 
 
-def create_proof(a, x):
-    x = np.array([x**i for i in range(len(a))])
+def poly_commit(p):
+    # Sage randomly orders terms. No guarantee about ordering.
+    #a = np.array(p.coefficients())
+    a = np.array([p[i] for i in range(p.degree() + _sage_const_1 )])
+    r = Scalar.random_element()
+    C_x = int(r) * H + dot_product(a, G_vec)
+    return (r, C_x)
+
+def create_proof(p, r, x):
+    a = np.array([p[i] for i in range(p.degree() + _sage_const_1 )])
+    #a = np.array(p.coefficients())
+
+    x = np.array([x**i for i in range(p.degree() + _sage_const_1 )])
     # Evaluate the polynomial
     # Evaluate the polynomial
     z = a.dot(x)
     z = a.dot(x)
 
 
@@ -57,7 +68,7 @@ def create_proof(a, x):
     # Commitments
     # Commitments
 
 
     t = Scalar.random_element()
     t = Scalar.random_element()
-    r = Scalar.random_element()
+    #r = Scalar.random_element()
     s = Scalar.random_element()
     s = Scalar.random_element()
 
 
     C_z = int(t) * H + int(z) * G
     C_z = int(t) * H + int(z) * G
@@ -148,11 +159,19 @@ def verify_proof(proof, x):
 
 
     return True
     return True
 
 
+R = LaurentPolynomialRing(Scalar, names=('x',)); (x,) = R._first_ngens(1)
 a = np.array([
 a = np.array([
     Scalar(_sage_const_110 ), Scalar(_sage_const_56 ), Scalar(_sage_const_89 ), Scalar(_sage_const_6543 ), Scalar(_sage_const_2 )
     Scalar(_sage_const_110 ), Scalar(_sage_const_56 ), Scalar(_sage_const_89 ), Scalar(_sage_const_6543 ), Scalar(_sage_const_2 )
 ])
 ])
+p = _sage_const_0 
+for i, a_i in enumerate(a):
+    p += a_i * x**i
+print(p)
 xx = Scalar(_sage_const_77 )
 xx = Scalar(_sage_const_77 )
-proof = create_proof(a, xx)
+r, commit = poly_commit(p)
+proof = create_proof(p, r, xx)
 assert verify_proof(proof, xx)
 assert verify_proof(proof, xx)
+assert proof.poly_commit == commit
+assert proof.value == p(xx)
 
 
 
 

+ 16 - 5
scripts/halo/groth_poly_commit.sage

@@ -39,10 +39,19 @@ def dot_product(x, y):
             result += int(x_i) * y_i
             result += int(x_i) * y_i
     return result
     return result
 
 
-def create_proof(p, x):
-    a = np.array(p.coefficients())
+def poly_commit(p):
+    # Sage randomly orders terms. No guarantee about ordering.
+    #a = np.array(p.coefficients())
+    a = np.array([p[i] for i in range(p.degree() + 1)])
+    r = Scalar.random_element()
+    C_x = int(r) * H + dot_product(a, G_vec)
+    return (r, C_x)
 
 
-    x = np.array([x**i for i in range(len(a))])
+def create_proof(p, r, x):
+    a = np.array([p[i] for i in range(p.degree() + 1)])
+    #a = np.array(p.coefficients())
+
+    x = np.array([x**i for i in range(p.degree() + 1)])
     # Evaluate the polynomial
     # Evaluate the polynomial
     z = a.dot(x)
     z = a.dot(x)
 
 
@@ -53,7 +62,7 @@ def create_proof(p, x):
     # Commitments
     # Commitments
 
 
     t = Scalar.random_element()
     t = Scalar.random_element()
-    r = Scalar.random_element()
+    #r = Scalar.random_element()
     s = Scalar.random_element()
     s = Scalar.random_element()
 
 
     C_z = int(t) * H + int(z) * G
     C_z = int(t) * H + int(z) * G
@@ -153,7 +162,9 @@ for i, a_i in enumerate(a):
     p += a_i * x**i
     p += a_i * x**i
 print(p)
 print(p)
 xx = Scalar(77)
 xx = Scalar(77)
-proof = create_proof(p, xx)
+r, commit = poly_commit(p)
+proof = create_proof(p, r, xx)
 assert verify_proof(proof, xx)
 assert verify_proof(proof, xx)
+assert proof.poly_commit == commit
 assert proof.value == p(xx)
 assert proof.value == p(xx)
 
 

+ 49 - 2
scripts/halo/halo1.sage

@@ -1,6 +1,7 @@
 import numpy as np
 import numpy as np
-from groth_poly_commit import K, create_proof, verify_proof
+from groth_poly_commit import Scalar, poly_commit, create_proof, verify_proof
 
 
+K = Scalar
 # Just use the same finite field we put in the polynomial commitment scheme file
 # Just use the same finite field we put in the polynomial commitment scheme file
 #p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
 #p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
 #K = FiniteField(p)
 #K = FiniteField(p)
@@ -165,12 +166,16 @@ for i in range(1, 4 + 1):
 # Commit to r(X, Y)
 # Commit to r(X, Y)
 
 
 s_prime_x_y = y**n * s_x_y
 s_prime_x_y = y**n * s_x_y
-for i in range(n, 1):
+for i in range(1, n):
     s_prime_x_y -= (y**i + y**-i) * x**(i + n)
     s_prime_x_y -= (y**i + y**-i) * x**(i + n)
 
 
 r_x_1 = r_x_y(y=K(1))
 r_x_1 = r_x_y(y=K(1))
 t_x_y = r_x_1 * (r_x_y + s_prime_x_y) - y**n * k_y
 t_x_y = r_x_1 * (r_x_y + s_prime_x_y) - y**n * k_y
 
 
+# This can be opened to r(X, Y) since r(X, Y) = r(XY, 1)
+r_x_1_scaled = (r_x_1 * x**(3*n - 1)).univariate_polynomial()
+rx1_commit_blind, rx1_commit = poly_commit(r_x_1_scaled)
+
 print("===================")
 print("===================")
 print(" t(X, Y)")
 print(" t(X, Y)")
 print("===================")
 print("===================")
@@ -212,6 +217,24 @@ print(t_x.dict())
 print()
 print()
 print("Constant coefficient:", t_x.constant_coefficient())
 print("Constant coefficient:", t_x.constant_coefficient())
 
 
+# Split the polynomial into low and hi versions
+t_lo_x = 0
+t_hi_x = 0
+smallest_power = -min(t_x.dict().keys())
+for power, coeff in t_x.dict().items():
+    assert power != 0
+    if power < 0:
+        t_lo_x += x**(smallest_power + power) * coeff
+    else:
+        t_hi_x += x**(power - 1) * coeff
+d = t_lo_x.degree() + 1
+t_lo_x = t_lo_x.univariate_polynomial()
+t_hi_x = t_hi_x.univariate_polynomial()
+assert (t_lo_x * x**-d + t_hi_x * x).univariate_polynomial() == t_x
+
+T_lo_commit_blind, T_lo = poly_commit(t_lo_x)
+T_hi_commit_blind, T_hi = poly_commit(t_hi_x)
+
 # zkV2
 # zkV2
 # Send a random z
 # Send a random z
 challenge_z = K.random_element()
 challenge_z = K.random_element()
@@ -226,8 +249,32 @@ t = t_x_y(x=challenge_z, y=challenge_y)
 # Evaluate s = s(z, y)
 # Evaluate s = s(z, y)
 s = s_prime_x_y(x=challenge_z, y=challenge_y)
 s = s_prime_x_y(x=challenge_z, y=challenge_y)
 
 
+# Calculate equivalent openings
+# s'(X, Y) is known by both prover and verifier
+a_proof = create_proof(r_x_1_scaled, rx1_commit_blind, challenge_z)
+assert a_proof.poly_commit == rx1_commit
+b_proof = create_proof(r_x_1_scaled, rx1_commit_blind, challenge_y * challenge_z)
+assert b_proof.poly_commit == rx1_commit
+t_proof_lo = create_proof(t_lo_x, T_lo_commit_blind, challenge_z)
+assert t_proof_lo.poly_commit == T_lo
+t_proof_hi = create_proof(t_hi_x, T_hi_commit_blind, challenge_z)
+assert t_proof_hi.poly_commit == T_hi
+
+# Signature of correct computation not yet implemented
+# So just use s for now as is
+
+# Scaling factor
+verifier_rescale = challenge_z**(-3*n + 1)
+assert a_proof.value * verifier_rescale == a
+verifier_rescale = (challenge_y * challenge_z)**(-3*n + 1)
+assert b_proof.value * verifier_rescale == b
+
 # zkV3
 # zkV3
 # Recalculate t from a, b and s
 # Recalculate t from a, b and s
+t_new = t_proof_lo.value * challenge_z**-d + t_proof_hi.value * challenge_z
+assert t_new == t
+t = t_new
+
 k = (y**n * k_y)(y=challenge_y)
 k = (y**n * k_y)(y=challenge_y)
 t_new = a * (b + s) - k
 t_new = a * (b + s) - k
 assert t_new == t
 assert t_new == t

+ 3 - 3
scripts/halo/sonic.sage

@@ -158,9 +158,9 @@ for q, k_q in enumerate(k, 1):
 # zkP1
 # zkP1
 # 4 blinding factors since we evaluate r(X, Y) 3 times
 # 4 blinding factors since we evaluate r(X, Y) 3 times
 # Blind r(X, Y)
 # Blind r(X, Y)
-for i in range(1, 4 + 1):
-    blind_c_i = K.random_element()
-    r_x_y += x**(-2*n - i) * y**(-2*n - i) * blind_c_i
+#for i in range(1, 4 + 1):
+#    blind_c_i = K.random_element()
+#    r_x_y += x**(-2*n - i) * y**(-2*n - i) * blind_c_i
 # Commit to r(X, Y)
 # Commit to r(X, Y)
 
 
 r_prime_x_y = r_x_y + s_x_y
 r_prime_x_y = r_x_y + s_x_y