mirror of https://github.com/nucypher/nucypher.git
feat: remove dependency on DkgPublicParams
parent
0eb10e2d37
commit
44d1e81b8f
2
Pipfile
2
Pipfile
|
@ -11,7 +11,7 @@ python_version = "3"
|
||||||
constant-sorrow = ">=0.1.0a9"
|
constant-sorrow = ">=0.1.0a9"
|
||||||
bytestring-splitter = ">=2.4.0"
|
bytestring-splitter = ">=2.4.0"
|
||||||
hendrix = ">=4.0"
|
hendrix = ">=4.0"
|
||||||
nucypher-core = ">=0.9.0"
|
nucypher-core = {git="https://github.com/nucypher/nucypher-core.git", ref="49144396dfa291491b62fe0a05c71de8d1adcd42", subdirectory="nucypher-core-python"}
|
||||||
# Cryptography
|
# Cryptography
|
||||||
cryptography = ">=3.2"
|
cryptography = ">=3.2"
|
||||||
mnemonic = "*"
|
mnemonic = "*"
|
||||||
|
|
|
@ -534,11 +534,10 @@ class Ritualist(BaseActor):
|
||||||
self.log.debug(f"Failed to aggregate transcripts for ritual #{ritual_id}: {str(e)}")
|
self.log.debug(f"Failed to aggregate transcripts for ritual #{ritual_id}: {str(e)}")
|
||||||
raise e
|
raise e
|
||||||
else:
|
else:
|
||||||
aggregated_transcript, dkg_public_key, params = result
|
aggregated_transcript, dkg_public_key = result
|
||||||
|
|
||||||
# Store the DKG artifacts for later us
|
# Store the DKG artifacts for later us
|
||||||
self.dkg_storage.store_aggregated_transcript(ritual_id=ritual_id, aggregated_transcript=aggregated_transcript)
|
self.dkg_storage.store_aggregated_transcript(ritual_id=ritual_id, aggregated_transcript=aggregated_transcript)
|
||||||
self.dkg_storage.store_dkg_params(ritual_id=ritual_id, public_params=params)
|
|
||||||
self.dkg_storage.store_public_key(ritual_id=ritual_id, public_key=dkg_public_key)
|
self.dkg_storage.store_public_key(ritual_id=ritual_id, public_key=dkg_public_key)
|
||||||
|
|
||||||
# publish the transcript and store the receipt
|
# publish the transcript and store the receipt
|
||||||
|
|
|
@ -50,7 +50,6 @@ from nucypher_core.ferveo import (
|
||||||
DecryptionSharePrecomputed,
|
DecryptionSharePrecomputed,
|
||||||
DecryptionShareSimple,
|
DecryptionShareSimple,
|
||||||
DkgPublicKey,
|
DkgPublicKey,
|
||||||
DkgPublicParameters,
|
|
||||||
Transcript,
|
Transcript,
|
||||||
Validator,
|
Validator,
|
||||||
combine_decryption_shares_precomputed,
|
combine_decryption_shares_precomputed,
|
||||||
|
@ -670,7 +669,6 @@ class Bob(Character):
|
||||||
ciphertext: Ciphertext,
|
ciphertext: Ciphertext,
|
||||||
conditions: Lingo,
|
conditions: Lingo,
|
||||||
context: Optional[dict] = None,
|
context: Optional[dict] = None,
|
||||||
params: Optional[DkgPublicParameters] = None,
|
|
||||||
ursulas: Optional[List["Ursula"]] = None,
|
ursulas: Optional[List["Ursula"]] = None,
|
||||||
variant: str = "simple",
|
variant: str = "simple",
|
||||||
peering_timeout: int = 60,
|
peering_timeout: int = 60,
|
||||||
|
@ -716,18 +714,8 @@ class Bob(Character):
|
||||||
participant_public_keys=participant_public_keys,
|
participant_public_keys=participant_public_keys,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not params:
|
|
||||||
# TODO: Bob can call.verify here instead of aggregating the shares.
|
|
||||||
# if the DKG parameters are not provided, we need to
|
|
||||||
# aggregate the transcripts and derive them.
|
|
||||||
|
|
||||||
# TODO we don't need all ursulas, only threshold of them
|
|
||||||
# ursulas = [u for u in ursulas if u.checksum_address in decryption_shares]
|
|
||||||
params = self.__derive_dkg_parameters(ritual_id, ursulas, ritual, threshold)
|
|
||||||
# TODO: compare the results with the on-chain records (Coordinator).
|
|
||||||
|
|
||||||
return self.__decrypt(
|
return self.__decrypt(
|
||||||
list(decryption_shares.values()), ciphertext, conditions, params, variant
|
list(decryption_shares.values()), ciphertext, conditions, variant
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -735,7 +723,6 @@ class Bob(Character):
|
||||||
shares: List[Union[DecryptionShareSimple, DecryptionSharePrecomputed]],
|
shares: List[Union[DecryptionShareSimple, DecryptionSharePrecomputed]],
|
||||||
ciphertext: Ciphertext,
|
ciphertext: Ciphertext,
|
||||||
conditions: Lingo,
|
conditions: Lingo,
|
||||||
params: DkgPublicParameters,
|
|
||||||
variant: FerveoVariant,
|
variant: FerveoVariant,
|
||||||
):
|
):
|
||||||
"""decrypt the ciphertext"""
|
"""decrypt the ciphertext"""
|
||||||
|
@ -750,25 +737,9 @@ class Bob(Character):
|
||||||
ciphertext,
|
ciphertext,
|
||||||
conditions, # aad
|
conditions, # aad
|
||||||
shared_secret,
|
shared_secret,
|
||||||
params # dkg params
|
|
||||||
)
|
)
|
||||||
return cleartext
|
return cleartext
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def __derive_dkg_parameters(ritual_id: int, ursulas, ritual, threshold) -> DkgPublicParameters:
|
|
||||||
validators = [u.as_external_validator() for u in ursulas]
|
|
||||||
validators = sorted(validators, key=lambda v: v.address)
|
|
||||||
transcripts = [Transcript.from_bytes(t[1]) for t in ritual.transcripts]
|
|
||||||
data = list(zip(validators, transcripts))
|
|
||||||
pvss_aggregated, public_key, params = aggregate_transcripts(
|
|
||||||
ritual_id=ritual_id,
|
|
||||||
me=validators[0], # TODO: #3097 this is awkward, but we need to pass "me" here to derive_generator_inverse
|
|
||||||
threshold=threshold,
|
|
||||||
shares=ritual.shares,
|
|
||||||
transcripts=data
|
|
||||||
)
|
|
||||||
return params
|
|
||||||
|
|
||||||
|
|
||||||
class Ursula(Teacher, Character, Operator, Ritualist):
|
class Ursula(Teacher, Character, Operator, Ritualist):
|
||||||
|
|
||||||
|
|
|
@ -51,15 +51,15 @@ def derive_public_key(*args, **kwargs) -> DkgPublicKey:
|
||||||
|
|
||||||
def aggregate_transcripts(
|
def aggregate_transcripts(
|
||||||
transcripts: List[Tuple[Validator, Transcript]], shares: int, *args, **kwargs
|
transcripts: List[Tuple[Validator, Transcript]], shares: int, *args, **kwargs
|
||||||
) -> Tuple[AggregatedTranscript, DkgPublicKey, DkgPublicParameters]:
|
) -> Tuple[AggregatedTranscript, DkgPublicKey]:
|
||||||
validators = [t[0] for t in transcripts]
|
validators = [t[0] for t in transcripts]
|
||||||
_dkg = _make_dkg(nodes=validators, shares=shares, *args, **kwargs)
|
_dkg = _make_dkg(nodes=validators, shares=shares, *args, **kwargs)
|
||||||
pvss_aggregated = _dkg.aggregate_transcripts(transcripts)
|
pvss_aggregated = _dkg.aggregate_transcripts(transcripts)
|
||||||
verify_aggregate(pvss_aggregated, shares, transcripts)
|
verify_aggregate(pvss_aggregated, shares, transcripts)
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
f"derived final DKG key {bytes(_dkg.public_key).hex()[:10]} and {keccak(bytes(_dkg.public_params)).hex()[:10]}"
|
f"derived final DKG key {bytes(_dkg.public_key).hex()[:10]}"
|
||||||
)
|
)
|
||||||
return pvss_aggregated, _dkg.public_key, _dkg.public_params
|
return pvss_aggregated, _dkg.public_key
|
||||||
|
|
||||||
|
|
||||||
def verify_aggregate(
|
def verify_aggregate(
|
||||||
|
|
|
@ -315,15 +315,15 @@ class RitualisticPower(KeyPairBasedPower):
|
||||||
shares: int,
|
shares: int,
|
||||||
threshold: int,
|
threshold: int,
|
||||||
transcripts: list
|
transcripts: list
|
||||||
) -> Tuple[AggregatedTranscript, DkgPublicKey, Any]:
|
) -> Tuple[AggregatedTranscript, DkgPublicKey]:
|
||||||
aggregated_transcript, dkg_public_key, params = dkg.aggregate_transcripts(
|
aggregated_transcript, dkg_public_key = dkg.aggregate_transcripts(
|
||||||
ritual_id=ritual_id,
|
ritual_id=ritual_id,
|
||||||
me=Validator(address=checksum_address, public_key=self.keypair.pubkey),
|
me=Validator(address=checksum_address, public_key=self.keypair.pubkey),
|
||||||
shares=shares,
|
shares=shares,
|
||||||
threshold=threshold,
|
threshold=threshold,
|
||||||
transcripts=transcripts
|
transcripts=transcripts
|
||||||
)
|
)
|
||||||
return aggregated_transcript, dkg_public_key, params
|
return aggregated_transcript, dkg_public_key
|
||||||
|
|
||||||
|
|
||||||
class DerivedKeyBasedPower(CryptoPowerUp):
|
class DerivedKeyBasedPower(CryptoPowerUp):
|
||||||
|
|
|
@ -36,12 +36,6 @@ class DKGStorage:
|
||||||
def get_aggregated_transcript_receipt(self, ritual_id: int) -> TxReceipt:
|
def get_aggregated_transcript_receipt(self, ritual_id: int) -> TxReceipt:
|
||||||
return self.data["aggregated_transcript_receipts"][ritual_id]
|
return self.data["aggregated_transcript_receipts"][ritual_id]
|
||||||
|
|
||||||
def store_dkg_params(self, ritual_id: int, public_params) -> None:
|
|
||||||
self.data["public_params"][ritual_id] = public_params
|
|
||||||
|
|
||||||
def get_dkg_params(self, ritual_id: int) -> int:
|
|
||||||
return self.data["public_params"][ritual_id]
|
|
||||||
|
|
||||||
def store_public_key(self, ritual_id: int, public_key: bytes) -> None:
|
def store_public_key(self, ritual_id: int, public_key: bytes) -> None:
|
||||||
self.data["public_keys"][ritual_id] = public_key
|
self.data["public_keys"][ritual_id] = public_key
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ msgpack==1.0.5
|
||||||
msgpack-python==0.5.6
|
msgpack-python==0.5.6
|
||||||
multidict==5.2.0 ; python_version >= '3.6'
|
multidict==5.2.0 ; python_version >= '3.6'
|
||||||
mypy-extensions==0.4.4 ; python_version >= '2.7'
|
mypy-extensions==0.4.4 ; python_version >= '2.7'
|
||||||
nucypher-core==0.9.0
|
nucypher-core@git+https://github.com/nucypher/nucypher-core.git@49144396dfa291491b62fe0a05c71de8d1adcd42#subdirectory=nucypher-core-python
|
||||||
packaging==23.1 ; python_version >= '3.7'
|
packaging==23.1 ; python_version >= '3.7'
|
||||||
parsimonious==0.9.0
|
parsimonious==0.9.0
|
||||||
pendulum==3.0.0a1 ; python_version >= '3.7' and python_version < '4.0'
|
pendulum==3.0.0a1 ; python_version >= '3.7' and python_version < '4.0'
|
||||||
|
|
|
@ -16,7 +16,6 @@ from eth_utils import to_checksum_address
|
||||||
from nucypher_core.ferveo import (
|
from nucypher_core.ferveo import (
|
||||||
AggregatedTranscript,
|
AggregatedTranscript,
|
||||||
DkgPublicKey,
|
DkgPublicKey,
|
||||||
DkgPublicParameters,
|
|
||||||
Keypair,
|
Keypair,
|
||||||
Validator,
|
Validator,
|
||||||
)
|
)
|
||||||
|
@ -729,7 +728,7 @@ def ursulas(
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def dkg_public_key_data(
|
def dkg_public_key_data(
|
||||||
get_random_checksum_address,
|
get_random_checksum_address,
|
||||||
) -> Tuple[AggregatedTranscript, DkgPublicKey, DkgPublicParameters]:
|
) -> Tuple[AggregatedTranscript, DkgPublicKey]:
|
||||||
ritual_id = 0
|
ritual_id = 0
|
||||||
num_shares = 4
|
num_shares = 4
|
||||||
threshold = 3
|
threshold = 3
|
||||||
|
@ -755,7 +754,7 @@ def dkg_public_key_data(
|
||||||
)
|
)
|
||||||
transcripts.append(transcript)
|
transcripts.append(transcript)
|
||||||
|
|
||||||
aggregate_transcript, public_key, params = dkg.aggregate_transcripts(
|
aggregate_transcript, public_key = dkg.aggregate_transcripts(
|
||||||
ritual_id=ritual_id,
|
ritual_id=ritual_id,
|
||||||
me=validators[0],
|
me=validators[0],
|
||||||
shares=num_shares,
|
shares=num_shares,
|
||||||
|
@ -763,16 +762,16 @@ def dkg_public_key_data(
|
||||||
transcripts=list(zip(validators, transcripts)),
|
transcripts=list(zip(validators, transcripts)),
|
||||||
)
|
)
|
||||||
|
|
||||||
return aggregate_transcript, public_key, params
|
return aggregate_transcript, public_key
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def dkg_public_key(dkg_public_key_data) -> DkgPublicKey:
|
def dkg_public_key(dkg_public_key_data) -> DkgPublicKey:
|
||||||
_, dkg_public_key, _ = dkg_public_key_data
|
_, dkg_public_key = dkg_public_key_data
|
||||||
return dkg_public_key
|
return dkg_public_key
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def aggregated_transcript(dkg_public_key_data) -> AggregatedTranscript:
|
def aggregated_transcript(dkg_public_key_data) -> AggregatedTranscript:
|
||||||
aggregated_transcript, _, _ = dkg_public_key_data
|
aggregated_transcript, _ = dkg_public_key_data
|
||||||
return aggregated_transcript
|
return aggregated_transcript
|
||||||
|
|
|
@ -175,14 +175,10 @@ def test_ursula_ritualist(testerchain, mock_coordinator_agent, cohort, alice, bo
|
||||||
print("==================== DKG DECRYPTION ====================")
|
print("==================== DKG DECRYPTION ====================")
|
||||||
bob.start_learning_loop(now=True)
|
bob.start_learning_loop(now=True)
|
||||||
|
|
||||||
# ritual_id, ciphertext, conditions, and params are obtained from the side channel
|
|
||||||
params = cohort[0].dkg_storage.get_dkg_params(ritual_id)
|
|
||||||
|
|
||||||
cleartext = bob.threshold_decrypt(
|
cleartext = bob.threshold_decrypt(
|
||||||
ritual_id=ritual_id,
|
ritual_id=ritual_id,
|
||||||
ciphertext=ciphertext,
|
ciphertext=ciphertext,
|
||||||
conditions=CONDITIONS,
|
conditions=CONDITIONS,
|
||||||
params=params,
|
|
||||||
peering_timeout=0,
|
peering_timeout=0,
|
||||||
variant=variant
|
variant=variant
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue