mirror of https://github.com/nucypher/nucypher.git
Merge pull request #3193 from derekpierre/no-exposed-variant
Don't expose Ferveo variant in python Bob public APIpull/3195/head
commit
57267c7019
|
@ -0,0 +1 @@
|
|||
Don't allow users to specify the FerveoVariant to use for threshold decryption. The default, simple variant, will be used.
|
|
@ -438,7 +438,7 @@ class Alice(Character, actors.PolicyAuthor):
|
|||
|
||||
class Bob(Character):
|
||||
banner = BOB_BANNER
|
||||
default_dkg_variant = FerveoVariant.SIMPLE
|
||||
_default_dkg_variant = FerveoVariant.SIMPLE
|
||||
_default_crypto_powerups = [SigningPower, DecryptingPower]
|
||||
_threshold_decryption_client_class = ThresholdDecryptionClient
|
||||
|
||||
|
@ -622,7 +622,7 @@ class Bob(Character):
|
|||
return cohort
|
||||
|
||||
@staticmethod
|
||||
def make_decryption_request(
|
||||
def __make_decryption_request(
|
||||
ritual_id: int,
|
||||
ciphertext: Ciphertext,
|
||||
lingo: Lingo,
|
||||
|
@ -712,7 +712,6 @@ class Bob(Character):
|
|||
conditions: Lingo,
|
||||
context: Optional[dict] = None,
|
||||
ursulas: Optional[List["Ursula"]] = None,
|
||||
variant: str = "simple",
|
||||
peering_timeout: int = 60,
|
||||
) -> bytes:
|
||||
ritual = self.get_ritual_from_id(ritual_id)
|
||||
|
@ -730,20 +729,14 @@ class Bob(Character):
|
|||
)
|
||||
self.remember_node(ursula)
|
||||
|
||||
try:
|
||||
variant = FerveoVariant(getattr(FerveoVariant, variant.upper()).value)
|
||||
except AttributeError:
|
||||
raise ValueError(
|
||||
f"Invalid variant: {variant}; Options are: {list(v.name.lower() for v in list(FerveoVariant))}"
|
||||
)
|
||||
|
||||
variant = self._default_dkg_variant
|
||||
threshold = (
|
||||
(ritual.shares // 2) + 1
|
||||
if variant == FerveoVariant.SIMPLE
|
||||
else ritual.shares
|
||||
) # TODO: #3095 get this from the ritual / put it on-chain?
|
||||
|
||||
decryption_request = self.make_decryption_request(
|
||||
decryption_request = self.__make_decryption_request(
|
||||
ritual_id=ritual_id,
|
||||
ciphertext=ciphertext,
|
||||
lingo=conditions,
|
||||
|
@ -758,12 +751,12 @@ class Bob(Character):
|
|||
threshold=threshold,
|
||||
)
|
||||
|
||||
return self._decrypt(
|
||||
return self.__decrypt(
|
||||
list(decryption_shares.values()), ciphertext, conditions, variant
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _decrypt(
|
||||
def __decrypt(
|
||||
shares: List[Union[DecryptionShareSimple, DecryptionSharePrecomputed]],
|
||||
ciphertext: Ciphertext,
|
||||
conditions: Lingo,
|
||||
|
@ -1453,7 +1446,6 @@ class Enrico:
|
|||
"""A data source that encrypts data for some policy's public key"""
|
||||
|
||||
banner = ENRICO_BANNER
|
||||
default_dkg_variant = FerveoVariant.SIMPLE
|
||||
|
||||
def __init__(self, encrypting_key: Union[PublicKey, DkgPublicKey]):
|
||||
self.signing_power = SigningPower()
|
||||
|
@ -1480,29 +1472,6 @@ class Enrico:
|
|||
ciphertext = encrypt(plaintext, conditions_bytes, self.policy_pubkey)
|
||||
return ciphertext
|
||||
|
||||
def encrypt_for_dkg_and_produce_decryption_request(
|
||||
self,
|
||||
plaintext: bytes,
|
||||
conditions: Lingo,
|
||||
ritual_id: int,
|
||||
variant: int = None,
|
||||
context: Optional[bytes] = None,
|
||||
) -> Tuple[Ciphertext, ThresholdDecryptionRequest]:
|
||||
ciphertext = self.encrypt_for_dkg(plaintext=plaintext, conditions=conditions)
|
||||
|
||||
if variant is None:
|
||||
variant = self.default_dkg_variant.value
|
||||
|
||||
tdr = ThresholdDecryptionRequest(
|
||||
ritual_id=ritual_id,
|
||||
ciphertext=ciphertext,
|
||||
conditions=Conditions(json.dumps(conditions)),
|
||||
context=context,
|
||||
variant=variant,
|
||||
)
|
||||
|
||||
return ciphertext, tdr
|
||||
|
||||
@classmethod
|
||||
def from_alice(cls, alice: Alice, label: bytes):
|
||||
"""
|
||||
|
|
|
@ -78,6 +78,7 @@ def verify_aggregate(
|
|||
):
|
||||
pvss_aggregated.verify(shares, transcripts)
|
||||
|
||||
|
||||
def derive_decryption_share(
|
||||
nodes: List[Validator],
|
||||
aggregated_transcript: AggregatedTranscript,
|
||||
|
@ -93,7 +94,7 @@ def derive_decryption_share(
|
|||
try:
|
||||
derive_share = _VARIANTS[variant]
|
||||
except KeyError:
|
||||
raise Exception(f"invalid variant {variant}")
|
||||
raise ValueError(f"Invalid variant {variant}")
|
||||
share = derive_share(
|
||||
# first arg here is intended to be "self" since the method is unbound
|
||||
aggregated_transcript,
|
||||
|
|
|
@ -134,7 +134,6 @@ def test_ursula_ritualist(testerchain, coordinator_agent, cohort, alice, bob):
|
|||
ritual_id=RITUAL_ID,
|
||||
ciphertext=ciphertext,
|
||||
conditions=CONDITIONS,
|
||||
# params=cohort[0].dkg_storage.get_dkg_params(RITUAL_ID),
|
||||
peering_timeout=0
|
||||
)
|
||||
assert bytes(cleartext) == PLAINTEXT.encode()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from time import time
|
||||
from typing import List
|
||||
from unittest.mock import PropertyMock, patch
|
||||
|
||||
import pytest
|
||||
import pytest_twisted
|
||||
|
@ -9,6 +10,7 @@ from web3.datastructures import AttributeDict
|
|||
|
||||
from nucypher.blockchain.eth.agents import CoordinatorAgent
|
||||
from nucypher.characters.lawful import Enrico, Ursula
|
||||
from nucypher.crypto.ferveo.dkg import FerveoVariant
|
||||
from nucypher.policy.conditions.lingo import ConditionLingo
|
||||
from tests.constants import TESTERCHAIN_CHAIN_ID
|
||||
from tests.mock.coordinator import MockCoordinatorAgent
|
||||
|
@ -31,17 +33,17 @@ ROUND_1_EVENT_NAME = "StartRitual"
|
|||
ROUND_2_EVENT_NAME = "StartAggregationRound"
|
||||
|
||||
PARAMS = [ # dkg_size, ritual_id, variant
|
||||
(2, 0, "precomputed"),
|
||||
(4, 1, "precomputed"),
|
||||
(8, 2, "precomputed"),
|
||||
(2, 3, "simple"),
|
||||
(4, 4, "simple"),
|
||||
(8, 5, "simple"),
|
||||
(2, 0, FerveoVariant.PRECOMPUTED),
|
||||
(4, 1, FerveoVariant.PRECOMPUTED),
|
||||
(8, 2, FerveoVariant.PRECOMPUTED),
|
||||
(2, 3, FerveoVariant.SIMPLE),
|
||||
(4, 4, FerveoVariant.SIMPLE),
|
||||
(8, 5, FerveoVariant.SIMPLE),
|
||||
# TODO: slow and need additional accounts for testing
|
||||
# (16, 6, "precomputed"),
|
||||
# (16, 7, "simple"),
|
||||
# (32, 8, "precomputed"),
|
||||
# (32, 9, "simple"),
|
||||
# (16, 6, FerveoVariant.PRECOMPUTED),
|
||||
# (16, 7, FerveoVariant.SIMPLE),
|
||||
# (32, 8, FerveoVariant.PRECOMPUTED),
|
||||
# (32, 9, FerveoVariant.SIMPLE),
|
||||
]
|
||||
|
||||
BLOCKS = list(reversed(range(1, 1000)))
|
||||
|
@ -127,7 +129,6 @@ def test_ursula_ritualist(
|
|||
test_registry_source_manager,
|
||||
):
|
||||
"""Tests the DKG and the encryption/decryption of a message"""
|
||||
|
||||
cohort = cohort[:dkg_size]
|
||||
|
||||
def initialize():
|
||||
|
@ -185,24 +186,18 @@ def test_ursula_ritualist(
|
|||
print("==================== DKG DECRYPTION ====================")
|
||||
bob.start_learning_loop(now=True)
|
||||
|
||||
cleartext = bob.threshold_decrypt(
|
||||
ritual_id=ritual_id,
|
||||
ciphertext=ciphertext,
|
||||
conditions=CONDITIONS,
|
||||
peering_timeout=0,
|
||||
variant=variant
|
||||
)
|
||||
assert bytes(cleartext) == PLAINTEXT.encode()
|
||||
# mock the use of non-default variants since it can no longer be specified
|
||||
with patch.object(
|
||||
bob, "_default_dkg_variant", new_callable=PropertyMock(return_value=variant)
|
||||
):
|
||||
cleartext = bob.threshold_decrypt(
|
||||
ritual_id=ritual_id,
|
||||
ciphertext=ciphertext,
|
||||
conditions=CONDITIONS,
|
||||
peering_timeout=0,
|
||||
)
|
||||
assert bytes(cleartext) == PLAINTEXT.encode()
|
||||
|
||||
# again, but without `params`
|
||||
cleartext = bob.threshold_decrypt(
|
||||
ritual_id=ritual_id,
|
||||
ciphertext=ciphertext,
|
||||
conditions=CONDITIONS,
|
||||
peering_timeout=0,
|
||||
variant=variant
|
||||
)
|
||||
assert bytes(cleartext) == PLAINTEXT.encode()
|
||||
print("==================== DECRYPTION SUCCESSFUL ====================")
|
||||
|
||||
def error_handler(e):
|
||||
|
|
|
@ -15,6 +15,7 @@ from nucypher_core.umbral import SecretKey, Signer
|
|||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.characters.lawful import Alice, Bob, Enrico, Ursula
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.crypto.ferveo.dkg import FerveoVariant
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from nucypher.crypto.powers import (
|
||||
DecryptingPower,
|
||||
|
@ -191,7 +192,7 @@ def test_ritualist(temp_dir_path, testerchain, dkg_public_key):
|
|||
ciphertext = enrico.encrypt_for_dkg(plaintext=plaintext, conditions=CONDITIONS)
|
||||
decryption_request = ThresholdDecryptionRequest(
|
||||
ritual_id=ritual_id,
|
||||
variant=0,
|
||||
variant=FerveoVariant.SIMPLE.value,
|
||||
ciphertext=ciphertext,
|
||||
conditions=Conditions(json.dumps(CONDITIONS)),
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue