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_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 serialize_ssk(ssk): (time, g2r, hpoly, hvector) = ssk hlen = len(hvector) buf = time.to_bytes(4, 'big') + b"%c"% hlen buf += serialize(g2r, True) buf += serialize(hpoly, True) for e in hvector: buf += serialize(e, True) return buf
def key_test_vector_gen(): seed = b"this is a very long seed for pixel tests" pk, sk = key_gen(seed) print_sk(sk) pk_buf = b"\0" + serialize(pk, True) f = open("test_vector/pk_bin.txt", "wb") f.write(pk_buf) f.close() sk_buf = serialize_sk(sk) f = open("test_vector/sk_bin_01.txt", "wb") f.write(sk_buf) f.close() fname = "test_vector/sk_plain_01.txt" t = sys.stdout sys.stdout = open(fname, 'w') print_sk(sk) sys.stdout = t
def pop_verify(pk, proof, ciphersuite): pk_bytes = serialize(pk, True) # serialize in compressed form P = map2curve_osswu2(pk_bytes, ciphersuite) if not (subgroup_check_g1(pk) and subgroup_check_g2(proof)): return False return multi_pairing((pk, point_neg(g1gen)), (P, proof)) == 1
def pop_prove(x_prime, pk, ciphersuite): pk_bytes = serialize(pk, True) # serialize in compressed form P = map2curve_osswu2(pk_bytes, ciphersuite) return point_mul(x_prime, P)
def pop_verify(pk, proof, ciphersuite): pk_bytes = serialize(pk, True) # serialize in compressed form P = map2curve_osswu(pk_bytes, ciphersuite) pk_ok = subgroup_check_g2(pk) proof_ok = multi_pairing((P, proof), (pk, point_neg(g2gen))) == 1 return pk_ok and proof_ok
def _agg_ver_aug(pks, msgs, sig, ciphersuite, ver_fn): assert len(pks) == len( msgs), "FAIL: aggregate_verify_aug needs same number of sigs and msgs" msgs_aug = [serialize(pk, True) + msg for (pk, msg) in zip(pks, msgs)] return ver_fn(pks, msgs_aug, sig, ciphersuite)
def _verify_aug(pk, sig, msg, ciphersuite, ver_fn=verify): pk_bytes = serialize(pk, True) # serialize in compressed form return ver_fn(pk, sig, pk_bytes + msg, ciphersuite)
def _sign_aug(x_prime, msg, ciphersuite, pk=None, gen=None, sign_fn=sign): if pk is None: pk = point_mul(x_prime, gen) pk_bytes = serialize(pk, True) # serialize in compressed form return sign_fn(x_prime, pk_bytes + msg, ciphersuite)
info = b"H2G_h" + I2OSP(i, 1) # expand the secret key = hkdf.hkdf_expand(pseudo_random_key=m, info=info, length=32, hash=hashlib.sha512) # hash to G2 hi = map2curve_osswu2(key, ciphersuite) hlist.append(hi) default_param = (g1gen, h, hlist) # formulate the outputs buf = b"%c" % ciphersuite buf = buf + b"%c" % d buf = buf + serialize(g1gen, False) buf = buf + serialize(h, False) for i in range(d + 1): buf = buf + serialize(hlist[i], False) # write to the output f = open("test_vector/param_bin.txt", "wb") f.write(buf) f.close() if __name__ == "__main__": def main(): assert filecmp.cmp("test_vector/param_bin.txt", "../test_vector/test_vector/param_bin.txt")
def test_vector(): seed = b"this is a very long seed for pixel tests" msg = b"this is the message we want pixel to sign" print("Initialization") pk, sk = key_gen(seed) sig = sign_present(sk, 1, default_param, msg) sk_back_up = copy.deepcopy(sk) # output pk to a binary file pk_buf = b"\0" + serialize(pk, True) f = open("test_vector/pk_bin.txt", "wb") f.write(pk_buf) f.close() assert filecmp.cmp("test_vector/pk_bin.txt", "../test_vector/test_vector/pk_bin.txt") # output sk to a human readable file fname = "test_vector/sk_plain_01.txt" t = sys.stdout sys.stdout = open(fname, 'w') print_sk(sk) sys.stdout = t # output sk to a binary file sk_buf = serialize_sk(sk) f = open("test_vector/sk_bin_01.txt", "wb") f.write(sk_buf) f.close() assert filecmp.cmp("test_vector/sk_bin_01.txt", "../test_vector/test_vector/sk_bin_01.txt") # output sig to a human readable file fname = "test_vector/sig_plain_01.txt" t = sys.stdout sys.stdout = open(fname, 'w') print_sig(sig) sys.stdout = t # output sig to a binary file sig_buf = serialize_sig(sig) f = open("test_vector/sig_bin_01.txt", "wb") f.write(sig_buf) f.close() assert filecmp.cmp("test_vector/sig_bin_01.txt", "../test_vector/test_vector/sig_bin_01.txt") # update the secret key sequentially, and make sure the # updated key matched rust's outputs. for i in range(2, 64): print("updating to time %d" % i) # updated sk and signatures sk2 = sk_update(copy.deepcopy(sk), default_param, i, b"") sig = sign_present(sk2, i, default_param, msg) # output sk to a human readable file fname = "test_vector/sk_plain_%02d.txt" % i t = sys.stdout sys.stdout = open(fname, 'w') print_sk(sk2) sys.stdout = t # output sk to a binary file sk_buf = serialize_sk(sk2) fname = "test_vector/sk_bin_%02d.txt" % i f = open(fname, "wb") f.write(sk_buf) f.close() # compare with rust's output fname2 = "../test_vector/test_vector/sk_bin_%02d.txt" % i assert filecmp.cmp(fname, fname2) # output sig to a human readable file fname = "test_vector/sig_plain_%02d.txt" % i t = sys.stdout sys.stdout = open(fname, 'w') print_sig(sig) sys.stdout = t # output sig to a binary file fname = "test_vector/sig_bin_%02d.txt" % i fname2 = "../test_vector/test_vector/sig_bin_%02d.txt" % i sig_buf = serialize_sig(sig) f = open(fname, "wb") f.write(sig_buf) f.close() assert filecmp.cmp(fname, fname2) sk = copy.deepcopy(sk2) sk = copy.deepcopy(sk_back_up) for i in range(2, 64): cur_time = sk[1][0][0] tar_time = cur_time + i print("updating from time %d to time %d" % (cur_time, tar_time)) # updated sk and signatures sk2 = sk_update(copy.deepcopy(sk), default_param, tar_time, b"") sig = sign_present(sk2, tar_time, default_param, msg) # output sk to a human readable file fname = "test_vector/sk_plain_ff_%04d_%04d.txt" % (cur_time, tar_time) t = sys.stdout sys.stdout = open(fname, 'w') print_sk(sk2) sys.stdout = t # output sk to a binary file sk_buf = serialize_sk(sk2) fname = "test_vector/sk_bin_ff_%04d_%04d.txt" % (cur_time, tar_time) f = open(fname, "wb") f.write(sk_buf) f.close() # compare with rust's output fname2 = "../test_vector/test_vector/sk_bin_ff_%04d_%04d.txt" % ( cur_time, tar_time) assert filecmp.cmp(fname, fname2) # output sig to a human readable file fname = "test_vector/sig_plain_ff_%04d_%04d.txt" % (cur_time, tar_time) t = sys.stdout sys.stdout = open(fname, 'w') print_sig(sig) sys.stdout = t # output sig to a binary file fname = "test_vector/sig_bin_ff_%04d_%04d.txt" % (cur_time, tar_time) fname2 = "../test_vector/test_vector/sig_bin_ff_%04d_%04d.txt" % ( cur_time, tar_time) sig_buf = serialize_sig(sig) f = open(fname, "wb") f.write(sig_buf) f.close() assert filecmp.cmp(fname, fname2) sk = copy.deepcopy(sk2)
def serialize_sig(sig): return b"%c" % 0 + sig[0].to_bytes(4, 'big') + serialize( sig[1], True) + serialize(sig[2], True)