Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ jobs:
working-directory: ferveo-python

- name: Run ruff
run: ruff check ferveo
run: ruff check .
working-directory: ferveo-python

codecov:
Expand Down
2 changes: 1 addition & 1 deletion ferveo-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ferveo-nucypher-common"
version = "0.4.0"
version = "0.4.1"
edition = "2021"
license = "GPL-3.0"
authors = ["David Nuñez <david@nucypher.com>", "Piotr Roslaniec <p.roslaniec@gmail.com>", "Heliax AG <hello@heliax.dev>"]
Expand Down
2 changes: 1 addition & 1 deletion ferveo-python/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "ferveo-python"
authors = ["David Nuñez <david@nucypher.com>", "Piotr Roslaniec <p.roslaniec@gmail.com>"]
version = "0.4.0"
version = "0.4.1"
edition = "2021"
repository = "https://github.com/nucypher/ferveo"
publish = false
Expand Down
2 changes: 1 addition & 1 deletion ferveo-python/examples/exception.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from ferveo import (
Dkg,
Keypair,
Validator,
Dkg,
)


Expand Down
10 changes: 5 additions & 5 deletions ferveo-python/examples/server_api_precomputed.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from ferveo import (
encrypt,
combine_decryption_shares_precomputed,
decrypt_with_shared_secret,
AggregatedTranscript,
Dkg,
Keypair,
Validator,
ValidatorMessage,
Dkg,
AggregatedTranscript,
combine_decryption_shares_precomputed,
decrypt_with_shared_secret,
encrypt,
)


Expand Down
13 changes: 5 additions & 8 deletions ferveo-python/examples/server_api_simple.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from ferveo import (
encrypt,
combine_decryption_shares_simple,
decrypt_with_shared_secret,
AggregatedTranscript,
Dkg,
Keypair,
Validator,
ValidatorMessage,
Dkg,
AggregatedTranscript,
combine_decryption_shares_simple,
decrypt_with_shared_secret,
encrypt,
)


Expand All @@ -24,9 +24,6 @@ def gen_eth_addr(i: int) -> str:
for i, keypair in enumerate(validator_keypairs)
]

# Validators must be sorted by their public key
validators.sort(key=lambda v: v.address)

# Each validator holds their own DKG instance and generates a transcript every
# validator, including themselves
messages = []
Expand Down
13 changes: 5 additions & 8 deletions ferveo-python/examples/server_api_simple_with_handover.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from ferveo import (
encrypt,
combine_decryption_shares_simple,
decrypt_with_shared_secret,
AggregatedTranscript,
Dkg,
Keypair,
Validator,
ValidatorMessage,
Dkg,
AggregatedTranscript,
combine_decryption_shares_simple,
decrypt_with_shared_secret,
encrypt,
)


Expand All @@ -24,9 +24,6 @@ def gen_eth_addr(i: int) -> str:
for i, keypair in enumerate(validator_keypairs)
]

# Validators must be sorted by their public key
validators.sort(key=lambda v: v.address)

# Each validator holds their own DKG instance and generates a transcript every
# validator, including themselves
messages = []
Expand Down
3 changes: 3 additions & 0 deletions ferveo-python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ requires = ["setuptools", "wheel", "setuptools-rust"]
[tool.ruff]
exclude = ["ferveo/__init__.py"] # false-positive unused-import
select = ["E", "F", "I"]

[tool.ruff.lint]
ignore = ["E501"]
4 changes: 2 additions & 2 deletions ferveo-python/setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from pathlib import Path

from setuptools import setup
from setuptools_rust import Binding, RustExtension

from pathlib import Path

this_directory = Path(__file__).parent
long_description = (this_directory / "README.md").read_text()

Expand Down
15 changes: 7 additions & 8 deletions ferveo-python/test/test_ferveo.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import pytest

from ferveo import (
encrypt,
combine_decryption_shares_simple,
combine_decryption_shares_precomputed,
decrypt_with_shared_secret,
AggregatedTranscript,
Dkg,
FerveoVariant,
Keypair,
ThresholdEncryptionError,
Validator,
ValidatorMessage,
Dkg,
DkgPublicKey,
ThresholdEncryptionError,
FerveoVariant,
combine_decryption_shares_precomputed,
combine_decryption_shares_simple,
decrypt_with_shared_secret,
encrypt,
)


