Enforce CapsuleFrag verification before decryption

pull/267/head
Bogdan Opanchuk 2021-04-19 18:53:16 -07:00
parent 65d32fd63e
commit 84883b85da
13 changed files with 226 additions and 167 deletions

View File

@ -1,6 +1,6 @@
import random
from umbral import (
SecretKey, PublicKey, Signer, GenericError,
SecretKey, PublicKey, Signer, GenericError, CapsuleFrag,
encrypt, generate_kfrags, reencrypt, decrypt_original, decrypt_reencrypted)
# Generate an Umbral key pair
@ -86,15 +86,18 @@ assert len(cfrags) == 10
# Bob checks the capsule fragments
# --------------------------------
# Bob can verify that the capsule fragments are valid and really originate from Alice,
# If Bob received the capsule fragments in serialized form,
# he can verify that they are valid and really originate from Alice,
# using Alice's public keys.
assert all(cfrag.verify(capsule,
suspicious_cfrags = [CapsuleFrag.from_bytes(bytes(cfrag)) for cfrag in cfrags]
cfrags = [cfrag.verify(capsule,
verifying_pk=alices_verifying_key,
delegating_pk=alices_public_key,
receiving_pk=bobs_public_key,
)
for cfrag in cfrags)
for cfrag in suspicious_cfrags]
# Bob opens the capsule
# ------------------------------------
@ -103,7 +106,7 @@ assert all(cfrag.verify(capsule,
bob_cleartext = decrypt_reencrypted(decrypting_sk=bobs_secret_key,
delegating_pk=alices_public_key,
capsule=bob_capsule,
cfrags=cfrags,
verified_cfrags=cfrags,
ciphertext=ciphertext)
print(bob_cleartext)
assert bob_cleartext == plaintext

View File

@ -56,7 +56,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"b'\\x1c\\xa0\\xa83\\x0cv\\x97\\x02d\\xe9\\xe9\\xc5_\\x9d5NRGRx\\xd4\\xc9\\x17%\\x9b\\xb4\\x05\\xd1\\xc2\\x1e\\x9d\\x0b\\xbf\\xb4g\\xf0n\\xfe\\x9eM\\x93\\xe0\\xbf#l\\xf9\\x033\\xb00\\xf5\\r\\xff\\xc9\\x133C\\xf0\\xa3\\xc0\\xd1e\\xdb~.E$%'\n"
"b'\\xfb\\xc3T\\xb2\\x89=\\x08X\\xb1<\\xd0G/\\xab\\x8c\\xac\\x7f\\xd4)\\xcbB\\xcb^\\x99;P\\x9c\\xbf\\xaaf\\x03\\xdd\\n\\x1f$\\x1b\\xfb\\x88\\xfa\\xcd\\xe2\\x11\\x8d\\xcf\\xe5\\x88\\xaf\\x00\\xfe\\xcb\\x9d\\xf83\\x17\\x9b\\xdd\\xba\\xab\\x8b\\x08\\xbe\\xb1M\\x80\\xf1<S#'\n"
]
}
],
@ -170,7 +170,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
@ -196,7 +196,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
@ -219,22 +219,27 @@
"metadata": {},
"source": [
"## Bob checks the capsule fragments\n",
"Bob can verify that the capsule fragments are valid and really originate from Alice, using Alice's public keys."
"If Bob received the capsule fragments in serialized form, he can verify that they are valid and really originate from Alice, using Alice's public keys."
]
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 10,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"assert all(cfrag.verify(capsule,\n",
"from umbral import CapsuleFrag\n",
"\n",
"suspicious_cfrags = [CapsuleFrag.from_bytes(bytes(cfrag)) for cfrag in cfrags]\n",
"\n",
"cfrags = [cfrag.verify(capsule,\n",
" verifying_pk=alices_verifying_key,\n",
" delegating_pk=alices_public_key,\n",
" receiving_pk=bobs_public_key)\n",
" for cfrag in cfrags)"
" receiving_pk=bobs_public_key,\n",
" )\n",
" for cfrag in suspicious_cfrags]"
]
},
{
@ -264,7 +269,7 @@
"bob_cleartext = decrypt_reencrypted(decrypting_sk=bobs_private_key,\n",
" delegating_pk=alices_public_key,\n",
" capsule=capsule,\n",
" cfrags=cfrags,\n",
" verified_cfrags=cfrags,\n",
" ciphertext=ciphertext)\n",
"\n",
"print(bob_cleartext)\n",

View File

@ -47,6 +47,9 @@ Intermediate objects
:special-members: __eq__, __hash__
:show-inheritance:
.. autoclass:: VerifiedCapsuleFrag()
:special-members: __eq__, __hash__
Encryption, re-encryption and decryption
----------------------------------------

View File

@ -173,17 +173,20 @@ Decryption
Bob checks the capsule fragments
--------------------------------
Bob can verify that the capsule fragments are valid and really originate from Alice,
If Bob received the capsule fragments in serialized form,
he can verify that they are valid and really originate from Alice,
using Alice's public keys.
.. doctest:: capsule_story
>>> all(cfrag.verify(capsule,
>>> from umbral import CapsuleFrag
>>> suspicious_cfrags = [CapsuleFrag.from_bytes(bytes(cfrag)) for cfrag in cfrags]
>>> cfrags = [cfrag.verify(capsule,
... verifying_pk=alices_verifying_key,
... delegating_pk=alices_public_key,
... receiving_pk=bobs_public_key)
... for cfrag in cfrags)
True
... receiving_pk=bobs_public_key,
... )
... for cfrag in suspicious_cfrags]
Bob opens the capsule
@ -196,7 +199,7 @@ Finally, Bob decrypts the re-encrypted ciphertext using his key.
>>> cleartext = decrypt_reencrypted(decrypting_sk=bobs_secret_key,
... delegating_pk=alices_public_key,
... capsule=capsule,
... cfrags=cfrags,
... verified_cfrags=cfrags,
... ciphertext=ciphertext)

View File

@ -77,7 +77,7 @@ def test_open_reencrypted(alices_keys, bobs_keys):
threshold=threshold,
num_kfrags=num_kfrags)
cfrags = [reencrypt(capsule, kfrag) for kfrag in kfrags]
cfrags = [reencrypt(capsule, kfrag).cfrag for kfrag in kfrags]
key_back = capsule.open_reencrypted(receiving_sk, delegating_pk, cfrags[:threshold])
assert key_back == key
@ -99,7 +99,7 @@ def test_open_reencrypted(alices_keys, bobs_keys):
receiving_pk=receiving_pk,
threshold=threshold,
num_kfrags=num_kfrags)
cfrags2 = [reencrypt(capsule, kfrag) for kfrag in kfrags2]
cfrags2 = [reencrypt(capsule, kfrag).cfrag for kfrag in kfrags2]
with pytest.raises(ValueError, match="CapsuleFrags are not pairwise consistent"):
capsule.open_reencrypted(receiving_sk, delegating_pk, [cfrags2[0]] + cfrags[:threshold-1])

