Skip to content

Commit

Permalink
Incorporate latest changes to use session key objects from `nucypher-…
Browse files Browse the repository at this point in the history
…core` that use Curve 25519, ferveo module in `nucypher-core`, and changes to CoordinatorAgent.
  • Loading branch information
derekpierre committed Jun 6, 2023
1 parent e3efee1 commit c19046f
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 80 deletions.
2 changes: 1 addition & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ python_version = "3"

[packages]
nucypher = {git = "https://github.com/nucypher/nucypher.git", ref = "development"}
nucypher-core = ">=0.8.0" # should be the same as nucypher
nucypher-core = {git = "https://github.com/nucypher/nucypher.git", ref = "main"} # should be the same as nucypher
flask-cors = "*"

[dev-packages]
Expand Down
5 changes: 2 additions & 3 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ ethpm-types==0.5.1 ; python_version >= '3.8' and python_version < '4'
evm-trace==0.1.0a20 ; python_version >= '3.8' and python_version < '4'
exceptiongroup==1.1.1 ; python_version >= '3.7'
executing==1.2.0
ferveo==0.1.13 ; python_version >= '3.7'
filelock==3.12.0 ; python_version >= '3.7'
flask==2.2.5 ; python_version >= '3.7'
frozenlist==1.3.3 ; python_version >= '3.7'
Expand Down Expand Up @@ -87,8 +86,8 @@ msgspec==0.15.1 ; python_version >= '3.8'
multidict==5.2.0 ; python_version >= '3.6'
mypy-extensions==0.4.4 ; python_version >= '2.7'
nodeenv==1.8.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'
nucypher @ git+https://github.com/nucypher/nucypher.git@9305d4d76c22dee587cbc20d443c43b757e41485
nucypher-core==0.8.0
nucypher @ git+https://github.com/derekpierre/nucypher.git@018b78b53fc013412c6fc8088bab05d8836f2dd2
nucypher-core @ git+https://github.com/derekpierre/nucypher-core.git@253dfde60e6106ceeda696b86cb2f605ce3cd557#subdirectory=nucypher-core-python
numpy==1.24.3 ; python_version >= '3.8'
packaging==23.1 ; python_version >= '3.7'
pandas==1.5.3 ; python_version >= '3.8'
Expand Down
5 changes: 2 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ eth-rlp==0.3.0 ; python_version >= '3.7' and python_version < '4'
eth-tester==0.9.0b1 ; python_version < '4' and python_full_version >= '3.6.8'
eth-typing==3.3.0 ; python_version < '4' and python_full_version >= '3.7.2'
eth-utils==2.1.0 ; python_version >= '3.7' and python_version < '4'
ferveo==0.1.13 ; python_version >= '3.7'
flask==2.2.5 ; python_version >= '3.7'
flask-cors==3.0.10
frozenlist==1.3.3 ; python_version >= '3.7'
Expand All @@ -57,8 +56,8 @@ msgpack==1.0.5
msgpack-python==0.5.6
multidict==5.2.0 ; python_version >= '3.6'
mypy-extensions==0.4.4 ; python_version >= '2.7'
nucypher @ git+https://github.com/nucypher/nucypher.git@9305d4d76c22dee587cbc20d443c43b757e41485
nucypher-core==0.8.0
nucypher @ git+https://github.com/derekpierre/nucypher.git@018b78b53fc013412c6fc8088bab05d8836f2dd2
nucypher-core @ git+https://github.com/derekpierre/nucypher-core.git@253dfde60e6106ceeda696b86cb2f605ce3cd557#subdirectory=nucypher-core-python
packaging==23.1 ; python_version >= '3.7'
parsimonious==0.9.0
pendulum==3.0.0a1 ; python_version >= '3.7' and python_version < '4.0'
Expand Down
25 changes: 15 additions & 10 deletions tests/cbd/test_cbd_specifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import pytest
from eth_utils import to_checksum_address
from nucypher.crypto.ferveo.dkg import FerveoVariant
from nucypher_core import Conditions, ThresholdDecryptionRequest
from nucypher_core.umbral import SecretKey
from nucypher_core import Conditions, SessionStaticSecret, ThresholdDecryptionRequest

