def print_tv_hash(hash_in, ciphersuite, hash_fn, print_pt_fn, is_ell2, opts): if len(hash_in) > 2: (msg, _, hash_expect) = hash_in[:3] else: msg = hash_in[0] hash_expect = None # hash to point P = hash_fn(msg, ciphersuite) if opts.gen_vectors: print(b' '.join( hexlify(v) for v in (msg, b'\x00', serialize(P)) ).decode('ascii')) return if hash_expect is not None: if serialize(P) != hash_expect: raise SerError("serializing P did not give hash_expect") if from_jacobian(deserialize(hash_expect, is_ell2)) != from_jacobian(P): raise DeserError("deserializing hash_expect did not give P") if opts.quiet: return print("=============== begin hash test vector ==================") sys.stdout.write("ciphersuite: ") print_value(ciphersuite, 13, True) sys.stdout.write("message: ") print_value(msg, 13, True) print("result:") print_pt_fn(P) print("=============== end hash test vector ==================")
def print_tv_hash(hash_in, ciphersuite, hash_fn, print_pt_fn, quiet): if len(hash_in) > 2: (msg, _, hash_expect) = hash_in[:3] else: msg = hash_in[0] hash_expect = None # hash to point P = hash_fn(msg, ciphersuite) if hash_expect is not None: if serialize(P) != hash_expect: raise SerError("serializing P did not give hash_expect") if from_jacobian(deserialize(hash_expect)) != from_jacobian(P): raise DeserError("deserializing hash_expect did not give P") if quiet: return print("=============== begin hash test vector ==================") sys.stdout.write("ciphersuite: ") print_value(ciphersuite, 13, True) sys.stdout.write("message: ") print_value(msg, 13, True) print("result:") print_pt_fn(P) print("=============== end hash test vector ==================")
def run_tests(): import random from curve_ops import psi for _ in range(0, 128): t1 = Fq2(p, random.getrandbits(380), random.getrandbits(380)) t2 = Fq2(p, random.getrandbits(380), random.getrandbits(380)) # make sure each helper function actually returns a point on the curve for t in (t1, t2): P = osswu2_help(t) Pp = from_jacobian(P) assert Pp[0]**3 + Ell2p_a * Pp[0] + Ell2p_b == Pp[1]**2 P = iso3(P) Pp = from_jacobian(P) assert Pp[0]**3 + Fq2(p, 4, 4) == Pp[1]**2 P = psi(P) Pp = from_jacobian(P) assert Pp[0]**3 + Fq2(p, 4, 4) == Pp[1]**2 P = clear_h2(P) Pp = from_jacobian(P) assert Pp[0]**3 + Fq2(p, 4, 4) == Pp[1]**2 # now test end-to-end P = opt_swu2_map(t1, t2) Pp = from_jacobian(P) assert Pp[0]**3 + Fq2(p, 4, 4) == Pp[1]**2 sys.stdout.write('.') sys.stdout.flush() sys.stdout.write("\n")
def print_tv_sig(sig_in, ciphersuite, sign_fn, keygen_fn, print_pk_fn, print_sig_fn, ver_fn, is_ell2, opts): if len(sig_in) > 2: (msg, sk, sig_expect) = sig_in[:3] else: (msg, sk) = sig_in sig_expect = None # generate key and signature (x_prime, pk) = keygen_fn(sk) sig = sign_fn(x_prime, msg, ciphersuite) if ver_fn is not None and not ver_fn(pk, sig, msg, ciphersuite): raise RuntimeError("verifying generated signature failed") if opts.gen_vectors: print(b' '.join(hexlify(v) for v in (msg, sk, serialize(sig))).decode('ascii')) return if sig_expect is not None: if serialize(sig) != sig_expect: raise SerError("serializing sig did not give sig_expect") if from_jacobian(deserialize(sig_expect, is_ell2)) != from_jacobian(sig): raise DeserError("deserializing sig_expect did not give sig") if opts.quiet: return # output the test vector print("================== begin test vector ====================") print("g1 generator:") print_g1_hex(g1gen) print("g2 generator:") print_g2_hex(g2gen) print("group order: 0x%x" % q) sys.stdout.write("ciphersuite: ") print_value(ciphersuite, 13, True) sys.stdout.write("message: ") print_value(msg, 13, True) sys.stdout.write("sk: ") print_value(sk, 13, True) sys.stdout.write("x_prime: ") print_value(x_prime, 13, True) print("public key:") print_pk_fn(pk) print("signature:") print_sig_fn(sig) print("================== end test vector ====================")
def print_tv_pop(sig_in, ciphersuite, sign_fn, keygen_fn, print_pk_fn, print_sig_fn, ver_fn, quiet): if len(sig_in) > 2: (_, sk, sig_expect) = sig_in[:3] else: (_, sk) = sig_in sig_expect = None # generate key and signature (x_prime, pk) = keygen_fn(sk) sig = sign_fn(x_prime, pk, ciphersuite) if sig_expect is not None: if serialize(sig) != sig_expect: raise SerError("serializing sig did not give sig_expect") if from_jacobian(deserialize(sig_expect)) != from_jacobian(sig): raise DeserError("deserializing sig_expect did not give sig") if ver_fn is not None and not ver_fn(pk, sig, ciphersuite): raise RuntimeError("verifying generated signature failed") if quiet: return # output the test vector print("================== begin test vector ====================") print("g1 generator:") print_g1_hex(g1gen) print("g2 generator:") print_g2_hex(g2gen) print("group order: 0x%x" % q) sys.stdout.write("ciphersuite: ") print_value(ciphersuite, 13, True) sys.stdout.write("sk: ") print_value(sk, 13, True) sys.stdout.write("x_prime: ") print_value(x_prime, 13, True) print("public key:") print_pk_fn(pk) print("signature:") print_sig_fn(sig) print("================== end test vector ====================")
def _serialize_ell2(P, compressed): if not isinstance(P[0], Fq2): raise SerError("cannot serialize a point not on E2") if len(P) != 3: raise SerError("can only serialize Jacobian points") first_tag = 0xe0 if compressed else 0x60 # handle point at infinity if P[2] == 0: return first_tag.to_bytes( 1, "big") + b'\x00' * 47 + b'\xc0' + b'\x00' * (47 if compressed else 143) (x, y) = from_jacobian(P) if pow(y, 2) != _gx2(x): raise SerError("cannot serialize invalid point") x_str = _to_bytes_F2(x) x_str[0] = x_str[0] | first_tag if not compressed: x_str[48] = x_str[48] | 0x80 return struct.pack("=" + "B" * 192, *(x_str + _to_bytes_F2(y))) y_neg = sgn0(y) < 0 tag_bits = 0xa0 if y_neg else 0x80 x_str[48] = x_str[48] | tag_bits return struct.pack("=" + "B" * 96, *x_str)
def run_tests(): import random for _ in range(0, 128): t1 = Fq(p, random.getrandbits(380)) t2 = Fq(p, random.getrandbits(380)) # test helpers individually for t in (t1, t2): P = osswu_help(t) Pp = from_jacobian(P) assert Pp[0]**3 + EllP_a * Pp[0] + EllP_b == Pp[1]**2 P = iso11(P) Pp = from_jacobian(P) assert Pp[0]**3 + 4 == Pp[1]**2 P = clear_h(P) Pp = from_jacobian(P) assert Pp[0]**3 + 4 == Pp[1]**2 # now test end-to-end P = from_jacobian(opt_swu_map(t1, t2)) assert P[0]**3 + 4 == P[1]**2 sys.stdout.write('.') sys.stdout.flush() sys.stdout.write("\n")
def _miller_loop(T, P, Q): if len(P) == 3: P = from_jacobian(P) res_num = Fq12.one(p) res_den = Fq12.one(p) R = Q T_bits = [1 if b == '1' else 0 for b in bin(T)[3:]] # all except MSB in MSB-to-LSB order for b in T_bits: (d_num, d_den) = _double_eval(R, P) res_num = pow(res_num, 2) * d_num res_den = pow(res_den, 2) * d_den R = point_double(R) if b: (a_num, a_den) = _add_eval(R, Q, P) res_num = res_num * a_num res_den = res_den * a_den R = point_add(R, Q) return res_num / res_den
def _serialize_help(P, compressed, to_bytes, clen, g): # point at infinity if P[2] == 0: if compressed: return b'\xc0' + b'\x00' * (clen - 1) return b'\x40' + b'\x00' * (2 * clen - 1) (x, y) = from_jacobian(P) if pow(y, 2) != g(x): raise SerError("cannot serialize invalid point") x_str = to_bytes(x) if not compressed: return struct.pack("=" + "B" * 2 * clen, *(x_str + to_bytes(y))) y_neg = sgn0(y) < 0 tag_bits = 0xa0 if y_neg else 0x80 x_str[0] = x_str[0] | tag_bits return struct.pack("=" + "B" * clen, *x_str)
def _serialize_ell1(P, compressed): if not isinstance(P[0], Fq): raise SerError("cannot serialize a point not on E1") if len(P) != 3: raise SerError("can only serialize Jacobian points") # handle point at infinity if P[2] == 0: if compressed: return b'\xc0' + b'\x00' * 47 return b'\x40' + b'\x00' * 95 (x, y) = from_jacobian(P) if pow(y, 2) != _gx1(x): raise SerError("cannot serialize invalid point") x_str = _to_bytes_F1(x) if not compressed: return struct.pack("=" + "B" * 96, *(x_str + _to_bytes_F1(y))) y_neg = sgn0(y) < 0 tag_bits = 0xa0 if y_neg else 0x80 x_str[0] = x_str[0] | tag_bits return struct.pack("=" + "B" * 48, *x_str)
def print_g1_hex(P, margin=8): indent_str = " " * margin if len(P) == 3: P = from_jacobian(P) print(indent_str, "x = 0x%x" % P[0]) print(indent_str, "y = 0x%x" % P[1])
def print_g2_hex(P, margin=8): if len(P) == 3: P = from_jacobian(P) print_f2_hex(P[0], 'x', margin) print_f2_hex(P[1], 'y', margin)