Expand Down
57 changes: 49 additions & 8 deletions ferveo-python/test/test_serialization.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import pytest

from ferveo import (
Keypair,
Validator,
AggregatedTranscript,
Dkg,
DkgPublicKey,
FerveoPublicKey,
FerveoVariant,
ValidatorMessage
Keypair,
Validator,
ValidatorMessage,
)


Expand All @@ -24,19 +27,24 @@ def gen_eth_addr(i: int) -> str:
validators.sort(key=lambda v: v.address)


def make_dkg_public_key():
@pytest.fixture(scope="module")
def dkg():
me = validators[0]
dkg = Dkg(
return Dkg(
tau=tau,
shares_num=shares_num,
security_threshold=security_threshold,
validators=validators,
me=me,
)


@pytest.fixture(scope="module")
def aggregate(dkg):
transcripts = [ValidatorMessage(v, dkg.generate_transcript()) for v in validators]
aggregate = dkg.aggregate_transcripts(transcripts)
assert aggregate.verify(shares_num, transcripts)
return aggregate.public_key
return aggregate


def make_shared_secret():
Expand Down Expand Up @@ -67,8 +75,8 @@ def test_keypair_serialization():
assert serialized == bytes(deserialized)


def test_dkg_public_key_serialization():
dkg_pk = make_dkg_public_key()
def test_dkg_public_key_serialization(aggregate):
dkg_pk = aggregate.public_key
serialized = bytes(dkg_pk)
deserialized = DkgPublicKey.from_bytes(serialized)
# TODO: Implement __richcmp__
Expand All @@ -90,3 +98,36 @@ def test_ferveo_variant_serialization():
assert FerveoVariant.Precomputed == FerveoVariant.Precomputed
assert FerveoVariant.Simple == FerveoVariant.Simple
assert FerveoVariant.Precomputed != FerveoVariant.Simple


def test_aggregate_transcript_serialization(aggregate):
serialized = bytes(aggregate)
deserialized = AggregatedTranscript.from_bytes(serialized)
assert bytes(aggregate.public_key) == bytes(deserialized.public_key)


def test_aggregate_transcript_validity(dkg, aggregate):
assert aggregate.verify_for_dkg(dkg)


@pytest.mark.parametrize("handover_slot_index", range(shares_num))
def test_handover_serialization(dkg, aggregate, handover_slot_index):
incoming_validator_keypair = Keypair.random()
departing_keypair = validator_keypairs[handover_slot_index]

handover_transcript = dkg.generate_handover_transcript(
aggregate,
handover_slot_index,
incoming_validator_keypair,
)

assert handover_transcript.share_index == handover_slot_index

assert aggregate.validate_handover_transcript(handover_transcript)

new_aggregate = aggregate.finalize_handover(
handover_transcript, departing_keypair
)

assert bytes(new_aggregate.public_key) == bytes(aggregate.public_key)
assert bytes(new_aggregate) != bytes(aggregate)
6 changes: 3 additions & 3 deletions ferveo-tdec/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ferveo-nucypher-tdec"
version = "0.4.0"
version = "0.4.1"
edition = "2021"
authors = ["David Nuñez <david@nucypher.com>", "Piotr Roslaniec <p.roslaniec@gmail.com>", "Heliax AG <hello@heliax.dev>"]
license = "GPL-3.0"
Expand All @@ -24,7 +24,7 @@ ark-serialize = { workspace = true }
ark-std = { workspace = true }
bincode = { workspace = true }
chacha20poly1305 = { workspace = true }
ferveo-common = { package = "ferveo-nucypher-common", path = "../ferveo-common", version = "^0.4.0" }
ferveo-common = { package = "ferveo-nucypher-common", path = "../ferveo-common", version = "^0.4.1" }
itertools = { workspace = true }
miracl_core = { workspace = true }
rand = { workspace = true }
Expand All @@ -33,7 +33,7 @@ serde = { workspace = true, features = ["derive"] }
serde_bytes = { workspace = true }
serde_with = { workspace = true }
sha2 = { workspace = true }
subproductdomain = { package = "subproductdomain-nucypher", path = "../subproductdomain", version = "^0.4.0" }
subproductdomain = { package = "subproductdomain-nucypher", path = "../subproductdomain", version = "^0.4.1" }
thiserror = { workspace = true }
zeroize = { workspace = true }

Expand Down
2 changes: 1 addition & 1 deletion ferveo-wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ferveo-wasm"
version = "0.4.0"
version = "0.4.1"
authors = ["David Nuñez <david@nucypher.com>", "Piotr Roslaniec <p.roslaniec@gmail.com>"]
edition = "2021"
license = "GPL-3.0-only"
Expand Down
8 changes: 4 additions & 4 deletions ferveo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ferveo-nucypher"
version = "0.4.0"
version = "0.4.1"
edition = "2021"
license = "GPL-3.0"
repository = "https://github.com/nucypher/ferveo"
Expand All @@ -21,8 +21,8 @@ ark-poly = { workspace = true }
ark-serialize = { workspace = true }
ark-std = { workspace = true }
bincode = { workspace = true }
ferveo-common = { package = "ferveo-nucypher-common", path = "../ferveo-common", version = "^0.4.0" }
ferveo-tdec = { package = "ferveo-nucypher-tdec", path = "../ferveo-tdec", features = ["api", "test-common"], version = "^0.4.0" }
ferveo-common = { package = "ferveo-nucypher-common", path = "../ferveo-common", version = "^0.4.1" }
ferveo-tdec = { package = "ferveo-nucypher-tdec", path = "../ferveo-tdec", features = ["api", "test-common"], version = "^0.4.1" }
hex = { workspace = true }
itertools = { workspace = true }
measure_time = { workspace = true }
Expand All @@ -31,7 +31,7 @@ rand_core = { workspace = true }
rand_old = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_with = { workspace = true }
subproductdomain = { package = "subproductdomain-nucypher", path = "../subproductdomain", version = "^0.4.0" }
subproductdomain = { package = "subproductdomain-nucypher", path = "../subproductdomain", version = "^0.4.1" }
thiserror = { workspace = true }
zeroize = { workspace = true, features = ["derive"] }
generic-array = { workspace = true }
Expand Down
29 changes: 28 additions & 1 deletion ferveo/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::bindings_python;
use crate::bindings_wasm;
pub use crate::EthereumAddress;
use crate::{
do_verify_aggregation, Error, PubliclyVerifiableSS, Result,
do_verify_aggregation, Aggregated, Error, PubliclyVerifiableSS, Result,
UpdateTranscript,
};

Expand Down Expand Up @@ -315,6 +315,10 @@ impl AggregatedTranscript {
)
}