from porter.fields.cbd import (
EncryptedThresholdDecryptionRequestField,
Expand All @@ -26,21 +25,24 @@ def test_cbd_decrypt(
decryption_request = ThresholdDecryptionRequest(
ritual_id=ritual_id,
variant=int(FerveoVariant.SIMPLE.value),
ciphertext=bytes(ciphertext),
ciphertext=ciphertext,
conditions=Conditions(json.dumps(conditions)),
)

response_sk = SecretKey.random()
requester_secret_key = SessionStaticSecret.random()

encrypted_request_field = EncryptedThresholdDecryptionRequestField()
encrypted_decryption_requests = {}
for ursula in cohort:
request_encrypting_key = (
ursula_decryption_request_static_key = (
ursula.threshold_request_power.get_pubkey_from_ritual_id(ritual_id)
)
shared_secret = requester_secret_key.derive_shared_secret(
ursula_decryption_request_static_key
)
encrypted_decryption_request = decryption_request.encrypt(
request_encrypting_key=request_encrypting_key,
response_encrypting_key=response_sk.public_key(),
shared_secret=shared_secret,
requester_public_key=requester_secret_key.public_key(),
)
encrypted_decryption_requests[
ursula.checksum_address
Expand Down Expand Up @@ -112,12 +114,15 @@ def test_cbd_decrypt(
# actual outcomes
encrypted_decryption_requests = {}
for ursula in cohort:
request_encrypting_key = (
ursula_decryption_request_static_key = (
ursula.threshold_request_power.get_pubkey_from_ritual_id(ritual_id)
)
shared_secret = requester_secret_key.derive_shared_secret(
ursula_decryption_request_static_key
)
encrypted_decryption_request = decryption_request.encrypt(
request_encrypting_key=request_encrypting_key,
response_encrypting_key=response_sk.public_key(),
shared_secret=shared_secret,
requester_public_key=requester_secret_key.public_key(),
)
encrypted_decryption_requests[
ursula.checksum_address
Expand Down
38 changes: 23 additions & 15 deletions tests/cbd/test_porter_cbd_python_interface.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import json

from ferveo_py import (
from nucypher.crypto.ferveo.dkg import FerveoVariant
from nucypher_core import Conditions, SessionStaticSecret, ThresholdDecryptionRequest
from nucypher_core.ferveo import (
Ciphertext,
DecryptionShareSimple,
combine_decryption_shares_simple,
decrypt_with_shared_secret,
)
from nucypher.crypto.ferveo.dkg import FerveoVariant
from nucypher_core import Conditions, ThresholdDecryptionRequest
from nucypher_core.umbral import SecretKey


def test_cbd_decryption(porter, dkg_setup, dkg_encrypted_data):
Expand All @@ -22,19 +21,24 @@ def test_cbd_decryption(porter, dkg_setup, dkg_encrypted_data):
conditions=Conditions(json.dumps(conditions)),
)

response_sk = SecretKey.random()
requester_secret_key = SessionStaticSecret.random()

encrypted_decryption_requests = {}
shared_secrets = {}
for ursula in cohort:
request_encrypting_key = (
ursula_decryption_request_static_key = (
ursula.threshold_request_power.get_pubkey_from_ritual_id(ritual_id)
)
shared_secret = requester_secret_key.derive_shared_secret(
ursula_decryption_request_static_key
)
encrypted_decryption_requests[
ursula.checksum_address
] = decryption_request.encrypt(
request_encrypting_key=request_encrypting_key,
response_encrypting_key=response_sk.public_key(),
shared_secret=shared_secret,
requester_public_key=requester_secret_key.public_key(),
)
shared_secrets[ursula.checksum_address] = shared_secret

cbd_outcome = porter.cbd_decrypt(
threshold=threshold, encrypted_decryption_requests=encrypted_decryption_requests
Expand All @@ -54,33 +58,37 @@ def test_cbd_decryption(porter, dkg_setup, dkg_encrypted_data):
encrypted_decryption_response,
) in cbd_outcome.encrypted_decryption_responses.items():
assert ursula_address in cohort_addresses
decryption_response = encrypted_decryption_response.decrypt(sk=response_sk)
shared_secret = shared_secrets[ursula_address]
decryption_response = encrypted_decryption_response.decrypt(
shared_secret=shared_secret
)
decryption_share = DecryptionShareSimple.from_bytes(
decryption_response.decryption_share
)
decryption_shares.append(decryption_share)

shared_secret = combine_decryption_shares_simple(decryption_shares)
combined_shares = combine_decryption_shares_simple(decryption_shares)
conditions = json.dumps(conditions).encode() # aad
cleartext = decrypt_with_shared_secret(
Ciphertext.from_bytes(ciphertext),
ciphertext,
conditions, # aad
shared_secret,
combined_shares,
params, # dkg params
)
assert bytes(cleartext) == expected_plaintext

#
# errors - invalid encrypting key used for request
#
random_public_key = SecretKey.random().public_key()
random_public_key = SessionStaticSecret.random().public_key()
shared_secret = requester_secret_key.derive_shared_secret(random_public_key)
encrypted_decryption_requests = {}
for ursula in cohort:
encrypted_decryption_requests[
ursula.checksum_address
] = decryption_request.encrypt(
request_encrypting_key=random_public_key,
response_encrypting_key=response_sk.public_key(),
shared_secret=shared_secret,
requester_public_key=requester_secret_key.public_key(),
)

cbd_outcome = porter.cbd_decrypt(
Expand Down
54 changes: 33 additions & 21 deletions tests/cbd/test_porter_cbd_web_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
from base64 import b64decode

from eth_utils import to_checksum_address
from ferveo_py import (
Ciphertext,
DecryptionShareSimple,
combine_decryption_shares_simple,
decrypt_with_shared_secret,
)
from nucypher.crypto.ferveo.dkg import FerveoVariant
from nucypher_core import (
Conditions,
EncryptedThresholdDecryptionResponse,
SessionStaticSecret,
ThresholdDecryptionRequest,
)
from nucypher_core.umbral import SecretKey
from nucypher_core.ferveo import (
Ciphertext,
DecryptionShareSimple,
combine_decryption_shares_simple,
decrypt_with_shared_secret,
)

from porter.fields.cbd import EncryptedThresholdDecryptionRequestField

Expand All @@ -38,27 +38,32 @@ def test_cbd_decrypt(
decryption_request = ThresholdDecryptionRequest(
ritual_id=ritual_id,
variant=int(FerveoVariant.SIMPLE.value),
ciphertext=bytes(ciphertext),
ciphertext=ciphertext,
conditions=Conditions(json.dumps(conditions)),
)

response_sk = SecretKey.random()
requester_secret_key = SessionStaticSecret.random()

encrypted_request_field = EncryptedThresholdDecryptionRequestField()
encrypted_decryption_requests = {}
shared_secrets = {}
for ursula in cohort:
request_encrypting_key = (
ursula_decryption_request_static_key = (
ursula.threshold_request_power.get_pubkey_from_ritual_id(ritual_id)
)
shared_secret = requester_secret_key.derive_shared_secret(
ursula_decryption_request_static_key
)
encrypted_decryption_request = decryption_request.encrypt(
request_encrypting_key=request_encrypting_key,
response_encrypting_key=response_sk.public_key(),
shared_secret=shared_secret,
requester_public_key=requester_secret_key.public_key(),
)
encrypted_decryption_requests[
ursula.checksum_address
] = encrypted_request_field._serialize(
value=encrypted_decryption_request, attr=None, obj=None
)
shared_secrets[ursula.checksum_address] = shared_secret

request_data = {
"threshold": threshold,
Expand Down Expand Up @@ -98,18 +103,21 @@ def test_cbd_decrypt(
encrypted_decryption_response = EncryptedThresholdDecryptionResponse.from_bytes(
b64decode(response_bytes)
)
decryption_response = encrypted_decryption_response.decrypt(sk=response_sk)
shared_secret = shared_secrets[ursula_address]
decryption_response = encrypted_decryption_response.decrypt(
shared_secret=shared_secret
)
decryption_share = DecryptionShareSimple.from_bytes(
decryption_response.decryption_share
)
decryption_shares.append(decryption_share)

shared_secret = combine_decryption_shares_simple(decryption_shares)
combined_shares = combine_decryption_shares_simple(decryption_shares)
json_conditions = json.dumps(conditions).encode() # aad
cleartext = decrypt_with_shared_secret(
Ciphertext.from_bytes(ciphertext),
ciphertext,
json_conditions, # aad
shared_secret,
combined_shares,
params, # dkg params
)
assert bytes(cleartext) == expected_plaintext
Expand All @@ -128,15 +136,19 @@ def test_cbd_decrypt(
request = ThresholdDecryptionRequest(
ritual_id=999, # rando invalid ritual id
variant=int(FerveoVariant.SIMPLE.value),
ciphertext=bytes(ciphertext),
ciphertext=ciphertext,
conditions=Conditions(json.dumps(conditions)),
)

ursula_decryption_request_static_key = cohort[
i
].threshold_request_power.get_pubkey_from_ritual_id(ritual_id=ritual_id)
shared_secret = requester_secret_key.derive_shared_secret(
ursula_decryption_request_static_key
)
encrypted_decryption_request = request.encrypt(
request_encrypting_key=cohort[
i
].threshold_request_power.get_pubkey_from_ritual_id(ritual_id=ritual_id),
response_encrypting_key=response_sk.public_key(),
shared_secret=shared_secret,
requester_public_key=requester_secret_key.public_key(),
)
data = encrypted_request_field._serialize(
value=encrypted_decryption_request, attr=None, obj=None
Expand Down
19 changes: 10 additions & 9 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from click.testing import CliRunner
from eth_typing import ChecksumAddress
from eth_utils import to_checksum_address
from ferveo_py import DkgPublicKey, DkgPublicParameters, Validator
from nucypher.blockchain.economics import Economics, EconomicsFactory
from nucypher.blockchain.eth.actors import Operator
from nucypher.blockchain.eth.agents import (
Expand All @@ -19,15 +18,17 @@
from nucypher.characters.lawful import Enrico, Ursula
from nucypher.config.constants import TEMPORARY_DOMAIN
from nucypher.crypto.ferveo import dkg
from nucypher.crypto.powers import (
DecryptingPower,
RitualisticPower,
ThresholdRequestDecryptingPower,
)
from nucypher.crypto.powers import DecryptingPower, RitualisticPower
from nucypher.network.nodes import Learner, Teacher
from nucypher.policy.conditions.types import LingoList
from nucypher.utilities.logging import GlobalLoggerSettings
from nucypher_core import HRAC, Address, TreasureMap
from nucypher_core.ferveo import (
Ciphertext,
DkgPublicKey,
DkgPublicParameters,
Validator,
)

from porter.emitters import WebEmitter
from porter.main import Porter
Expand Down Expand Up @@ -303,7 +304,7 @@ def dkg_setup(
provider=ursula.checksum_address,
aggregated=True,
transcript=bytes(transcripts[i]),
requestEncryptingKey=ursula.threshold_request_power.get_pubkey_from_ritual_id(
decryption_request_static_key=ursula.threshold_request_power.get_pubkey_from_ritual_id(
ritual_id
),
)
Expand All @@ -327,11 +328,11 @@ def dkg_setup(


@pytest.fixture(scope="module")
def dkg_encrypted_data(dkg_setup) -> Tuple[bytes, bytes, LingoList]:
def dkg_encrypted_data(dkg_setup) -> Tuple[Ciphertext, bytes, LingoList]:
_, public_key, _, _, _ = dkg_setup
enrico = Enrico(encrypting_key=public_key)
ciphertext = enrico.encrypt_for_dkg(
plaintext=PLAINTEXT.encode(), conditions=CONDITIONS
)

return bytes(ciphertext), PLAINTEXT.encode(), CONDITIONS
return ciphertext, PLAINTEXT.encode(), CONDITIONS
Loading

0 comments on commit c19046f

Please sign in to comment.