pyUmbral/vectors/generate_test_vectors.py

273 lines
7.6 KiB
Python

import json
import os
from umbral import pre
from umbral.keys import UmbralPrivateKey
from umbral.signing import Signer
from umbral.curvebn import CurveBN
from umbral.point import Point, unsafe_hash_to_point
from umbral.config import set_default_curve, default_params
#######################
# Auxiliary functions #
#######################
def hexlify(data):
if isinstance(data, int):
return hex(data)[2:]
try:
return data.to_bytes().hex()
except AttributeError:
return bytes(data).hex()
def create_test_vector_file(vector, filename, generate_again=False):
path = os.path.join(os.path.dirname(__file__), filename)
mode = 'w' if generate_again else 'x'
try:
with open(path, mode) as f:
json.dump(vector, f, indent=2)
except FileExistsError:
pass
# If True, this will overwrite existing test vector files with new randomly generated instances
generate_again = False
#########
# SETUP #
#########
set_default_curve()
params = default_params()
curve = params.curve
# We create also some Umbral objects for later
delegating_privkey = UmbralPrivateKey.gen_key(params=params)
receiving_privkey = UmbralPrivateKey.gen_key(params=params)
signing_privkey = UmbralPrivateKey.gen_key(params=params)
verifying_key = signing_privkey.get_pubkey()
delegating_key = delegating_privkey.get_pubkey()
receiving_key = receiving_privkey.get_pubkey()
signer = Signer(signing_privkey)
kfrags = pre.split_rekey(delegating_privkey, signer, receiving_key, 6, 10)
plain_data = b'peace at dawn'
ciphertext, capsule = pre.encrypt(delegating_key, plain_data)
cfrag = pre.reencrypt(kfrags[0], capsule)
points = [ capsule._point_e, cfrag._point_e1, cfrag.proof._point_e2,
capsule._point_v, cfrag._point_v1, cfrag.proof._point_v2,
capsule._umbral_params.u, cfrag.proof._point_kfrag_commitment, cfrag.proof._point_kfrag_pok ]
z = cfrag.proof.bn_sig
# h = CurveBN.hash(*points, params=params)
#######################
# CurveBN arithmetics #
#######################
# Let's generate two random CurveBNs
bn1 = CurveBN.gen_rand(curve)
bn2 = CurveBN.gen_rand(curve)
# Expected results for some binary operations
expected = [ ('Addition', bn1 + bn2),
('Subtraction', bn1 - bn2),
('Multiplication', bn1 * bn2),
('Division', bn1 / bn2),
('Pow', bn1 ** bn2),
('Mod', bn1 % bn2),
('Inverse', ~bn1),
('Neg', -bn1),
]
expected = [ {'operation' : op, 'result' : hexlify(result) } for (op, result) in expected ]
# Definition of test vector
vector_suite = {
'name' : 'Test vectors for CurveBN operations',
'params' : 'default',
'first operand' : hexlify(bn1),
'second operand' : hexlify(bn2),
'vectors' : expected
}
json_file = 'vectors_curvebn_operations.json'
create_test_vector_file(vector_suite, json_file, generate_again=generate_again)
##################
# CurveBN.hash() #
##################
# Test vectors for different kinds of inputs (bytes, Points, CurveBNs, etc.)
inputs = ( [b''],
[b'abc'],
[capsule._point_e],
[z],
[capsule._point_e, z],
points,
)
vectors = list()
for input_to_hash in inputs:
bn_output = CurveBN.hash(*input_to_hash, params=params)
json_input = [{ 'class' : data.__class__.__name__,
'bytes' : hexlify(data),
}
for data in input_to_hash]
json_input = { 'input' : json_input, 'output' : hexlify(bn_output) }
vectors.append(json_input)
vector_suite = {
'name' : 'Test vectors for umbral.curvebn.CurveBN.hash()',
'params' : 'default',
'vectors' : vectors
}
create_test_vector_file(vector_suite, 'vectors_curvebn_hash.json', generate_again=generate_again)
#print(json.dumps(vector_suite, indent=2))
##########
# Points #
##########
point1 = Point.gen_rand(curve)
point2 = Point.gen_rand(curve)
# Expected results for some Point operations
expected = [ ('Addition', point1 + point2),
('Subtraction', point1 - point2),
('Multiplication', bn1 * point1),
('Inversion', -point1),
('To_affine.X', point1.to_affine()[0]),
('To_affine.Y', point1.to_affine()[1]),
]
expected = [ {'operation' : op, 'result' : hexlify(result) } for (op, result) in expected ]
# Definition of test vector
vector_suite = {
'name' : 'Test vectors for Point operations',
'params' : 'default',
'first Point operand' : hexlify(point1),
'second Point operand' : hexlify(point2),
'CurveBN operand' : hexlify(bn1),
'vectors' : expected
}
json_file = 'vectors_point_operations.json'
create_test_vector_file(vector_suite, json_file, generate_again=generate_again)
########################
# unsafe_hash_to_point #
########################
inputs = ( b'',
b'abc',
b'NuCypher',
b'Nucypher',
)
vectors = list()
for data in inputs:
for label in inputs:
point = unsafe_hash_to_point(label=label, data=data, params=params)
json_input = { 'data' : hexlify(data),
'label' : hexlify(label),
'point' : hexlify(point),
}
vectors.append(json_input)
vector_suite = {
'name' : 'Test vectors for umbral.point.Point.unsafe_hash_to_point',
'params' : 'default',
'vectors' : vectors
}
create_test_vector_file(vector_suite, 'vectors_unsafe_hash_to_point.json', generate_again=generate_again)
#print(json.dumps(vector_suite, indent=2))
##########
# KFrags #
##########
vectors = list()
for kfrag in kfrags:
assert kfrag.verify(verifying_key, delegating_key, receiving_key)
json_input = { 'kfrag' : hexlify(kfrag) }
vectors.append(json_input)
vector_suite = {
'name' : 'Test vectors for KFrags',
'description' : ('This is a collection of KFrags generated under the '
'enclosed delegating, verifying and receiving keys. '
'Each of them must deserialize correctly and the '
'call to verify() must succeed.'),
'params' : 'default',
'verifying_key' : hexlify(verifying_key),
'delegating_key' : hexlify(delegating_key),
'receiving_key' : hexlify(receiving_key),
'vectors' : vectors
}
#print(json.dumps(vector_suite, indent=2))
create_test_vector_file(vector_suite, 'vectors_kfrags.json', generate_again=generate_again)
##########
# CFrags #
##########
capsule.set_correctness_keys(delegating=delegating_key,
receiving=receiving_key,
verifying=verifying_key)
vectors = list()
for kfrag in kfrags:
cfrag = pre.reencrypt(kfrag, capsule, provide_proof=False)
json_input = { 'kfrag' : hexlify(kfrag), 'cfrag' : hexlify(cfrag) }
vectors.append(json_input)
vector_suite = {
'name' : 'Test vectors for CFrags',
'description' : ('This is a collection of CFrags, originated from the '
'enclosed Capsule, under the enclosed delegating, '
'verifying and receiving keys. Each CFrag must deserialize '
'correctly and can be replicated with a call to '
'`pre.reencrypt(kfrag, capsule, provide_proof=False)`'),
'params' : 'default',
'capsule' : hexlify(capsule),
'verifying_key' : hexlify(verifying_key),
'delegating_key' : hexlify(delegating_key),
'receiving_key' : hexlify(receiving_key),
'vectors' : vectors
}
#print(json.dumps(vector_suite, indent=2))
create_test_vector_file(vector_suite, 'vectors_cfrags.json', generate_again=generate_again)