pub fn verify_for_dkg(&self, dkg: &Dkg) -> Result<bool> {
self.0.aggregate.verify_full(&dkg.0)
}

pub fn create_decryption_share_precomputed(
&self,
dkg: &Dkg,
Expand Down Expand Up @@ -382,6 +386,19 @@ impl AggregatedTranscript {
Ok(AggregatedTranscript(eeww))
}

pub fn validate_handover_transcript(
&self,
handover_transcript: &HandoverTranscript,
) -> Result<bool> {
let share_commitments = self.0.aggregate.get_share_commitments();
let share_commitment = share_commitments
.get(handover_transcript.0.share_index as usize)
.ok_or(
Error::InvalidTranscriptAggregate, // FIXME: better error
)?;
handover_transcript.0.validate(share_commitment)
}

pub fn finalize_handover(
&self,
handover_transcript: &HandoverTranscript,
Expand All @@ -398,6 +415,16 @@ impl AggregatedTranscript {
.unwrap();
Ok(AggregatedTranscript(eeww))
}

pub fn aggregate(&self) -> &PubliclyVerifiableSS<E, Aggregated> {
&self.0.aggregate
}
}

impl HandoverTranscript {
pub fn share_index(&self) -> u32 {
self.0.share_index
}
}

#[serde_as]
Expand Down
Loading
Loading