1 # Test libsecp256k1' group operation implementations using prover.sage
5 load("group_prover.sage")
6 load("weierstrass_prover.sage")
8 def formula_secp256k1_gej_double_var(a):
9 """libsecp256k1's secp256k1_gej_double_var, used by various addition functions"""
30 return jacobianpoint(rx, ry, rz)
32 def formula_secp256k1_gej_add_var(branch, a, b):
33 """libsecp256k1's secp256k1_gej_add_var"""
35 return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), b)
37 return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a)
51 r = formula_secp256k1_gej_double_var(a)
52 return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r)
54 return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity())
72 return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
74 def formula_secp256k1_gej_add_ge_var(branch, a, b):
75 """libsecp256k1's secp256k1_gej_add_ge_var, which assume bz==1"""
77 return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(nonzero={a.Infinity : 'a_infinite'}), b)
79 return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a)
91 r = formula_secp256k1_gej_double_var(a)
92 return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r)
94 return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity())
111 return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
113 def formula_secp256k1_gej_add_zinv_var(branch, a, b):
114 """libsecp256k1's secp256k1_gej_add_zinv_var"""
117 return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a)
120 bzinv3 = bzinv2 * bzinv
124 return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz))
137 r = formula_secp256k1_gej_double_var(a)
138 return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r)
140 return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity())
158 return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz))
160 def formula_secp256k1_gej_add_ge(branch, a, b):
161 """libsecp256k1's secp256k1_gej_add_ge"""
165 if (branch & 4) != 0:
166 nonzeroes.update({a.Infinity : 'a_infinite'})
169 zeroes.update({a.Infinity : 'a_finite'})
184 degenerate = (branch & 3) == 3
185 if (branch & 1) != 0:
186 zeroes.update({m : 'm_zero'})
188 nonzeroes.update({m : 'm_nonzero'})
189 if (branch & 2) != 0:
190 zeroes.update({rr : 'rr_zero'})
192 nonzeroes.update({rr : 'rr_nonzero'})
207 if (branch & 8) != 0:
210 zeroes.update({rz : 'r.z=0'})
212 nonzeroes.update({rz : 'r.z!=0'})
229 return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), point_at_infinity())
230 return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), jacobianpoint(rx, ry, rz))
232 def formula_secp256k1_gej_add_ge_old(branch, a, b):
233 """libsecp256k1's old secp256k1_gej_add_ge, which fails when ay+by=0 but ax!=bx"""
234 a_infinity = (branch & 1) != 0
238 nonzero.update({a.Infinity : 'a_infinite'})
240 zero.update({a.Infinity : 'a_finite'})
262 if (branch & 2) != 0:
266 return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(nonzero={z : 'conflict_a'}, zero={z : 'conflict_b'}), point_at_infinity())
267 zero.update({rz : 'r.z=0'})
269 nonzero.update({rz : 'r.z!=0'})
270 rz = rz * (0 if a_infinity else 2)
280 rx = rx * (0 if a_infinity else 4)
281 ry = ry * (0 if a_infinity else 4)
283 t = t * (1 if a_infinity else 0)
286 t = t * (1 if a_infinity else 0)
288 t = (1 if a_infinity else 0)
291 return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), point_at_infinity())
292 return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), jacobianpoint(rx, ry, rz))
294 if __name__ == "__main__":
295 check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var)
296 check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var)
297 check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var)
298 check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge)
299 check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old)
301 if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive":
302 check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43)
303 check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43)
304 check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43)
305 check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43)
306 check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43)