mirror of https://github.com/nucypher/pyUmbral.git
Verify Capsules once on creation
parent
3e95809fea
commit
6696ebb2b3
|
@ -33,16 +33,6 @@ def test_capsule_creation(alices_keys):
|
|||
with pytest.raises(TypeError):
|
||||
rare_capsule = Capsule(params) # Alice cannot make a capsule this way.
|
||||
|
||||
|
||||
|
||||
# Some users may create capsules their own way.
|
||||
custom_capsule = Capsule(params,
|
||||
point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=CurveBN.gen_rand())
|
||||
|
||||
assert isinstance(custom_capsule, Capsule)
|
||||
|
||||
# Typical Alice, constructing a typical capsule
|
||||
delegating_privkey, _signing_key = alices_keys
|
||||
plaintext = b'peace at dawn'
|
||||
|
@ -50,19 +40,41 @@ def test_capsule_creation(alices_keys):
|
|||
|
||||
assert isinstance(typical_capsule, Capsule)
|
||||
|
||||
# Some users may create capsules their own way.
|
||||
# Using the data from the previously created capsule to make sure it will pass verification.
|
||||
custom_capsule = Capsule(params,
|
||||
point_e=typical_capsule.point_e,
|
||||
point_v=typical_capsule.point_v,
|
||||
bn_sig=typical_capsule.bn_sig)
|
||||
|
||||
def test_capsule_equality():
|
||||
assert isinstance(custom_capsule, Capsule)
|
||||
|
||||
|
||||
def test_capsule_equality(alices_keys):
|
||||
params = default_params()
|
||||
delegating_privkey, _signing_key = alices_keys
|
||||
plaintext = b'peace at dawn'
|
||||
_ciphertext, typical_capsule = pre.encrypt(delegating_privkey.get_pubkey(), plaintext)
|
||||
|
||||
one_capsule = Capsule(params,
|
||||
point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=CurveBN.gen_rand())
|
||||
point_e=typical_capsule.point_e,
|
||||
point_v=typical_capsule.point_v,
|
||||
bn_sig=typical_capsule.bn_sig)
|
||||
|
||||
same_capsule = Capsule(params,
|
||||
point_e=typical_capsule.point_e,
|
||||
point_v=typical_capsule.point_v,
|
||||
bn_sig=typical_capsule.bn_sig)
|
||||
|
||||
assert one_capsule == same_capsule
|
||||
|
||||
# Capsule creation involves RNG, so it will have different components
|
||||
_ciphertext, another_typical_capsule = pre.encrypt(delegating_privkey.get_pubkey(), plaintext)
|
||||
|
||||
another_capsule = Capsule(params,
|
||||
point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=CurveBN.gen_rand())
|
||||
point_e=another_typical_capsule.point_e,
|
||||
point_v=another_typical_capsule.point_v,
|
||||
bn_sig=another_typical_capsule.bn_sig)
|
||||
|
||||
assert one_capsule != another_capsule
|
||||
|
||||
|
@ -80,17 +92,14 @@ def test_decapsulation_by_alice(alices_keys):
|
|||
assert sym_key_2 == sym_key
|
||||
|
||||
|
||||
def test_bad_capsule_fails_reencryption(kfrags):
|
||||
def test_bad_capsule_cannot_be_created():
|
||||
params = default_params()
|
||||
|
||||
bollocks_capsule = Capsule(params,
|
||||
point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=CurveBN.gen_rand())
|
||||
|
||||
for kfrag in kfrags:
|
||||
with pytest.raises(Capsule.NotValid):
|
||||
pre.reencrypt(kfrag, bollocks_capsule)
|
||||
with pytest.raises(Capsule.NotValid, match="Capsule verification failed."):
|
||||
bollocks_capsule = Capsule(params,
|
||||
point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=CurveBN.gen_rand())
|
||||
|
||||
|
||||
def test_capsule_as_dict_key(alices_keys, bobs_keys):
|
||||
|
|
|
@ -26,7 +26,7 @@ from umbral.keys import UmbralPrivateKey, UmbralPublicKey
|
|||
from umbral.params import UmbralParameters
|
||||
from umbral.point import Point
|
||||
from umbral.random_oracles import unsafe_hash_to_point
|
||||
from umbral.pre import Capsule
|
||||
from umbral.pre import Capsule, _encapsulate
|
||||
|
||||
# test parameters
|
||||
max_examples = 1000
|
||||
|
@ -43,6 +43,10 @@ bns = integers(min_value=1, max_value=backend._bn_to_int(curve.order)).map(
|
|||
points = binary(min_size=1).map(
|
||||
lambda x: unsafe_hash_to_point(x, label=b'hypothesis', params=params))
|
||||
|
||||
public_keys = points.map(lambda p: UmbralPublicKey(p, params))
|
||||
|
||||
capsules = public_keys.map(lambda pk: _encapsulate(pk)[1])
|
||||
|
||||
signatures = tuples(integers(min_value=1, max_value=backend._bn_to_int(curve.order)),
|
||||
integers(min_value=1, max_value=backend._bn_to_int(curve.order))).map(
|
||||
lambda tup: tup[0].to_bytes(bn_size, 'big') + tup[1].to_bytes(bn_size, 'big'))
|
||||
|
@ -86,10 +90,10 @@ def test_kfrag_roundtrip(d, b0, p0, p1, sig_proxy, sig_bob):
|
|||
signature_for_proxy=sig_proxy, signature_for_bob=sig_bob)
|
||||
assert_kfrag_eq(k, KFrag.from_bytes(k.to_bytes()))
|
||||
|
||||
@given(points, points, bns)
|
||||
@given(capsules)
|
||||
@settings(max_examples=max_examples)
|
||||
def test_capsule_roundtrip_0(p0, p1, b):
|
||||
c = Capsule(params=params, point_e=p0, point_v=p1, bn_sig=b)
|
||||
def test_capsule_roundtrip_0(capsule):
|
||||
c = Capsule(params=params, point_e=capsule.point_e, point_v=capsule.point_v, bn_sig=capsule.bn_sig)
|
||||
assert(c == Capsule.from_bytes(c.to_bytes(), params=params))
|
||||
|
||||
@given(points, points, points, points, bns, signatures)
|
||||
|
|
|
@ -61,10 +61,6 @@ class CorrectnessProof:
|
|||
|
||||
params = capsule.params
|
||||
|
||||
# Check correctness of original ciphertext
|
||||
if not capsule.verify():
|
||||
raise capsule.NotValid("Capsule verification failed.")
|
||||
|
||||
rk = kfrag.bn_key
|
||||
t = CurveBN.gen_rand(params.curve)
|
||||
####
|
||||
|
|
|
@ -74,6 +74,10 @@ class Capsule:
|
|||
self.point_v = point_v
|
||||
self.bn_sig = bn_sig
|
||||
|
||||
if not self._verify():
|
||||
# Check correctness of original ciphertext
|
||||
raise self.NotValid("Capsule verification failed.")
|
||||
|
||||
class NotValid(ValueError):
|
||||
"""
|
||||
raised if the capsule does not pass verification.
|
||||
|
@ -128,7 +132,7 @@ class Capsule:
|
|||
e, v, s = self.components()
|
||||
return e.to_bytes() + v.to_bytes() + s.to_bytes()
|
||||
|
||||
def verify(self) -> bool:
|
||||
def _verify(self):
|
||||
|
||||
g = self.params.g
|
||||
e, v, s = self.components()
|
||||
|
@ -182,9 +186,6 @@ class PreparedCapsule:
|
|||
|
||||
self._attached_cfrags = set() # type: set
|
||||
|
||||
def verify(self):
|
||||
return self.capsule.verify()
|
||||
|
||||
def verify_cfrag(self, cfrag) -> bool:
|
||||
return cfrag.verify_correctness(capsule=self.capsule,
|
||||
delegating_pubkey=self.delegating_key,
|
||||
|
@ -319,9 +320,6 @@ def reencrypt(kfrag: KFrag,
|
|||
if not isinstance(prepared_capsule, PreparedCapsule):
|
||||
raise Capsule.NotValid
|
||||
|
||||
if not prepared_capsule.verify():
|
||||
raise Capsule.NotValid
|
||||
|
||||
if verify_kfrag:
|
||||
if not isinstance(kfrag, KFrag) or not prepared_capsule.verify_kfrag(kfrag):
|
||||
raise KFrag.NotValid
|
||||
|
@ -358,10 +356,6 @@ def _decapsulate_original(private_key: UmbralPrivateKey,
|
|||
key_length: int = DEM_KEYSIZE) -> bytes:
|
||||
"""Derive the same symmetric key"""
|
||||
|
||||
if not capsule.verify():
|
||||
# Check correctness of original ciphertext
|
||||
raise capsule.NotValid("Capsule verification failed.")
|
||||
|
||||
shared_key = private_key.bn_key * (capsule.point_e + capsule.point_v) # type: Any
|
||||
key = kdf(shared_key, key_length)
|
||||
return key
|
||||
|
@ -482,9 +476,6 @@ def decrypt_original(ciphertext: bytes,
|
|||
We hope that's a symmetric key, which we use to decrypt the ciphertext
|
||||
and return the resulting cleartext.
|
||||
"""
|
||||
if not capsule.verify():
|
||||
raise Capsule.NotValid
|
||||
|
||||
encapsulated_key = _decapsulate_original(decrypting_key, capsule)
|
||||
return _dem_decrypt(encapsulated_key, ciphertext, capsule)
|
||||
|
||||
|
@ -499,8 +490,5 @@ def decrypt_reencrypted(ciphertext: bytes,
|
|||
We hope that's a symmetric key, which we use to decrypt the ciphertext
|
||||
and return the resulting cleartext.
|
||||
"""
|
||||
if not capsule.verify():
|
||||
raise Capsule.NotValid
|
||||
|
||||
encapsulated_key = _open_capsule(capsule, cfrags, decrypting_key, check_proof=check_proof)
|
||||
return _dem_decrypt(encapsulated_key, ciphertext, capsule.capsule)
|
||||
|
|
Loading…
Reference in New Issue