View File

@ -1,14 +1,12 @@
from umbral import reencrypt, CapsuleFrag, PublicKey, Capsule
import pytest
from umbral import reencrypt, CapsuleFrag, PublicKey, Capsule, VerificationError
from umbral.curve_point import CurvePoint
def test_cfrag_serialization(alices_keys, bobs_keys, capsule, kfrags):
def test_cfrag_serialization(verification_keys, capsule, kfrags):
delegating_sk, signing_sk = alices_keys
_receiving_sk, receiving_pk = bobs_keys
verifying_pk = PublicKey.from_secret_key(signing_sk)
delegating_pk = PublicKey.from_secret_key(delegating_sk)
verifying_pk, delegating_pk, receiving_pk = verification_keys
metadata = b'This is an example of metadata for re-encryption request'
for kfrag in kfrags:
@ -16,24 +14,26 @@ def test_cfrag_serialization(alices_keys, bobs_keys, capsule, kfrags):
cfrag_bytes = bytes(cfrag)
new_cfrag = CapsuleFrag.from_bytes(cfrag_bytes)
assert new_cfrag == cfrag
assert new_cfrag.verify(capsule,
verified_cfrag = new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
metadata=metadata,
)
assert verified_cfrag == cfrag
# No metadata
assert not new_cfrag.verify(capsule,
with pytest.raises(VerificationError):
new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
)
# Wrong metadata
assert not new_cfrag.verify(capsule,
with pytest.raises(VerificationError):
new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
@ -41,7 +41,8 @@ def test_cfrag_serialization(alices_keys, bobs_keys, capsule, kfrags):
)
# Wrong delegating key
assert not new_cfrag.verify(capsule,
with pytest.raises(VerificationError):
new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=receiving_pk,
receiving_pk=receiving_pk,
@ -49,7 +50,8 @@ def test_cfrag_serialization(alices_keys, bobs_keys, capsule, kfrags):
)
# Wrong receiving key
assert not new_cfrag.verify(capsule,
with pytest.raises(VerificationError):
new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=delegating_pk,
@ -57,7 +59,8 @@ def test_cfrag_serialization(alices_keys, bobs_keys, capsule, kfrags):
)
# Wrong signing key
assert not new_cfrag.verify(capsule,
with pytest.raises(VerificationError):
new_cfrag.verify(capsule,
verifying_pk=receiving_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
@ -65,13 +68,9 @@ def test_cfrag_serialization(alices_keys, bobs_keys, capsule, kfrags):
)
def test_cfrag_serialization_no_metadata(alices_keys, bobs_keys, capsule, kfrags):
def test_cfrag_serialization_no_metadata(verification_keys, capsule, kfrags):
delegating_sk, signing_sk = alices_keys
_receiving_sk, receiving_pk = bobs_keys
verifying_pk = PublicKey.from_secret_key(signing_sk)
delegating_pk = PublicKey.from_secret_key(delegating_sk)
verifying_pk, delegating_pk, receiving_pk = verification_keys
for kfrag in kfrags:
@ -80,13 +79,15 @@ def test_cfrag_serialization_no_metadata(alices_keys, bobs_keys, capsule, kfrags
cfrag_bytes = bytes(cfrag)
new_cfrag = CapsuleFrag.from_bytes(cfrag_bytes)
assert new_cfrag.verify(capsule,
verified_cfrag = new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
)
assert verified_cfrag == cfrag
assert not new_cfrag.verify(capsule,
with pytest.raises(VerificationError):
new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
@ -94,55 +95,52 @@ def test_cfrag_serialization_no_metadata(alices_keys, bobs_keys, capsule, kfrags
)
def test_cfrag_with_wrong_capsule(alices_keys, bobs_keys,
kfrags, capsule_and_ciphertext, message):
def test_cfrag_with_wrong_capsule(verification_keys, kfrags, capsule_and_ciphertext, message):
capsule, ciphertext = capsule_and_ciphertext
delegating_sk, signing_sk = alices_keys
delegating_pk = PublicKey.from_secret_key(delegating_sk)
_receiving_sk, receiving_pk = bobs_keys
verifying_pk, delegating_pk, receiving_pk = verification_keys
capsule_alice1 = capsule
capsule_alice2, _unused_key2 = Capsule.from_public_key(delegating_pk)
metadata = b"some metadata"
cfrag = reencrypt(capsule_alice2, kfrags[0], metadata=metadata)
cfrag = CapsuleFrag.from_bytes(bytes(cfrag)) # de-verify
assert not cfrag.verify(capsule_alice1,
verifying_pk=PublicKey.from_secret_key(signing_sk),
with pytest.raises(VerificationError):
cfrag.verify(capsule_alice1,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
metadata=metadata,
)
def test_cfrag_with_wrong_data(kfrags, alices_keys, bobs_keys, capsule_and_ciphertext, message):
def test_cfrag_with_wrong_data(verification_keys, kfrags, capsule_and_ciphertext, message):
capsule, ciphertext = capsule_and_ciphertext
delegating_sk, signing_sk = alices_keys
delegating_pk = PublicKey.from_secret_key(delegating_sk)
_receiving_sk, receiving_pk = bobs_keys
verifying_pk, delegating_pk, receiving_pk = verification_keys
metadata = b"some metadata"
cfrag = reencrypt(capsule, kfrags[0], metadata=metadata)
# Let's put random garbage in one of the cfrags
cfrag = CapsuleFrag.from_bytes(bytes(cfrag)) # de-verify
cfrag.point_e1 = CurvePoint.random()
cfrag.point_v1 = CurvePoint.random()
assert not cfrag.verify(capsule,
verifying_pk=PublicKey.from_secret_key(signing_sk),
with pytest.raises(VerificationError):
cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
metadata=metadata,
)
def test_cfrag_is_hashable(capsule, kfrags):
def test_cfrag_is_hashable(verification_keys, capsule, kfrags):
verifying_pk, delegating_pk, receiving_pk = verification_keys
cfrag0 = reencrypt(capsule, kfrags[0], metadata=b'abcdef')
cfrag1 = reencrypt(capsule, kfrags[1], metadata=b'abcdef')
@ -150,10 +148,22 @@ def test_cfrag_is_hashable(capsule, kfrags):
assert hash(cfrag0) != hash(cfrag1)
new_cfrag = CapsuleFrag.from_bytes(bytes(cfrag0))
assert hash(new_cfrag) == hash(cfrag0)
assert hash(new_cfrag) != hash(cfrag0)
verified_cfrag = new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
metadata=b'abcdef')
assert hash(verified_cfrag) == hash(cfrag0)
def test_cfrag_str(capsule, kfrags):
cfrag0 = reencrypt(capsule, kfrags[0], metadata=b'abcdef')
s = str(cfrag0)
assert 'CapsuleFrag' in s
assert 'VerifiedCapsuleFrag' in s
s = str(CapsuleFrag.from_bytes(bytes(cfrag0)))
assert "VerifiedCapsuleFrag" not in s
assert "CapsuleFrag" in s

View File

@ -162,19 +162,19 @@ def _decrypt_reencrypted(umbral, receiving_sk_bytes, delegating_pk_bytes, verify
capsule = umbral.Capsule.from_bytes(bytes(capsule_bytes))
cfrags = [umbral.CapsuleFrag.from_bytes(cfrag_bytes) for cfrag_bytes in cfrags_bytes]
assert all(cfrag.verify(capsule,
verified_cfrags = [cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
metadata=metadata)
for cfrag in cfrags)
for cfrag in cfrags]
# Decryption by Bob
plaintext = umbral.decrypt_reencrypted(receiving_sk,
delegating_pk,
capsule,
cfrags,
ciphertext,
plaintext = umbral.decrypt_reencrypted(decrypting_sk=receiving_sk,
delegating_pk=delegating_pk,
capsule=capsule,
verified_cfrags=verified_cfrags,
ciphertext=ciphertext,
)
return plaintext

View File

@ -6,6 +6,7 @@ from umbral import (
Signer,
GenericError,
KeyFrag,
CapsuleFrag,
encrypt,
generate_kfrags,
decrypt_original,
@ -77,28 +78,14 @@ def test_simple_api(num_kfrags, threshold):
num_kfrags=num_kfrags)
# Bob requests re-encryption to some set of M ursulas
cfrags = list()
for kfrag in kfrags[:threshold]:
# Re-encryption by an Ursula
cfrag = reencrypt(capsule, kfrag)
# Bob collects the result
cfrags.append(cfrag)
# Bob checks that the received cfrags are valid
assert all(cfrag.verify(capsule=capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,
) for cfrag in cfrags)
cfrags = [reencrypt(capsule, kfrag) for kfrag in kfrags]
# Decryption by Bob
plaintext_reenc = decrypt_reencrypted(receiving_sk,
delegating_pk,
capsule,
cfrags[:threshold],
ciphertext,
plaintext_reenc = decrypt_reencrypted(decrypting_sk=receiving_sk,
delegating_pk=delegating_pk,
capsule=capsule,
verified_cfrags=cfrags[:threshold],
ciphertext=ciphertext,
)
assert plaintext_reenc == plaintext
@ -108,3 +95,19 @@ def test_reencrypt_unverified_kfrag(capsule, kfrags):
kfrag = KeyFrag.from_bytes(bytes(kfrags[0]))
with pytest.raises(TypeError):
reencrypt(capsule, kfrag)
def test_decrypt_unverified_cfrag(verification_keys, bobs_keys, capsule_and_ciphertext, kfrags):
verifying_pk, delegating_pk, receiving_pk = verification_keys
receiving_sk, _receiving_pk = bobs_keys
capsule, ciphertext = capsule_and_ciphertext
cfrags = [reencrypt(capsule, kfrag) for kfrag in kfrags]
cfrags[0] = CapsuleFrag.from_bytes(bytes(cfrags[0]))
with pytest.raises(TypeError):
plaintext_reenc = decrypt_reencrypted(decrypting_sk=receiving_sk,
delegating_pk=delegating_pk,
capsule=capsule,
verified_cfrags=cfrags,
ciphertext=ciphertext,
)

View File

@ -154,12 +154,12 @@ def test_cfrags():
delegating_pk=delegating_pk,
receiving_pk=receiving_pk)
new_cfrag = reencrypt(capsule, verified_kfrag, metadata=metadata)
new_cfrag = reencrypt(capsule, verified_kfrag, metadata=metadata).cfrag
assert new_cfrag.point_e1 == cfrag.point_e1
assert new_cfrag.point_v1 == cfrag.point_v1
assert new_cfrag.kfrag_id == cfrag.kfrag_id
assert new_cfrag.precursor == cfrag.precursor
assert new_cfrag.verify(capsule,
new_cfrag.verify(capsule,
verifying_pk=verifying_pk,
delegating_pk=delegating_pk,
receiving_pk=receiving_pk,

View File

@ -3,7 +3,7 @@ from .__about__ import (
)
from .capsule import Capsule
from .capsule_frag import CapsuleFrag
from .capsule_frag import CapsuleFrag, VerifiedCapsuleFrag
from .errors import GenericError, VerificationError
from .key_frag import KeyFrag, VerifiedKeyFrag, generate_kfrags
from .keys import SecretKey, PublicKey, SecretKeyFactory
@ -28,6 +28,7 @@ __all__ = [
"KeyFrag",
"VerifiedKeyFrag",
"CapsuleFrag",
"VerifiedCapsuleFrag",
"GenericError",
"VerificationError",
"encrypt",

View File

@ -3,6 +3,7 @@ from typing import Sequence, Optional, Tuple
from .capsule import Capsule
from .curve_point import CurvePoint
from .curve_scalar import CurveScalar
from .errors import VerificationError
from .hashing import Hash, hash_to_cfrag_verification, kfrag_signature_message
from .keys import PublicKey, SecretKey
from .key_frag import KeyFrag, KeyFragID
@ -163,7 +164,7 @@ class CapsuleFrag(Serializable):
delegating_pk: PublicKey,
receiving_pk: PublicKey,
metadata: Optional[bytes] = None,
) -> bool:
) -> 'VerifiedCapsuleFrag':
"""
Verifies the validity of this fragment.
@ -203,7 +204,7 @@ class CapsuleFrag(Serializable):
maybe_receiving_pk=receiving_pk)
if not self.proof.kfrag_signature.verify(verifying_pk, kfrag_message):
return False
raise VerificationError("Invalid KeyFrag signature")
z = self.proof.signature
@ -215,6 +216,30 @@ class CapsuleFrag(Serializable):
correct_reencryption_of_v = v * z == v2 + v1 * h
correct_rk_commitment = u * z == u2 + u1 * h
return (correct_reencryption_of_e
and correct_reencryption_of_v
and correct_rk_commitment)
if not (correct_reencryption_of_e and correct_reencryption_of_v and correct_rk_commitment):
raise VerificationError("Failed to verify reencryption proof")
return VerifiedCapsuleFrag(self)
class VerifiedCapsuleFrag:
"""
Verified capsule frag, good for decryption.
Can be cast to ``bytes``, but cannot be deserialized from bytes directly.
It can only be obtained from :py:meth:`CapsuleFrag.verify`.
"""
def __init__(self, cfrag: CapsuleFrag):
self.cfrag = cfrag
def __bytes__(self):
return bytes(self.cfrag)
def __eq__(self, other):
return self.cfrag == other.cfrag
def __hash__(self):
return hash((self.__class__, bytes(self)))
def __str__(self):
return f"{self.__class__.__name__}:{bytes(self).hex()[:16]}"

View File

@ -1,7 +1,7 @@
from typing import Tuple, Optional, Sequence
from .capsule import Capsule
from .capsule_frag import CapsuleFrag
from .capsule_frag import VerifiedCapsuleFrag, CapsuleFrag
from .dem import DEM
from .keys import PublicKey, SecretKey
from .key_frag import VerifiedKeyFrag, KeyFrag
@ -33,7 +33,7 @@ def decrypt_original(sk: SecretKey, capsule: Capsule, ciphertext: bytes) -> byte
def reencrypt(capsule: Capsule,
kfrag: VerifiedKeyFrag,
metadata: Optional[bytes] = None
) -> CapsuleFrag:
) -> VerifiedCapsuleFrag:
"""
Creates a capsule fragment using the given key fragment.
Capsule fragments can later be used to decrypt the ciphertext.
@ -46,19 +46,25 @@ def reencrypt(capsule: Capsule,
if isinstance(kfrag, KeyFrag) and not isinstance(kfrag, VerifiedKeyFrag):
raise TypeError("KeyFrag must be verified before reencryption")
return CapsuleFrag.reencrypted(capsule, kfrag.kfrag, metadata)
return VerifiedCapsuleFrag(CapsuleFrag.reencrypted(capsule, kfrag.kfrag, metadata))
def decrypt_reencrypted(decrypting_sk: SecretKey,
delegating_pk: PublicKey,
capsule: Capsule,
cfrags: Sequence[CapsuleFrag],
verified_cfrags: Sequence[VerifiedCapsuleFrag],
ciphertext: bytes,
) -> bytes:
"""
Decrypts the ciphertext using the original capsule and the reencrypted capsule fragments.
"""
# We could let duck typing do its work,
# but it's better to make a common error more understandable.
for cfrag in verified_cfrags:
if isinstance(cfrag, CapsuleFrag) and not isinstance(cfrag, VerifiedCapsuleFrag):
raise TypeError("All CapsuleFrags must be verified before decryption")
cfrags = [vcfrag.cfrag for vcfrag in verified_cfrags]
key_seed = capsule.open_reencrypted(decrypting_sk, delegating_pk, cfrags)
dem = DEM(bytes(key_seed))
return dem.decrypt(ciphertext, authenticated_data=bytes(capsule))

View File

@ -1,7 +1,7 @@
import json
import os
from umbral import SecretKey, PublicKey, Signer, KeyFrag, encrypt, generate_kfrags, reencrypt
from umbral import SecretKey, PublicKey, Signer, KeyFrag, CapsuleFrag, encrypt, generate_kfrags, reencrypt
from umbral.curve_scalar import CurveScalar
from umbral.curve_point import CurvePoint
from umbral.hashing import Hash, unsafe_hash_to_point
@ -59,7 +59,7 @@ plain_data = b'peace at dawn'
capsule, ciphertext = encrypt(delegating_pk, plain_data)
cfrag = reencrypt(capsule, kfrags[0])
cfrag = CapsuleFrag.from_bytes(bytes(reencrypt(capsule, kfrags[0])))
points = [capsule.point_e, cfrag.point_e1, cfrag.proof.point_e2,
capsule.point_v, cfrag.point_v1, cfrag.proof.point_v2,
cfrag.proof.kfrag_commitment, cfrag.proof.kfrag_pok]