Bläddra i källkod

working 4.5.2 basic algorithm

narodnik 5 år sedan
förälder
incheckning
726ae89ee9
1 ändrade filer med 102 tillägg och 0 borttagningar
  1. 102 0
      scripts/zk/4.5.2-multi-operation-polynomials.py

+ 102 - 0
scripts/zk/4.5.2-multi-operation-polynomials.py

@@ -1,9 +1,21 @@
 from bls_py import bls12381
+from bls_py import pairing
+from bls_py import ec
+from bls_py.fields import Fq, Fq2, Fq6, Fq12, bls12381_q as Q
 from finite_fields.modp import IntegersModP
 from finite_fields.polynomial import polynomialsOver
+import random
 
 n = bls12381.n
 
+g1 = ec.generator_Fq(bls12381)
+g2 = ec.generator_Fq2(bls12381)
+
+null = ec.AffinePoint(Fq(n, 0), Fq(n, 1), True, bls12381)
+assert null + g1 == g1
+null2 = ec.AffinePoint(Fq2.zero(n), Fq2.zero(n), True, bls12381)
+assert null2 + g2 == g2
+
 mod_field = IntegersModP(n)
 poly = polynomialsOver(mod_field).factory
 
@@ -63,3 +75,93 @@ main_poly = left_poly * right_poly - out_poly
 cofactor_poly = main_poly / target_poly
 
 assert left_poly * right_poly - out_poly == target_poly * cofactor_poly
+
+def rand_scalar():
+    return random.randrange(1, bls12381.q)
+
+#################################
+# Verifier (trusted setup)
+#################################
+
+# samples a random value (a secret)
+toxic_scalar = rand_scalar()
+# calculate the shift
+alpha_shift = rand_scalar()
+
+# calculates encryptions of s for all powers i in 0 to d
+# E(s^i) = g^s^i
+degree = 10
+enc_s1 = [
+    g1 * (toxic_scalar**i) for i in range(degree)
+]
+enc_s2 = [
+    g2 * (toxic_scalar**i) for i in range(degree)
+]
+enc_s1_shift = [
+    g1 * (alpha_shift * toxic_scalar**i) for i in range(degree)
+]
+enc_s2_shift = [
+    g2 * (alpha_shift * toxic_scalar**i) for i in range(degree)
+]
+
+# evaluates unencrypted target polynomial with s: t(s)
+toxic_target = (toxic_scalar - 1) * (toxic_scalar - 2) * (toxic_scalar - 3)
+# CRS = common reference string = trusted setup parameters
+target_crs = g1 * toxic_target
+alpha_crs = g2 * alpha_shift
+alpha_crs_g1 = g1 * alpha_shift
+
+# Proving key = (encrypted_powers, encrypted_shifted_powers)
+# Verify key = (target_crs, alpha_crs)
+
+# encrypted values of s provided to the prover
+# Actual values of s are toxic waste and discarded
+
+#################################
+# Prover
+#################################
+
+# Using encrypted powers and coefficients, evaluates
+# E(p(s)) and E(h(s))
+def evaluate(poly, encrypted_powers, identity):
+    result = identity
+    for power, coeff in zip(encrypted_powers, poly):
+        result += power * coeff.n
+    return result
+
+enc_left = evaluate(left_poly, enc_s1, null)
+enc_right = evaluate(right_poly, enc_s2, null2)
+enc_out = evaluate(out_poly, enc_s1, null)
+
+enc_cofactor = evaluate(cofactor_poly, enc_s2, null2)
+
+# Alpha shifted powers
+enc_left_shift = evaluate(left_poly, enc_s1_shift, null)
+enc_right_shift = evaluate(right_poly, enc_s2_shift, null2)
+enc_out_shift = evaluate(out_poly, enc_s1_shift, null)
+
+#################################
+# Verifier
+#################################
+
+def restrict_polynomial_g1(encrypted_shift_poly, encrypted_poly):
+    res1 = pairing.ate_pairing(encrypted_shift_poly, g2)
+    res2 = pairing.ate_pairing(encrypted_poly, alpha_crs)
+    assert res1 == res2
+
+def restrict_polynomial_g2(encrypted_shift_poly, encrypted_poly):
+    res1 = pairing.ate_pairing(g1, encrypted_shift_poly)
+    res2 = pairing.ate_pairing(alpha_crs_g1, encrypted_poly)
+    assert res1 == res2
+
+restrict_polynomial_g1(enc_left_shift, enc_left)
+restrict_polynomial_g2(enc_right_shift, enc_right)
+restrict_polynomial_g1(enc_out_shift, enc_out)
+
+# Valid operation check
+# e(g^l, g^r) == e(g^t, g^h) * e(g^o, g)
+res1 = pairing.ate_pairing(enc_left, enc_right)
+res2 = pairing.ate_pairing(target_crs, enc_cofactor) * \
+       pairing.ate_pairing(enc_out, g2)
+assert res1 == res2
+