mirror of https://github.com/nucypher/pyUmbral.git
Merge pull request #157 from jMyles/cfrags-with-correctness-proof
Attaching CFrags to a Capsule now requires correctness check and KFrag signature validation.pull/160/head
commit
0ae4210367
|
@ -0,0 +1,104 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from umbral import pre
|
||||
from umbral.curvebn import CurveBN
|
||||
from umbral.fragments import CapsuleFrag
|
||||
from umbral.keys import UmbralPrivateKey
|
||||
from umbral.point import Point
|
||||
from umbral.pre import Capsule
|
||||
from umbral.signing import Signer
|
||||
|
||||
|
||||
def test_cannot_attach_cfrag_without_keys():
|
||||
"""
|
||||
We need the proper keys to verify the correctness of CFrags
|
||||
in order to attach them to a Capsule.
|
||||
"""
|
||||
capsule = Capsule(point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=CurveBN.gen_rand())
|
||||
|
||||
cfrag = CapsuleFrag(point_e1=Point.gen_rand(),
|
||||
point_v1=Point.gen_rand(),
|
||||
kfrag_id=os.urandom(10),
|
||||
point_noninteractive=Point.gen_rand(),
|
||||
point_xcoord=Point.gen_rand(),
|
||||
)
|
||||
with pytest.raises(TypeError):
|
||||
capsule.attach_cfrag(cfrag)
|
||||
|
||||
|
||||
def test_set_correctness_keys(alices_keys, bobs_keys):
|
||||
"""
|
||||
If the three keys do appear together, along with the capsule,
|
||||
we can attach them all at once.
|
||||
"""
|
||||
|
||||
delegating_privkey, signing_privkey = alices_keys
|
||||
signer = Signer(signing_privkey)
|
||||
priv_key_bob, pub_key_bob = bobs_keys
|
||||
|
||||
plain_data = b'peace at dawn'
|
||||
ciphertext, capsule = pre.encrypt(delegating_privkey.get_pubkey(), plain_data)
|
||||
|
||||
capsule.set_correctness_keys(delegating_privkey.get_pubkey(),
|
||||
pub_key_bob,
|
||||
signing_privkey.get_pubkey()
|
||||
)
|
||||
|
||||
kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, 2, 2)
|
||||
for kfrag in kfrags:
|
||||
cfrag = pre.reencrypt(kfrag, capsule)
|
||||
capsule.attach_cfrag(cfrag)
|
||||
|
||||
|
||||
def test_cannot_attach_cfrag_without_proof():
|
||||
"""
|
||||
However, even when properly attaching keys, we can't attach the CFrag
|
||||
if it is unproven.
|
||||
"""
|
||||
capsule = Capsule(point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=CurveBN.gen_rand())
|
||||
|
||||
cfrag = CapsuleFrag(point_e1=Point.gen_rand(),
|
||||
point_v1=Point.gen_rand(),
|
||||
kfrag_id=os.urandom(10),
|
||||
point_noninteractive=Point.gen_rand(),
|
||||
point_xcoord=Point.gen_rand(),
|
||||
)
|
||||
key_details = capsule.set_correctness_keys(
|
||||
UmbralPrivateKey.gen_key().get_pubkey(),
|
||||
UmbralPrivateKey.gen_key().get_pubkey(),
|
||||
UmbralPrivateKey.gen_key().get_pubkey())
|
||||
|
||||
delegating_details, encrypting_details, verifying_details = key_details
|
||||
|
||||
assert all((delegating_details, encrypting_details, verifying_details))
|
||||
|
||||
with pytest.raises(cfrag.NoProofProvided):
|
||||
capsule.attach_cfrag(cfrag)
|
||||
|
||||
|
||||
def test_cannot_set_different_keys():
|
||||
"""
|
||||
Once a key is set on a Capsule, it can't be changed to a different key.
|
||||
"""
|
||||
capsule = Capsule(point_e=Point.gen_rand(),
|
||||
point_v=Point.gen_rand(),
|
||||
bn_sig=CurveBN.gen_rand())
|
||||
|
||||
capsule.set_correctness_keys(delegating=UmbralPrivateKey.gen_key().get_pubkey(),
|
||||
encrypting=UmbralPrivateKey.gen_key().get_pubkey(),
|
||||
verifying=UmbralPrivateKey.gen_key().get_pubkey())
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
capsule.set_correctness_keys(delegating=UmbralPrivateKey.gen_key().get_pubkey())
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
capsule.set_correctness_keys(encrypting=UmbralPrivateKey.gen_key().get_pubkey())
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
capsule.set_correctness_keys(verifying=UmbralPrivateKey.gen_key().get_pubkey())
|
|
@ -1,6 +1,6 @@
|
|||
import pytest
|
||||
|
||||
from umbral import pre, keys
|
||||
from umbral import pre
|
||||
from umbral.curvebn import CurveBN
|
||||
from umbral.point import Point
|
||||
from umbral.pre import Capsule
|
||||
|
@ -73,15 +73,20 @@ def test_capsule_as_dict_key(alices_keys):
|
|||
# TODO: This test is a little weird - why activate a Capsule from alice to alice? Let's get bob involved.
|
||||
delegating_privkey, signing_privkey = alices_keys
|
||||
signer_alice = Signer(signing_privkey)
|
||||
encrypting_key = delegating_privkey.get_pubkey()
|
||||
|
||||
plain_data = b'peace at dawn'
|
||||
ciphertext, capsule = pre.encrypt(delegating_privkey.get_pubkey(), plain_data)
|
||||
ciphertext, capsule = pre.encrypt(encrypting_key, plain_data)
|
||||
|
||||
capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
|
||||
encrypting=encrypting_key,
|
||||
verifying=signing_privkey.get_pubkey())
|
||||
|
||||
# We can use the capsule as a key, and successfully lookup using it.
|
||||
some_dict = {capsule: "Thing that Bob wants to try per-Capsule"}
|
||||
assert some_dict[capsule] == "Thing that Bob wants to try per-Capsule"
|
||||
|
||||
kfrags = pre.split_rekey(delegating_privkey, signer_alice, delegating_privkey.get_pubkey(), 1, 2)
|
||||
kfrags = pre.split_rekey(delegating_privkey, signer_alice, encrypting_key , 1, 2)
|
||||
cfrag = pre.reencrypt(kfrags[0], capsule)
|
||||
capsule.attach_cfrag(cfrag)
|
||||
|
||||
|
|
|
@ -41,6 +41,11 @@ def test_activated_capsule_serialization(alices_keys, bobs_keys):
|
|||
priv_key_bob, pub_key_bob = bobs_keys
|
||||
|
||||
_unused_key, capsule = pre._encapsulate(pub_key_bob.point_key)
|
||||
|
||||
capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
|
||||
encrypting=pub_key_bob,
|
||||
verifying=signing_privkey.get_pubkey())
|
||||
|
||||
kfrags = pre.split_rekey(delegating_privkey, signer_alice, pub_key_bob, 1, 2)
|
||||
|
||||
cfrag = pre.reencrypt(kfrags[0], capsule)
|
||||
|
|
|
@ -21,9 +21,6 @@ def test_correctness_proof_serialization(alices_keys):
|
|||
metadata = b"This is an example of metadata for re-encryption request"
|
||||
|
||||
cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)
|
||||
|
||||
capsule.attach_cfrag(cfrag)
|
||||
|
||||
proof = cfrag.proof
|
||||
proof_bytes = proof.to_bytes()
|
||||
|
||||
|
@ -53,6 +50,10 @@ def test_cheating_ursula_replays_old_reencryption(N, M, alices_keys):
|
|||
sym_key_alice1, capsule_alice1 = pre._encapsulate(delegating_privkey.get_pubkey().point_key)
|
||||
sym_key_alice2, capsule_alice2 = pre._encapsulate(delegating_privkey.get_pubkey().point_key)
|
||||
|
||||
capsule_alice1.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
|
||||
encrypting=pub_key_bob,
|
||||
verifying=signing_privkey.get_pubkey())
|
||||
|
||||
kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, M, N)
|
||||
|
||||
cfrags, metadata = [], []
|
||||
|
@ -125,6 +126,11 @@ def test_cheating_ursula_sends_garbage(N, M, alices_keys):
|
|||
pub_key_bob = priv_key_bob.get_pubkey()
|
||||
|
||||
sym_key, capsule_alice = pre._encapsulate(delegating_privkey.get_pubkey().point_key)
|
||||
|
||||
capsule_alice.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
|
||||
encrypting=pub_key_bob,
|
||||
verifying=signing_privkey.get_pubkey())
|
||||
|
||||
kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, M, N)
|
||||
|
||||
cfrags, metadata = [], []
|
||||
|
@ -169,7 +175,7 @@ def test_cheating_ursula_sends_garbage(N, M, alices_keys):
|
|||
# We should get an exception with an attached list of incorrect cfrags
|
||||
with pytest.raises(pre.UmbralCorrectnessError) as exception_info:
|
||||
_decapsulated_key = pre._open_capsule(capsule_alice, priv_key_bob, delegating_privkey.get_pubkey(),
|
||||
signing_privkey.get_pubkey())
|
||||
signing_privkey.get_pubkey())
|
||||
correctness_error = exception_info.value
|
||||
assert cfrags[0] in correctness_error.offending_cfrags
|
||||
assert len(correctness_error.offending_cfrags) == 1
|
||||
|
@ -186,15 +192,24 @@ def test_decryption_fails_when_it_expects_a_proof_and_there_isnt(N, M, alices_ke
|
|||
plain_data = b'peace at dawn'
|
||||
ciphertext, capsule = pre.encrypt(delegating_privkey.get_pubkey(), plain_data)
|
||||
|
||||
capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
|
||||
encrypting=pub_key_bob,
|
||||
verifying=signing_privkey.get_pubkey())
|
||||
|
||||
kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, M, N)
|
||||
for kfrag in kfrags:
|
||||
cfrag = pre.reencrypt(kfrag, capsule, provide_proof=False)
|
||||
cfrag = pre.reencrypt(kfrag, capsule)
|
||||
capsule.attach_cfrag(cfrag)
|
||||
|
||||
# Even thought we can successfully attach a CFrag, if the proof is lost
|
||||
# (for example, it is chopped off a serialized CFrag or similar), then decrypt
|
||||
# will still fail.
|
||||
cfrag.proof = None
|
||||
|
||||
with pytest.raises(cfrag.NoProofProvided):
|
||||
_cleartext = pre.decrypt(ciphertext, capsule, priv_key_bob,
|
||||
delegating_privkey.get_pubkey(),
|
||||
signing_privkey.get_pubkey())
|
||||
delegating_privkey.get_pubkey(),
|
||||
signing_privkey.get_pubkey())
|
||||
|
||||
|
||||
@pytest.mark.parametrize("N, M", parameters)
|
||||
|
@ -205,6 +220,11 @@ def test_m_of_n(N, M, alices_keys, bobs_keys):
|
|||
priv_key_bob, pub_key_bob = bobs_keys
|
||||
|
||||
sym_key, capsule = pre._encapsulate(delegating_privkey.get_pubkey().point_key)
|
||||
|
||||
capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
|
||||
encrypting=pub_key_bob,
|
||||
verifying=signing_privkey.get_pubkey())
|
||||
|
||||
kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, M, N)
|
||||
|
||||
for kfrag in kfrags:
|
||||
|
@ -222,5 +242,6 @@ def test_m_of_n(N, M, alices_keys, bobs_keys):
|
|||
delegating_privkey.get_pubkey(), signing_privkey.get_pubkey(), pub_key_bob,
|
||||
)
|
||||
|
||||
sym_key_from_capsule = pre._open_capsule(capsule, priv_key_bob, delegating_privkey.get_pubkey(), signing_privkey.get_pubkey())
|
||||
sym_key_from_capsule = pre._open_capsule(capsule, priv_key_bob, delegating_privkey.get_pubkey(),
|
||||
signing_privkey.get_pubkey())
|
||||
assert sym_key == sym_key_from_capsule
|
||||
|
|
|
@ -27,6 +27,10 @@ def test_simple_api(alices_keys, N, M, curve=default_curve()):
|
|||
plain_data = b'peace at dawn'
|
||||
ciphertext, capsule = pre.encrypt(delegating_privkey.get_pubkey(), plain_data, params=params)
|
||||
|
||||
capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
|
||||
encrypting=decrypting_key.get_pubkey(),
|
||||
verifying=signing_privkey.get_pubkey())
|
||||
|
||||
cleartext = pre.decrypt(ciphertext, capsule, delegating_privkey, params=params)
|
||||
assert cleartext == plain_data
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ def prove_cfrag_correctness(cfrag: "CapsuleFrag",
|
|||
|
||||
# Check correctness of original ciphertext (check nº 2) at the end
|
||||
# to avoid timing oracles
|
||||
if not capsule.verify(params):
|
||||
if not capsule.verify():
|
||||
raise capsule.NotValid("Capsule verification failed.")
|
||||
|
||||
|
||||
|
|
|
@ -225,6 +225,9 @@ class CapsuleFrag(object):
|
|||
signing_pubkey: UmbralPublicKey,
|
||||
encrypting_pubkey: UmbralPublicKey,
|
||||
params: UmbralParameters = None):
|
||||
if not all((delegating_pubkey, signing_pubkey, encrypting_pubkey)):
|
||||
raise TypeError("Need all three keys to verify correctness.")
|
||||
|
||||
pubkey_a_point = delegating_pubkey.point_key
|
||||
pubkey_b_point = encrypting_pubkey.point_key
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from cryptography.hazmat.backends.openssl import backend
|
|||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
|
||||
from umbral._pre import prove_cfrag_correctness
|
||||
from umbral._pre import prove_cfrag_correctness, assess_cfrag_correctness
|
||||
from umbral.curvebn import CurveBN
|
||||
from umbral.config import default_params, default_curve
|
||||
from umbral.dem import UmbralDEM
|
||||
|
@ -37,7 +37,13 @@ class Capsule(object):
|
|||
bn_sig=None,
|
||||
point_e_prime=None,
|
||||
point_v_prime=None,
|
||||
point_noninteractive=None):
|
||||
point_noninteractive=None,
|
||||
delegating_pubkey: UmbralPublicKey = None,
|
||||
encrypting_pubkey: UmbralPublicKey = None,
|
||||
verifying_pubkey: UmbralPublicKey = None,
|
||||
params: UmbralParameters = None):
|
||||
|
||||
self._umbral_params = params if params is not None else default_params()
|
||||
|
||||
if isinstance(point_e, Point):
|
||||
if not isinstance(point_v, Point) or not isinstance(bn_sig, CurveBN):
|
||||
|
@ -50,6 +56,10 @@ class Capsule(object):
|
|||
"Need proper Points and/or CurveBNs to make a Capsule. Pass either Alice's data or Bob's. " \
|
||||
"Passing both is also fine.")
|
||||
|
||||
self._cfrag_correctness_keys = {"delegating": delegating_pubkey,
|
||||
"encrypting": encrypting_pubkey,
|
||||
"verifying": verifying_pubkey}
|
||||
|
||||
self._point_e = point_e
|
||||
self._point_v = point_v
|
||||
self._bn_sig = bn_sig
|
||||
|
@ -108,6 +118,31 @@ class Capsule(object):
|
|||
components = splitter(capsule_bytes)
|
||||
return cls(*components)
|
||||
|
||||
def _set_cfrag_correctness_key(self, key_type, key: UmbralPublicKey):
|
||||
current_key = self._cfrag_correctness_keys[key_type]
|
||||
|
||||
if current_key is None:
|
||||
if key is None:
|
||||
raise TypeError("The Delegating Key is not set and you didn't pass one.")
|
||||
else:
|
||||
self._cfrag_correctness_keys[key_type] = key
|
||||
return True
|
||||
elif key in (None, self._cfrag_correctness_keys[key_type]):
|
||||
return False
|
||||
else:
|
||||
raise ValueError("The Delegating Key is already set; you can't set it again.")
|
||||
|
||||
def set_correctness_keys(self,
|
||||
delegating: UmbralPublicKey = None,
|
||||
encrypting: UmbralPublicKey = None,
|
||||
verifying: UmbralPublicKey = None
|
||||
):
|
||||
delegating_key_details = self._set_cfrag_correctness_key("delegating", delegating)
|
||||
encrypting_key_details = self._set_cfrag_correctness_key("encrypting", encrypting)
|
||||
verifying_key_details = self._set_cfrag_correctness_key("verifying", verifying)
|
||||
|
||||
return delegating_key_details, encrypting_key_details, verifying_key_details
|
||||
|
||||
def _original_to_bytes(self) -> bytes:
|
||||
return bytes().join(c.to_bytes() for c in self.original_components())
|
||||
|
||||
|
@ -120,19 +155,27 @@ class Capsule(object):
|
|||
bytes_representation += bytes().join(c.to_bytes() for c in self.activated_components())
|
||||
return bytes_representation
|
||||
|
||||
def verify(self, params: UmbralParameters = None) -> bool:
|
||||
params = params if params is not None else default_params()
|
||||
def verify(self) -> bool:
|
||||
|
||||
e = self._point_e
|
||||
v = self._point_v
|
||||
s = self._bn_sig
|
||||
h = CurveBN.hash(e, v, params=params)
|
||||
h = CurveBN.hash(e, v, params=self._umbral_params)
|
||||
|
||||
return s * params.g == v + (h * e)
|
||||
return s * self._umbral_params.g == v + (h * e)
|
||||
|
||||
def attach_cfrag(self, cfrag: CapsuleFrag) -> None:
|
||||
self.verify_cfrag(cfrag)
|
||||
self._attached_cfrags.append(cfrag)
|
||||
|
||||
def verify_cfrag(self, cfrag):
|
||||
return cfrag.verify_correctness(self,
|
||||
self._cfrag_correctness_keys["delegating"],
|
||||
self._cfrag_correctness_keys["encrypting"],
|
||||
self._cfrag_correctness_keys["verifying"],
|
||||
self._umbral_params
|
||||
)
|
||||
|
||||
def original_components(self) -> Tuple[Point, Point, CurveBN]:
|
||||
return self._point_e, self._point_v, self._bn_sig
|
||||
|
||||
|
@ -140,12 +183,9 @@ class Capsule(object):
|
|||
return self._point_e_prime, self._point_v_prime, self._point_noninteractive
|
||||
|
||||
def _reconstruct_shamirs_secret(self,
|
||||
priv_b: Union[UmbralPrivateKey, CurveBN],
|
||||
params: UmbralParameters = None) -> None:
|
||||
|
||||
params = params if params is not None else default_params()
|
||||
|
||||
g = params.g
|
||||
priv_b: Union[UmbralPrivateKey, CurveBN]
|
||||
) -> None:
|
||||
g = self._umbral_params.g
|
||||
|
||||
if isinstance(priv_b, UmbralPrivateKey):
|
||||
pub_b = priv_b.get_pubkey()
|
||||
|
@ -167,9 +207,9 @@ class Capsule(object):
|
|||
hashed_dh_tuple = blake2b.finalize()
|
||||
|
||||
if len(self._attached_cfrags) > 1:
|
||||
xs = [CurveBN.hash(cfrag._kfrag_id, hashed_dh_tuple, params=params)
|
||||
xs = [CurveBN.hash(cfrag._kfrag_id, hashed_dh_tuple, params=self._umbral_params)
|
||||
for cfrag in self._attached_cfrags]
|
||||
x_0 = CurveBN.hash(id_0, hashed_dh_tuple, params=params)
|
||||
x_0 = CurveBN.hash(id_0, hashed_dh_tuple, params=self._umbral_params)
|
||||
lambda_0 = lambda_coeff(x_0, xs)
|
||||
e = lambda_0 * cfrag_0._point_e1
|
||||
v = lambda_0 * cfrag_0._point_v1
|
||||
|
@ -178,7 +218,7 @@ class Capsule(object):
|
|||
if (ni, xcoord) != (cfrag._point_noninteractive, cfrag._point_xcoord):
|
||||
raise ValueError("Attached CFrags are not pairwise consistent")
|
||||
|
||||
x_i = CurveBN.hash(cfrag._kfrag_id, hashed_dh_tuple, params=params)
|
||||
x_i = CurveBN.hash(cfrag._kfrag_id, hashed_dh_tuple, params=self._umbral_params)
|
||||
lambda_i = lambda_coeff(x_i, xs)
|
||||
e = e + (lambda_i * cfrag._point_e1)
|
||||
v = v + (lambda_i * cfrag._point_v1)
|
||||
|
@ -230,7 +270,7 @@ def split_rekey(privkey_a_bn: Union[UmbralPrivateKey, CurveBN],
|
|||
params: UmbralParameters = None) -> List[KFrag]:
|
||||
"""
|
||||
Creates a re-encryption key from Alice to Bob and splits it in KFrags,
|
||||
using Shamir's Secret Sharing. Requires a threshold number of KFrags
|
||||
using Shamir's Secret Sharing. Requires a threshold number of KFrags
|
||||
out of N to guarantee correctness of re-encryption.
|
||||
|
||||
Returns a list of KFrags.
|
||||
|
@ -262,7 +302,7 @@ def split_rekey(privkey_a_bn: Union[UmbralPrivateKey, CurveBN],
|
|||
|
||||
# 'xcoord' stands for 'X coordinate'.
|
||||
# This point is used as an ephemeral public key in a DH key exchange,
|
||||
# and the resulting shared secret 'dh_xcoord' contributes to prevent
|
||||
# and the resulting shared secret 'dh_xcoord' contributes to prevent
|
||||
# reconstruction of the re-encryption key without Bob's intervention
|
||||
priv_xcoord = CurveBN.gen_rand(params.curve)
|
||||
xcoord = priv_xcoord * g
|
||||
|
@ -304,7 +344,7 @@ def reencrypt(kfrag: KFrag, capsule: Capsule, params: UmbralParameters = None,
|
|||
if params is None:
|
||||
params = default_params()
|
||||
|
||||
if not capsule.verify(params):
|
||||
if not capsule.verify():
|
||||
raise capsule.NotValid
|
||||
|
||||
rk = kfrag._bn_key
|
||||
|
@ -342,7 +382,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_e=pub_r, point_v=pub_u, bn_sig=s)
|
||||
return key, Capsule(point_e=pub_r, point_v=pub_u, bn_sig=s, params=params)
|
||||
|
||||
|
||||
def _decapsulate_original(priv_key: CurveBN, capsule: Capsule, key_length=32,
|
||||
|
@ -353,7 +393,7 @@ def _decapsulate_original(priv_key: CurveBN, capsule: Capsule, key_length=32,
|
|||
shared_key = priv_key * (capsule._point_e + capsule._point_v)
|
||||
key = kdf(shared_key, key_length)
|
||||
|
||||
if not capsule.verify(params):
|
||||
if not capsule.verify():
|
||||
# Check correctness of original ciphertext
|
||||
# (check nº 2) at the end to avoid timing oracles
|
||||
raise capsule.NotValid("Capsule verification failed.")
|
||||
|
@ -439,7 +479,7 @@ def _open_capsule(capsule: Capsule,
|
|||
error_msg = "Decryption error: Some CFrags are not correct"
|
||||
raise UmbralCorrectnessError(error_msg, offending_cfrags)
|
||||
|
||||
capsule._reconstruct_shamirs_secret(priv_b, params=params)
|
||||
capsule._reconstruct_shamirs_secret(priv_b)
|
||||
|
||||
key = _decapsulate_reencrypted(bob_pubkey.point_key, priv_b, delegating_pubkey.point_key, capsule, params=params)
|
||||
return key
|
||||
|
|
Loading…
Reference in New Issue