mirror of https://github.com/nucypher/pyUmbral.git
commit
c5a9fc6dd9
|
@ -11,8 +11,8 @@ def test_capsule_creation(alices_keys):
|
|||
rare_capsule = Capsule() # Alice cannot make a capsule this way.
|
||||
|
||||
# Some users may create capsules their own way.
|
||||
custom_capsule = Capsule(point_eph_e=Point.gen_rand(),
|
||||
point_eph_v=Point.gen_rand(),
|
||||
custom_capsule = Capsule(point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=BigNum.gen_rand())
|
||||
|
||||
assert isinstance(custom_capsule, Capsule)
|
||||
|
@ -26,19 +26,19 @@ def test_capsule_creation(alices_keys):
|
|||
|
||||
|
||||
def test_capsule_equality():
|
||||
one_capsule = Capsule(point_eph_e=Point.gen_rand(),
|
||||
point_eph_v=Point.gen_rand(),
|
||||
one_capsule = Capsule(point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=BigNum.gen_rand())
|
||||
|
||||
another_capsule = Capsule(point_eph_e=Point.gen_rand(),
|
||||
point_eph_v=Point.gen_rand(),
|
||||
another_capsule = Capsule(point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=BigNum.gen_rand())
|
||||
|
||||
assert one_capsule != another_capsule
|
||||
|
||||
activated_capsule = Capsule(e_prime=Point.gen_rand(),
|
||||
v_prime=Point.gen_rand(),
|
||||
noninteractive_point=Point.gen_rand())
|
||||
activated_capsule = Capsule(point_e_prime=Point.gen_rand(),
|
||||
point_v_prime=Point.gen_rand(),
|
||||
point_noninteractive=Point.gen_rand())
|
||||
|
||||
assert activated_capsule != one_capsule
|
||||
|
||||
|
@ -59,8 +59,8 @@ def test_bad_capsule_fails_reencryption(alices_keys):
|
|||
|
||||
kfrags = pre.split_rekey(priv_key_alice, pub_key_alice, 1, 2)
|
||||
|
||||
bollocks_capsule = Capsule(point_eph_e=Point.gen_rand(),
|
||||
point_eph_v=Point.gen_rand(),
|
||||
bollocks_capsule = Capsule(point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=BigNum.gen_rand())
|
||||
|
||||
with pytest.raises(Capsule.NotValid):
|
||||
|
|
|
@ -27,8 +27,8 @@ def test_capsule_serialization(alices_keys):
|
|||
|
||||
# Third, we can directly compare the private original component attributes
|
||||
# (though this is not a supported approach):
|
||||
assert new_capsule._point_eph_e == capsule._point_eph_e
|
||||
assert new_capsule._point_eph_v == capsule._point_eph_v
|
||||
assert new_capsule._point_e == capsule._point_e
|
||||
assert new_capsule._point_v == capsule._point_v
|
||||
assert new_capsule._bn_sig == capsule._bn_sig
|
||||
|
||||
|
||||
|
@ -58,28 +58,28 @@ def test_activated_capsule_serialization(alices_keys, bobs_keys):
|
|||
|
||||
assert new_rec_capsule.activated_components() == capsule.activated_components()
|
||||
|
||||
assert new_rec_capsule._point_eph_e_prime == capsule._point_eph_e_prime
|
||||
assert new_rec_capsule._point_eph_v_prime == capsule._point_eph_v_prime
|
||||
assert new_rec_capsule._point_e_prime == capsule._point_e_prime
|
||||
assert new_rec_capsule._point_v_prime == capsule._point_v_prime
|
||||
assert new_rec_capsule._point_noninteractive == capsule._point_noninteractive
|
||||
|
||||
|
||||
def test_cannot_create_capsule_from_bogus_material(alices_keys):
|
||||
with pytest.raises(TypeError):
|
||||
capsule_of_questionable_parentage = pre.Capsule(point_eph_e=Point.gen_rand(),
|
||||
point_eph_v=42,
|
||||
capsule_of_questionable_parentage = pre.Capsule(point_e=Point.gen_rand(),
|
||||
point_v=42,
|
||||
bn_sig=BigNum.gen_rand())
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
capsule_of_questionable_parentage = pre.Capsule(point_eph_e=Point.gen_rand(),
|
||||
point_eph_v=Point.gen_rand(),
|
||||
capsule_of_questionable_parentage = pre.Capsule(point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=42)
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
capsule_of_questionable_parentage = pre.Capsule(e_prime=Point.gen_rand(),
|
||||
v_prime=42,
|
||||
noninteractive_point=Point.gen_rand())
|
||||
capsule_of_questionable_parentage = pre.Capsule(point_e_prime=Point.gen_rand(),
|
||||
point_v_prime=42,
|
||||
point_noninteractive=Point.gen_rand())
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
capsule_of_questionable_parentage = pre.Capsule(e_prime=Point.gen_rand(),
|
||||
v_prime=Point.gen_rand(),
|
||||
noninteractive_point=42)
|
||||
capsule_of_questionable_parentage = pre.Capsule(point_e_prime=Point.gen_rand(),
|
||||
point_v_prime=Point.gen_rand(),
|
||||
point_noninteractive=42)
|
||||
|
|
|
@ -34,13 +34,13 @@ def test_correctness_proof_serialization():
|
|||
# assert len(proof_bytes) == (33 * 4) + (32 * 3) == 228
|
||||
|
||||
new_proof = CorrectnessProof.from_bytes(proof_bytes)
|
||||
assert new_proof.point_eph_e2 == proof.point_eph_e2
|
||||
assert new_proof.point_eph_v2 == proof.point_eph_v2
|
||||
assert new_proof.point_kfrag_commitment == proof.point_kfrag_commitment
|
||||
assert new_proof.point_kfrag_pok == proof.point_kfrag_pok
|
||||
assert new_proof.bn_kfrag_sig1 == proof.bn_kfrag_sig1
|
||||
assert new_proof.bn_kfrag_sig2 == proof.bn_kfrag_sig2
|
||||
assert new_proof.bn_sig == proof.bn_sig
|
||||
assert new_proof._point_e2 == proof._point_e2
|
||||
assert new_proof._point_v2 == proof._point_v2
|
||||
assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment
|
||||
assert new_proof._point_kfrag_pok == proof._point_kfrag_pok
|
||||
assert new_proof._bn_kfrag_sig1 == proof._bn_kfrag_sig1
|
||||
assert new_proof._bn_kfrag_sig2 == proof._bn_kfrag_sig2
|
||||
assert new_proof._bn_sig == proof._bn_sig
|
||||
assert new_proof.metadata == proof.metadata
|
||||
|
||||
|
||||
|
@ -133,8 +133,8 @@ def test_cheating_ursula_sends_garbage(N, M):
|
|||
cfrags.append(cfrag)
|
||||
|
||||
# Let's put random garbage in one of the cfrags
|
||||
cfrags[0].point_eph_e1 = Point.gen_rand()
|
||||
cfrags[0].point_eph_v1 = Point.gen_rand()
|
||||
cfrags[0]._point_e1 = Point.gen_rand()
|
||||
cfrags[0]._point_v1 = Point.gen_rand()
|
||||
|
||||
capsule_alice._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob) # activate capsule
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@ def test_kfrag_serialization(alices_keys):
|
|||
assert len(kfrag_bytes) == 33 + 33 + (32 * 4) == 194
|
||||
|
||||
new_frag = pre.KFrag.from_bytes(kfrag_bytes)
|
||||
assert new_frag.bn_id == kfrags[0].bn_id
|
||||
assert new_frag.bn_key == kfrags[0].bn_key
|
||||
assert new_frag.point_eph_ni == kfrags[0].point_eph_ni
|
||||
assert new_frag.point_commitment == kfrags[0].point_commitment
|
||||
assert new_frag.bn_sig1 == kfrags[0].bn_sig1
|
||||
assert new_frag.bn_sig2 == kfrags[0].bn_sig2
|
||||
assert new_frag._bn_id == kfrags[0]._bn_id
|
||||
assert new_frag._bn_key == kfrags[0]._bn_key
|
||||
assert new_frag._point_noninteractive == kfrags[0]._point_noninteractive
|
||||
assert new_frag._point_commitment == kfrags[0]._point_commitment
|
||||
assert new_frag._bn_sig1 == kfrags[0]._bn_sig1
|
||||
assert new_frag._bn_sig2 == kfrags[0]._bn_sig2
|
||||
|
||||
|
||||
def test_cfrag_serialization_with_proof_and_metadata(alices_keys):
|
||||
|
@ -45,20 +45,20 @@ def test_cfrag_serialization_with_proof_and_metadata(alices_keys):
|
|||
#assert len(cfrag_bytes) == 33 + 33 + 33 + 32 == 131
|
||||
|
||||
new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes)
|
||||
assert new_cfrag.point_eph_e1 == cfrag.point_eph_e1
|
||||
assert new_cfrag.point_eph_v1 == cfrag.point_eph_v1
|
||||
assert new_cfrag.bn_kfrag_id == cfrag.bn_kfrag_id
|
||||
assert new_cfrag.point_eph_ni == cfrag.point_eph_ni
|
||||
assert new_cfrag._point_e1 == cfrag._point_e1
|
||||
assert new_cfrag._point_v1 == cfrag._point_v1
|
||||
assert new_cfrag._bn_kfrag_id == cfrag._bn_kfrag_id
|
||||
assert new_cfrag._point_noninteractive == cfrag._point_noninteractive
|
||||
|
||||
new_proof = new_cfrag.proof
|
||||
assert new_proof is not None
|
||||
assert new_proof.point_eph_e2 == proof.point_eph_e2
|
||||
assert new_proof.point_eph_v2 == proof.point_eph_v2
|
||||
assert new_proof.point_kfrag_commitment == proof.point_kfrag_commitment
|
||||
assert new_proof.point_kfrag_pok == proof.point_kfrag_pok
|
||||
assert new_proof.bn_kfrag_sig1 == proof.bn_kfrag_sig1
|
||||
assert new_proof.bn_kfrag_sig2 == proof.bn_kfrag_sig2
|
||||
assert new_proof.bn_sig == proof.bn_sig
|
||||
assert new_proof._point_e2 == proof._point_e2
|
||||
assert new_proof._point_v2 == proof._point_v2
|
||||
assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment
|
||||
assert new_proof._point_kfrag_pok == proof._point_kfrag_pok
|
||||
assert new_proof._bn_kfrag_sig1 == proof._bn_kfrag_sig1
|
||||
assert new_proof._bn_kfrag_sig2 == proof._bn_kfrag_sig2
|
||||
assert new_proof._bn_sig == proof._bn_sig
|
||||
assert new_proof.metadata == metadata
|
||||
assert new_proof.metadata == proof.metadata
|
||||
|
||||
|
@ -81,20 +81,20 @@ def test_cfrag_serialization_with_proof_but_no_metadata(alices_keys):
|
|||
#assert len(cfrag_bytes) == 33 + 33 + 33 + 32 == 131
|
||||
|
||||
new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes)
|
||||
assert new_cfrag.point_eph_e1 == cfrag.point_eph_e1
|
||||
assert new_cfrag.point_eph_v1 == cfrag.point_eph_v1
|
||||
assert new_cfrag.bn_kfrag_id == cfrag.bn_kfrag_id
|
||||
assert new_cfrag.point_eph_ni == cfrag.point_eph_ni
|
||||
assert new_cfrag._point_e1 == cfrag._point_e1
|
||||
assert new_cfrag._point_v1 == cfrag._point_v1
|
||||
assert new_cfrag._bn_kfrag_id == cfrag._bn_kfrag_id
|
||||
assert new_cfrag._point_noninteractive == cfrag._point_noninteractive
|
||||
|
||||
new_proof = new_cfrag.proof
|
||||
assert new_proof is not None
|
||||
assert new_proof.point_eph_e2 == proof.point_eph_e2
|
||||
assert new_proof.point_eph_v2 == proof.point_eph_v2
|
||||
assert new_proof.point_kfrag_commitment == proof.point_kfrag_commitment
|
||||
assert new_proof.point_kfrag_pok == proof.point_kfrag_pok
|
||||
assert new_proof.bn_kfrag_sig1 == proof.bn_kfrag_sig1
|
||||
assert new_proof.bn_kfrag_sig2 == proof.bn_kfrag_sig2
|
||||
assert new_proof.bn_sig == proof.bn_sig
|
||||
assert new_proof._point_e2 == proof._point_e2
|
||||
assert new_proof._point_v2 == proof._point_v2
|
||||
assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment
|
||||
assert new_proof._point_kfrag_pok == proof._point_kfrag_pok
|
||||
assert new_proof._bn_kfrag_sig1 == proof._bn_kfrag_sig1
|
||||
assert new_proof._bn_kfrag_sig2 == proof._bn_kfrag_sig2
|
||||
assert new_proof._bn_sig == proof._bn_sig
|
||||
assert new_proof.metadata is None
|
||||
|
||||
def test_cfrag_serialization_no_proof_no_metadata(alices_keys):
|
||||
|
@ -113,10 +113,10 @@ def test_cfrag_serialization_no_proof_no_metadata(alices_keys):
|
|||
assert len(cfrag_bytes) == 33 + 33 + 33 + 32 == 131
|
||||
|
||||
new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes)
|
||||
assert new_cfrag.point_eph_e1 == cfrag.point_eph_e1
|
||||
assert new_cfrag.point_eph_v1 == cfrag.point_eph_v1
|
||||
assert new_cfrag.bn_kfrag_id == cfrag.bn_kfrag_id
|
||||
assert new_cfrag.point_eph_ni == cfrag.point_eph_ni
|
||||
assert new_cfrag._point_e1 == cfrag._point_e1
|
||||
assert new_cfrag._point_v1 == cfrag._point_v1
|
||||
assert new_cfrag._bn_kfrag_id == cfrag._bn_kfrag_id
|
||||
assert new_cfrag._point_noninteractive == cfrag._point_noninteractive
|
||||
|
||||
new_proof = new_cfrag.proof
|
||||
assert new_proof is None
|
||||
|
|
|
@ -9,13 +9,14 @@ from io import BytesIO
|
|||
|
||||
|
||||
class KFrag(object):
|
||||
def __init__(self, id_, key, x, u1, z1, z2):
|
||||
self.bn_id = id_
|
||||
self.bn_key = key
|
||||
self.point_eph_ni = x
|
||||
self.point_commitment = u1
|
||||
self.bn_sig1 = z1
|
||||
self.bn_sig2 = z2
|
||||
def __init__(self, bn_id, bn_key, point_noninteractive,
|
||||
point_commitment, bn_sig1, bn_sig2):
|
||||
self._bn_id = bn_id
|
||||
self._bn_key = bn_key
|
||||
self._point_noninteractive = point_noninteractive
|
||||
self._point_commitment = point_commitment
|
||||
self._bn_sig1 = bn_sig1
|
||||
self._bn_sig2 = bn_sig2
|
||||
|
||||
@classmethod
|
||||
def from_bytes(cls, data: bytes, curve: ec.EllipticCurve = None):
|
||||
|
@ -30,60 +31,63 @@ class KFrag(object):
|
|||
# keysize + 1 bytes long.
|
||||
id = BigNum.from_bytes(data.read(key_size), curve)
|
||||
key = BigNum.from_bytes(data.read(key_size), curve)
|
||||
eph_ni = Point.from_bytes(data.read(key_size + 1), curve)
|
||||
ni = Point.from_bytes(data.read(key_size + 1), curve)
|
||||
commitment = Point.from_bytes(data.read(key_size + 1), curve)
|
||||
sig1 = BigNum.from_bytes(data.read(key_size), curve)
|
||||
sig2 = BigNum.from_bytes(data.read(key_size), curve)
|
||||
|
||||
return cls(id, key, eph_ni, commitment, sig1, sig2)
|
||||
return cls(id, key, ni, commitment, sig1, sig2)
|
||||
|
||||
def to_bytes(self):
|
||||
"""
|
||||
Serialize the KFrag into a bytestring.
|
||||
"""
|
||||
id = self.bn_id.to_bytes()
|
||||
key = self.bn_key.to_bytes()
|
||||
eph_ni = self.point_eph_ni.to_bytes()
|
||||
commitment = self.point_commitment.to_bytes()
|
||||
sig1 = self.bn_sig1.to_bytes()
|
||||
sig2 = self.bn_sig2.to_bytes()
|
||||
id = self._bn_id.to_bytes()
|
||||
key = self._bn_key.to_bytes()
|
||||
ni = self._point_noninteractive.to_bytes()
|
||||
commitment = self._point_commitment.to_bytes()
|
||||
sig1 = self._bn_sig1.to_bytes()
|
||||
sig2 = self._bn_sig2.to_bytes()
|
||||
|
||||
return id + key + eph_ni + commitment + sig1 + sig2
|
||||
return id + key + ni + commitment + sig1 + sig2
|
||||
|
||||
def verify(self, pub_a, pub_b, params: "UmbralParameters"=None):
|
||||
params = params if params is not None else default_params()
|
||||
|
||||
u = params.u
|
||||
|
||||
u1 = self.point_commitment
|
||||
z1 = self.bn_sig1
|
||||
z2 = self.bn_sig2
|
||||
x = self.point_eph_ni
|
||||
key = self.bn_key
|
||||
u1 = self._point_commitment
|
||||
z1 = self._bn_sig1
|
||||
z2 = self._bn_sig2
|
||||
x = self._point_noninteractive
|
||||
key = self._bn_key
|
||||
|
||||
# We check that the commitment u1 is well-formed
|
||||
check_kfrag_1 = u1 == key * u
|
||||
correct_commitment = u1 == key * u
|
||||
|
||||
# We check the Schnorr signature over the kfrag components
|
||||
g_y = (z2 * params.g) + (z1 * pub_a)
|
||||
check_kfrag_2 = z1 == BigNum.hash_to_bn(g_y, self.bn_id, pub_a, pub_b, u1, x, params=params)
|
||||
|
||||
|
||||
return check_kfrag_1 & check_kfrag_2
|
||||
kfrag_components = [g_y, self._bn_id, pub_a, pub_b, u1, x]
|
||||
valid_kfrag_signature = z1 == BigNum.hash_to_bn(*kfrag_components, params=params)
|
||||
|
||||
return correct_commitment & valid_kfrag_signature
|
||||
|
||||
def __bytes__(self):
|
||||
return self.to_bytes()
|
||||
|
||||
|
||||
class CorrectnessProof(object):
|
||||
def __init__(self, e2, v2, u1, u2, z1, z2, z3, metadata:bytes=None):
|
||||
self.point_eph_e2 = e2
|
||||
self.point_eph_v2 = v2
|
||||
self.point_kfrag_commitment = u1
|
||||
self.point_kfrag_pok = u2
|
||||
self.bn_kfrag_sig1 = z1
|
||||
self.bn_kfrag_sig2 = z2
|
||||
self.bn_sig = z3
|
||||
def __init__(self, point_e2, point_v2, point_kfrag_commitment,
|
||||
point_kfrag_pok, bn_kfrag_sig1, bn_kfrag_sig2, bn_sig,
|
||||
metadata:bytes=None):
|
||||
self._point_e2 = point_e2
|
||||
self._point_v2 = point_v2
|
||||
self._point_kfrag_commitment = point_kfrag_commitment
|
||||
self._point_kfrag_pok = point_kfrag_pok
|
||||
self._bn_kfrag_sig1 = bn_kfrag_sig1
|
||||
self._bn_kfrag_sig2 = bn_kfrag_sig2
|
||||
self._bn_sig = bn_sig
|
||||
self.metadata = metadata
|
||||
|
||||
@classmethod
|
||||
|
@ -114,13 +118,13 @@ class CorrectnessProof(object):
|
|||
"""
|
||||
Serialize the CorrectnessProof to a bytestring.
|
||||
"""
|
||||
e2 = self.point_eph_e2.to_bytes()
|
||||
v2 = self.point_eph_v2.to_bytes()
|
||||
kfrag_commitment = self.point_kfrag_commitment.to_bytes()
|
||||
kfrag_pok = self.point_kfrag_pok.to_bytes()
|
||||
kfrag_sig1 = self.bn_kfrag_sig1.to_bytes()
|
||||
kfrag_sig2 = self.bn_kfrag_sig2.to_bytes()
|
||||
sig = self.bn_sig.to_bytes()
|
||||
e2 = self._point_e2.to_bytes()
|
||||
v2 = self._point_v2.to_bytes()
|
||||
kfrag_commitment = self._point_kfrag_commitment.to_bytes()
|
||||
kfrag_pok = self._point_kfrag_pok.to_bytes()
|
||||
kfrag_sig1 = self._bn_kfrag_sig1.to_bytes()
|
||||
kfrag_sig2 = self._bn_kfrag_sig2.to_bytes()
|
||||
sig = self._bn_sig.to_bytes()
|
||||
|
||||
result = e2 \
|
||||
+ v2 \
|
||||
|
@ -139,11 +143,12 @@ class CorrectnessProof(object):
|
|||
|
||||
|
||||
class CapsuleFrag(object):
|
||||
def __init__(self, e1, v1, id_, x, proof: CorrectnessProof=None):
|
||||
self.point_eph_e1 = e1
|
||||
self.point_eph_v1 = v1
|
||||
self.bn_kfrag_id = id_
|
||||
self.point_eph_ni = x
|
||||
def __init__(self, point_e1, point_v1, bn_kfrag_id, point_noninteractive,
|
||||
proof: CorrectnessProof=None):
|
||||
self._point_e1 = point_e1
|
||||
self._point_v1 = point_v1
|
||||
self._bn_kfrag_id = bn_kfrag_id
|
||||
self._point_noninteractive = point_noninteractive
|
||||
self.proof = proof
|
||||
|
||||
@classmethod
|
||||
|
@ -160,23 +165,23 @@ class CapsuleFrag(object):
|
|||
e1 = Point.from_bytes(data.read(key_size + 1), curve)
|
||||
v1 = Point.from_bytes(data.read(key_size + 1), curve)
|
||||
kfrag_id = BigNum.from_bytes(data.read(key_size), curve)
|
||||
eph_ni = Point.from_bytes(data.read(key_size + 1), curve)
|
||||
ni = Point.from_bytes(data.read(key_size + 1), curve)
|
||||
|
||||
proof = data.read() or None
|
||||
proof = CorrectnessProof.from_bytes(proof, curve) if proof else None
|
||||
|
||||
return cls(e1, v1, kfrag_id, eph_ni, proof)
|
||||
return cls(e1, v1, kfrag_id, ni, proof)
|
||||
|
||||
def to_bytes(self):
|
||||
"""
|
||||
Serialize the CapsuleFrag into a bytestring.
|
||||
"""
|
||||
e1 = self.point_eph_e1.to_bytes()
|
||||
v1 = self.point_eph_v1.to_bytes()
|
||||
kfrag_id = self.bn_kfrag_id.to_bytes()
|
||||
eph_ni = self.point_eph_ni.to_bytes()
|
||||
e1 = self._point_e1.to_bytes()
|
||||
v1 = self._point_v1.to_bytes()
|
||||
kfrag_id = self._bn_kfrag_id.to_bytes()
|
||||
ni = self._point_noninteractive.to_bytes()
|
||||
|
||||
serialized_cfrag = e1 + v1 + kfrag_id + eph_ni
|
||||
serialized_cfrag = e1 + v1 + kfrag_id + ni
|
||||
|
||||
if self.proof is not None:
|
||||
serialized_cfrag += self.proof.to_bytes()
|
||||
|
|
167
umbral/pre.py
167
umbral/pre.py
|
@ -32,38 +32,38 @@ class UmbralCorrectnessError(GenericUmbralError):
|
|||
class Capsule(object):
|
||||
|
||||
def __init__(self,
|
||||
point_eph_e=None,
|
||||
point_eph_v=None,
|
||||
point_e=None,
|
||||
point_v=None,
|
||||
bn_sig=None,
|
||||
e_prime=None,
|
||||
v_prime=None,
|
||||
noninteractive_point=None):
|
||||
point_e_prime=None,
|
||||
point_v_prime=None,
|
||||
point_noninteractive=None):
|
||||
|
||||
if isinstance(point_eph_e, Point):
|
||||
if not isinstance(point_eph_v, Point) or not isinstance(bn_sig, BigNum):
|
||||
raise TypeError("Need point_eph_e, point_eph_v, and bn_sig to make a Capsule.")
|
||||
elif isinstance(e_prime, Point):
|
||||
if not isinstance(v_prime, Point) or not isinstance(noninteractive_point, Point):
|
||||
raise TypeError("Need e_prime, v_prime, and noninteractive_point to make an activated Capsule.")
|
||||
if isinstance(point_e, Point):
|
||||
if not isinstance(point_v, Point) or not isinstance(bn_sig, BigNum):
|
||||
raise TypeError("Need point_e, point_v, and bn_sig to make a Capsule.")
|
||||
elif isinstance(point_e_prime, Point):
|
||||
if not isinstance(point_v_prime, Point) or not isinstance(point_noninteractive, Point):
|
||||
raise TypeError("Need e_prime, v_prime, and point_noninteractive to make an activated Capsule.")
|
||||
else:
|
||||
raise TypeError(
|
||||
"Need proper Points and/or BigNums to make a Capsule. Pass either Alice's data or Bob's. " \
|
||||
"Passing both is also fine.")
|
||||
|
||||
self._point_eph_e = point_eph_e
|
||||
self._point_eph_v = point_eph_v
|
||||
self._point_e = point_e
|
||||
self._point_v = point_v
|
||||
self._bn_sig = bn_sig
|
||||
|
||||
self._point_eph_e_prime = e_prime
|
||||
self._point_eph_v_prime = v_prime
|
||||
self._point_noninteractive = noninteractive_point
|
||||
self._point_e_prime = point_e_prime
|
||||
self._point_v_prime = point_v_prime
|
||||
self._point_noninteractive = point_noninteractive
|
||||
|
||||
self._attached_cfrags = {}
|
||||
self._contents = None
|
||||
|
||||
class NotValid(ValueError):
|
||||
"""
|
||||
raised if the capusle does not pass verification.
|
||||
raised if the capsule does not pass verification.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
|
@ -78,20 +78,21 @@ class Capsule(object):
|
|||
# BigNums are the keysize in bytes, Points are compressed and the
|
||||
# keysize + 1 bytes long.
|
||||
if len(capsule_bytes) == 197:
|
||||
eph_e = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
eph_v = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
e = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
v = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
sig = BigNum.from_bytes(capsule_buff.read(key_size), curve)
|
||||
e_prime = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
v_prime = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
eph_ni = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
ni = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
else:
|
||||
eph_e = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
eph_v = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
e = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
v = Point.from_bytes(capsule_buff.read(key_size + 1), curve)
|
||||
sig = BigNum.from_bytes(capsule_buff.read(key_size), curve)
|
||||
e_prime = v_prime = eph_ni = None
|
||||
e_prime = v_prime = ni = None
|
||||
|
||||
return cls(point_eph_e=eph_e, point_eph_v=eph_v, bn_sig=sig,
|
||||
e_prime=e_prime, v_prime=v_prime, noninteractive_point=eph_ni)
|
||||
return cls(point_e=e, point_v=v, bn_sig=sig,
|
||||
point_e_prime=e_prime, point_v_prime=v_prime,
|
||||
point_noninteractive=ni)
|
||||
|
||||
def _original_to_bytes(self) -> bytes:
|
||||
return bytes().join(c.to_bytes() for c in self.original_components())
|
||||
|
@ -108,21 +109,21 @@ class Capsule(object):
|
|||
def verify(self, params: UmbralParameters=None) -> bool:
|
||||
params = params if params is not None else default_params()
|
||||
|
||||
e = self._point_eph_e
|
||||
v = self._point_eph_v
|
||||
e = self._point_e
|
||||
v = self._point_v
|
||||
s = self._bn_sig
|
||||
h = BigNum.hash_to_bn(e, v, params=params)
|
||||
|
||||
return s * params.g == v + (h * e)
|
||||
|
||||
def attach_cfrag(self, cfrag: CapsuleFrag) -> None:
|
||||
self._attached_cfrags[cfrag.bn_kfrag_id] = cfrag
|
||||
self._attached_cfrags[cfrag._bn_kfrag_id] = cfrag
|
||||
|
||||
def original_components(self) -> Tuple[Point, Point, BigNum]:
|
||||
return self._point_eph_e, self._point_eph_v, self._bn_sig
|
||||
return self._point_e, self._point_v, self._bn_sig
|
||||
|
||||
def activated_components(self) -> Union[Tuple[None, None, None], Tuple[Point, Point, Point]]:
|
||||
return self._point_eph_e_prime, self._point_eph_v_prime, self._point_noninteractive
|
||||
return self._point_e_prime, self._point_v_prime, self._point_noninteractive
|
||||
|
||||
def _reconstruct_shamirs_secret(self,
|
||||
pub_a: Union[UmbralPublicKey, Point],
|
||||
|
@ -151,24 +152,24 @@ class Capsule(object):
|
|||
id_0, cfrag_0 = id_cfrag_pairs[0]
|
||||
x_0 = BigNum.hash_to_bn(id_0, hashed_dh_tuple, params=params)
|
||||
if len(id_cfrag_pairs) > 1:
|
||||
xs = [BigNum.hash_to_bn(_id, hashed_dh_tuple, params=params)
|
||||
for _id in self._attached_cfrags.keys()]
|
||||
xs = [BigNum.hash_to_bn(id_, hashed_dh_tuple, params=params)
|
||||
for id_ in self._attached_cfrags.keys()]
|
||||
lambda_0 = lambda_coeff(x_0, xs)
|
||||
e = lambda_0 * cfrag_0.point_eph_e1
|
||||
v = lambda_0 * cfrag_0.point_eph_v1
|
||||
e = lambda_0 * cfrag_0._point_e1
|
||||
v = lambda_0 * cfrag_0._point_v1
|
||||
|
||||
for id_i, cfrag in id_cfrag_pairs[1:]:
|
||||
x_i = BigNum.hash_to_bn(id_i, hashed_dh_tuple, params=params)
|
||||
lambda_i = lambda_coeff(x_i, xs)
|
||||
e = e + (lambda_i * cfrag.point_eph_e1)
|
||||
v = v + (lambda_i * cfrag.point_eph_v1)
|
||||
e = e + (lambda_i * cfrag._point_e1)
|
||||
v = v + (lambda_i * cfrag._point_v1)
|
||||
else:
|
||||
e = cfrag_0.point_eph_e1
|
||||
v = cfrag_0.point_eph_v1
|
||||
e = cfrag_0._point_e1
|
||||
v = cfrag_0._point_v1
|
||||
|
||||
self._point_eph_e_prime = e
|
||||
self._point_eph_v_prime = v
|
||||
self._point_noninteractive = cfrag_0.point_eph_ni
|
||||
self._point_e_prime = e
|
||||
self._point_v_prime = v
|
||||
self._point_noninteractive = cfrag_0._point_noninteractive
|
||||
|
||||
def __bytes__(self):
|
||||
return self.to_bytes()
|
||||
|
@ -203,9 +204,6 @@ class Capsule(object):
|
|||
return hash(component_bytes)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def split_rekey(priv_a: Union[UmbralPrivateKey, BigNum],
|
||||
pub_b: Union[UmbralPublicKey, Point],
|
||||
threshold: int, N: int,
|
||||
|
@ -259,7 +257,9 @@ def split_rekey(priv_a: Union[UmbralPrivateKey, BigNum],
|
|||
z1 = BigNum.hash_to_bn(y * g, id_kfrag, pub_a, pub_b, u1, xcomp, params=params)
|
||||
z2 = y - priv_a * z1
|
||||
|
||||
kfrag = KFrag(id_=id_kfrag, key=rk, x=xcomp, u1=u1, z1=z1, z2=z2)
|
||||
kfrag = KFrag(bn_id=id_kfrag, bn_key=rk,
|
||||
point_noninteractive=xcomp, point_commitment=u1,
|
||||
bn_sig1=z1, bn_sig2=z2)
|
||||
kfrags.append(kfrag)
|
||||
|
||||
return kfrags
|
||||
|
@ -273,10 +273,11 @@ def reencrypt(kfrag: KFrag, capsule: Capsule, params: UmbralParameters=None,
|
|||
if not capsule.verify(params):
|
||||
raise capsule.NotValid
|
||||
|
||||
e1 = kfrag.bn_key * capsule._point_eph_e
|
||||
v1 = kfrag.bn_key * capsule._point_eph_v
|
||||
e1 = kfrag._bn_key * capsule._point_e
|
||||
v1 = kfrag._bn_key * capsule._point_v
|
||||
|
||||
cfrag = CapsuleFrag(e1=e1, v1=v1, id_=kfrag.bn_id, x=kfrag.point_eph_ni)
|
||||
cfrag = CapsuleFrag(point_e1=e1, point_v1=v1, bn_kfrag_id=kfrag._bn_id,
|
||||
point_noninteractive=kfrag._point_noninteractive)
|
||||
|
||||
if provide_proof:
|
||||
_prove_correctness(cfrag, kfrag, capsule, metadata, params)
|
||||
|
@ -289,14 +290,16 @@ def _prove_correctness(cfrag: CapsuleFrag, kfrag: KFrag, capsule: Capsule,
|
|||
) -> CorrectnessProof:
|
||||
params = params if params is not None else default_params()
|
||||
|
||||
e1 = cfrag.point_eph_e1
|
||||
v1 = cfrag.point_eph_v1
|
||||
e1 = cfrag._point_e1
|
||||
v1 = cfrag._point_v1
|
||||
|
||||
e = capsule._point_eph_e
|
||||
v = capsule._point_eph_v
|
||||
e = capsule._point_e
|
||||
v = capsule._point_v
|
||||
|
||||
u = params.u
|
||||
u1 = kfrag.point_commitment
|
||||
u1 = kfrag._point_commitment
|
||||
|
||||
rk = kfrag._bn_key
|
||||
|
||||
t = BigNum.gen_rand(params.curve)
|
||||
e2 = t * e
|
||||
|
@ -310,13 +313,16 @@ def _prove_correctness(cfrag: CapsuleFrag, kfrag: KFrag, capsule: Capsule,
|
|||
|
||||
h = BigNum.hash_to_bn(*hash_input, params=params)
|
||||
|
||||
z3 = t + h * kfrag.bn_key
|
||||
z3 = t + h * rk
|
||||
|
||||
proof = CorrectnessProof(e2=e2, v2=v2, u1=u1, u2=u2,
|
||||
z1=kfrag.bn_sig1, z2=kfrag.bn_sig2, z3=z3,
|
||||
metadata=metadata)
|
||||
|
||||
cfrag.proof = proof
|
||||
cfrag.proof = CorrectnessProof(point_e2=e2,
|
||||
point_v2=v2,
|
||||
point_kfrag_commitment=u1,
|
||||
point_kfrag_pok=u2,
|
||||
bn_kfrag_sig1=kfrag._bn_sig1,
|
||||
bn_kfrag_sig2=kfrag._bn_sig2,
|
||||
bn_sig=z3,
|
||||
metadata=metadata)
|
||||
|
||||
# Check correctness of original ciphertext (check nº 2) at the end
|
||||
# to avoid timing oracles
|
||||
|
@ -332,26 +338,26 @@ def _verify_correctness(capsule: Capsule, cfrag: CapsuleFrag,
|
|||
|
||||
params = params if params is not None else default_params()
|
||||
|
||||
e = capsule._point_eph_e
|
||||
v = capsule._point_eph_v
|
||||
e = capsule._point_e
|
||||
v = capsule._point_v
|
||||
|
||||
e1 = cfrag.point_eph_e1
|
||||
v1 = cfrag.point_eph_v1
|
||||
xcomp = cfrag.point_eph_ni
|
||||
kfrag_id = cfrag.bn_kfrag_id
|
||||
e1 = cfrag._point_e1
|
||||
v1 = cfrag._point_v1
|
||||
xcomp = cfrag._point_noninteractive
|
||||
kfrag_id = cfrag._bn_kfrag_id
|
||||
|
||||
e2 = proof.point_eph_e2
|
||||
v2 = proof.point_eph_v2
|
||||
e2 = proof._point_e2
|
||||
v2 = proof._point_v2
|
||||
|
||||
g = params.g
|
||||
u = params.u
|
||||
|
||||
u1 = proof.point_kfrag_commitment
|
||||
u2 = proof.point_kfrag_pok
|
||||
u1 = proof._point_kfrag_commitment
|
||||
u2 = proof._point_kfrag_pok
|
||||
|
||||
z1 = proof.bn_kfrag_sig1
|
||||
z2 = proof.bn_kfrag_sig2
|
||||
z3 = proof.bn_sig
|
||||
z1 = proof._bn_kfrag_sig1
|
||||
z2 = proof._bn_kfrag_sig2
|
||||
z3 = proof._bn_sig
|
||||
|
||||
g_y = (z2 * g) + (z1 * pub_a)
|
||||
|
||||
|
@ -366,7 +372,9 @@ def _verify_correctness(capsule: Capsule, cfrag: CapsuleFrag,
|
|||
valid_kfrag_signature = z1 == kfrag_signature1
|
||||
|
||||
correct_reencryption_of_e = z3 * e == e2 + (h * e1)
|
||||
|
||||
correct_reencryption_of_v = z3 * v == v2 + (h * v1)
|
||||
|
||||
correct_rk_commitment = z3 * u == u2 + (h * u1)
|
||||
|
||||
return valid_kfrag_signature \
|
||||
|
@ -395,7 +403,7 @@ def _encapsulate(alice_pub_key: Point, key_length=32,
|
|||
# Key to be used for symmetric encryption
|
||||
key = kdf(shared_key, key_length)
|
||||
|
||||
return key, Capsule(point_eph_e=pub_r, point_eph_v=pub_u, bn_sig=s)
|
||||
return key, Capsule(point_e=pub_r, point_v=pub_u, bn_sig=s)
|
||||
|
||||
|
||||
def _decapsulate_original(priv_key: BigNum, capsule: Capsule, key_length=32,
|
||||
|
@ -403,7 +411,7 @@ def _decapsulate_original(priv_key: BigNum, capsule: Capsule, key_length=32,
|
|||
"""Derive the same symmetric key"""
|
||||
params = params if params is not None else default_params()
|
||||
|
||||
shared_key = priv_key * (capsule._point_eph_e+capsule._point_eph_v)
|
||||
shared_key = priv_key * (capsule._point_e+capsule._point_v)
|
||||
key = kdf(shared_key, key_length)
|
||||
|
||||
if not capsule.verify(params):
|
||||
|
@ -423,15 +431,15 @@ def _decapsulate_reencrypted(pub_key: Point, priv_key: BigNum,
|
|||
xcomp = capsule._point_noninteractive
|
||||
d = BigNum.hash_to_bn(xcomp, pub_key, priv_key * xcomp, params=params)
|
||||
|
||||
e_prime = capsule._point_eph_e_prime
|
||||
v_prime = capsule._point_eph_v_prime
|
||||
e_prime = capsule._point_e_prime
|
||||
v_prime = capsule._point_v_prime
|
||||
|
||||
shared_key = d * (e_prime + v_prime)
|
||||
|
||||
key = kdf(shared_key, key_length)
|
||||
|
||||
e = capsule._point_eph_e
|
||||
v = capsule._point_eph_v
|
||||
e = capsule._point_e
|
||||
v = capsule._point_v
|
||||
s = capsule._bn_sig
|
||||
h = BigNum.hash_to_bn(e, v, params=params)
|
||||
inv_d = ~d
|
||||
|
@ -485,7 +493,8 @@ def _open_capsule(capsule: Capsule, bob_privkey: UmbralPrivateKey,
|
|||
offending_cfrags.append(cfrag)
|
||||
|
||||
if offending_cfrags:
|
||||
raise UmbralCorrectnessError("Some CFrags are not correct", offending_cfrags)
|
||||
error_msg = "Decryption error: Some CFrags are not correct"
|
||||
raise UmbralCorrectnessError(error_msg, offending_cfrags)
|
||||
|
||||
capsule._reconstruct_shamirs_secret(pub_a, priv_b, params=params)
|
||||
|
||||
|
|
Loading…
Reference in New Issue