Skip to content

Commit

Permalink
feature!: remove state from dkg, part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-roslaniec committed Feb 19, 2024
1 parent 779a7bb commit a9e7f44
Show file tree
Hide file tree
Showing 22 changed files with 483 additions and 745 deletions.
2 changes: 1 addition & 1 deletion ferveo-python/examples/server_api_precomputed.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def gen_eth_addr(i: int) -> str:
# In the meantime, the client creates a ciphertext and decryption request
msg = "abc".encode()
aad = "my-aad".encode()
ciphertext = encrypt(msg, aad, dkg.public_key)
ciphertext = encrypt(msg, aad, client_aggregate.public_key)

# Having aggregated the transcripts, the validators can now create decryption shares
decryption_shares = []
Expand Down
2 changes: 1 addition & 1 deletion ferveo-python/examples/server_api_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def gen_eth_addr(i: int) -> str:
# In the meantime, the client creates a ciphertext and decryption request
msg = "abc".encode()
aad = "my-aad".encode()
ciphertext = encrypt(msg, aad, dkg.public_key)
ciphertext = encrypt(msg, aad, client_aggregate.public_key)

# The client can serialize/deserialize ciphertext for transport
ciphertext_ser = bytes(ciphertext)
Expand Down
1 change: 1 addition & 0 deletions ferveo-python/ferveo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@
NoTranscriptsToAggregate,
InvalidAggregateVerificationParameters,
UnknownValidator,
TooManyTranscripts,
)
3 changes: 3 additions & 0 deletions ferveo-python/ferveo/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,6 @@ class InvalidAggregateVerificationParameters(Exception):

class UnknownValidator(Exception):
pass

class TooManyTranscripts(Exception):
pass
2 changes: 1 addition & 1 deletion ferveo-python/test/test_ferveo.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def scenario_for_variant(
# Client creates a ciphertext and requests decryption shares from validators
msg = "abc".encode()
aad = "my-aad".encode()
ciphertext = encrypt(msg, aad, dkg.public_key)
ciphertext = encrypt(msg, aad, client_aggregate.public_key)

# Having aggregated the transcripts, the validators can now create decryption shares
decryption_shares = []
Expand Down
6 changes: 5 additions & 1 deletion ferveo-python/test/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
DkgPublicKey,
FerveoPublicKey,
FerveoVariant,
ValidatorMessage
)


Expand Down Expand Up @@ -32,7 +33,10 @@ def make_dkg_public_key():
validators=validators,
me=me,
)
return dkg.public_key
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


def make_shared_secret():
Expand Down
5 changes: 2 additions & 3 deletions ferveo-tdec/src/ciphertext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ pub fn encrypt<E: Pairing>(
// h
let h_gen = E::G2Affine::generator();

let ry_prep =
E::G1Prepared::from(pubkey.public_key_share.mul(rand_element).into());
let ry_prep = E::G1Prepared::from(pubkey.0.mul(rand_element).into());
// s
let product = E::pairing(ry_prep, h_gen).0;
// u
Expand Down Expand Up @@ -150,7 +149,7 @@ pub fn decrypt_symmetric<E: Pairing>(
ciphertext.check(aad, g_inv)?;
let shared_secret = E::pairing(
E::G1Prepared::from(ciphertext.commitment),
E::G2Prepared::from(private_key.private_key_share),
E::G2Prepared::from(private_key.0),
)
.0;
let shared_secret = SharedSecret(shared_secret);
Expand Down
30 changes: 12 additions & 18 deletions ferveo-tdec/src/decryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ impl<E: Pairing> ValidatorShareChecksum<E> {

#[serde_as]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound(
serialize = "ValidatorShareChecksum<E>: Serialize",
deserialize = "ValidatorShareChecksum<E>: DeserializeOwned"
))]
pub struct DecryptionShareSimple<E: Pairing> {
#[serde_as(as = "serialization::SerdeAs")]
pub decryption_share: E::TargetField,
#[serde(bound(
serialize = "ValidatorShareChecksum<E>: Serialize",
deserialize = "ValidatorShareChecksum<E>: DeserializeOwned"
))]
pub validator_checksum: ValidatorShareChecksum<E>,
}

Expand Down Expand Up @@ -110,11 +110,8 @@ impl<E: Pairing> DecryptionShareSimple<E> {
ciphertext_header: &CiphertextHeader<E>,
) -> Result<Self> {
// D_i = e(U, Z_i)
let decryption_share = E::pairing(
ciphertext_header.commitment,
private_key_share.private_key_share,
)
.0;
let decryption_share =
E::pairing(ciphertext_header.commitment, private_key_share.0).0;

let validator_checksum = ValidatorShareChecksum::new(
validator_decryption_key,
Expand Down Expand Up @@ -146,14 +143,14 @@ impl<E: Pairing> DecryptionShareSimple<E> {

#[serde_as]
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound(
serialize = "ValidatorShareChecksum<E>: Serialize",
deserialize = "ValidatorShareChecksum<E>: DeserializeOwned"
))]
pub struct DecryptionSharePrecomputed<E: Pairing> {
pub decrypter_index: usize,
#[serde_as(as = "serialization::SerdeAs")]
pub decryption_share: E::TargetField,
#[serde(bound(
serialize = "ValidatorShareChecksum<E>: Serialize",
deserialize = "ValidatorShareChecksum<E>: DeserializeOwned"
))]
pub validator_checksum: ValidatorShareChecksum<E>,
}

Expand Down Expand Up @@ -188,11 +185,8 @@ impl<E: Pairing> DecryptionSharePrecomputed<E> {
let u_to_lagrange_coeff =
ciphertext_header.commitment.mul(lagrange_coeff);
// C_{λ_i} = e(U_{λ_i}, Z_i)
let decryption_share = E::pairing(
u_to_lagrange_coeff,
private_key_share.private_key_share,
)
.0;
let decryption_share =
E::pairing(u_to_lagrange_coeff, private_key_share.0).0;

let validator_checksum = ValidatorShareChecksum::new(
validator_decryption_key,
Expand Down
21 changes: 10 additions & 11 deletions ferveo-tdec/src/key_share.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use zeroize::{Zeroize, ZeroizeOnDrop};

#[derive(Debug, Clone)]
#[serde_as]
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
// TODO: Should we rename it to PublicKey or SharedPublicKey?
pub struct PublicKeyShare<E: Pairing> {
pub public_key_share: E::G1Affine, // A_{i, \omega_i}
}
pub struct PublicKeyShare<E: Pairing>(
#[serde_as(as = "serialization::SerdeAs")] pub E::G1Affine, // A_{i, \omega_i}
);

#[derive(Debug, Clone)]
pub struct BlindedKeyShare<E: Pairing> {
Expand All @@ -31,7 +32,7 @@ impl<E: Pairing> BlindedKeyShare<E> {
let alpha = E::ScalarField::rand(rng);

let alpha_a = E::G1Prepared::from(
g + public_key_share.public_key_share.mul(alpha).into_affine(),
g + public_key_share.0.mul(alpha).into_affine(),
);

// \sum_i(Y_i)
Expand All @@ -56,18 +57,16 @@ impl<E: Pairing> BlindedKeyShare<E> {
#[derive(
Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Zeroize, ZeroizeOnDrop,
)]
pub struct PrivateKeyShare<E: Pairing> {
// TODO: Replace with a tuple?
#[serde_as(as = "serialization::SerdeAs")]
pub private_key_share: E::G2Affine,
}
pub struct PrivateKeyShare<E: Pairing>(
#[serde_as(as = "serialization::SerdeAs")] pub E::G2Affine,
);

impl<E: Pairing> PrivateKeyShare<E> {
pub fn blind(&self, b: E::ScalarField) -> BlindedKeyShare<E> {
let blinding_key = E::G2Affine::generator().mul(b).into_affine();
BlindedKeyShare::<E> {
blinding_key,
blinded_key_share: self.private_key_share.mul(b).into_affine(),
blinded_key_share: self.0.mul(b).into_affine(),
}
}
}
32 changes: 8 additions & 24 deletions ferveo-tdec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,7 @@ pub mod test_common {
)
.enumerate()
{
let private_key_share = PrivateKeyShare {
private_key_share: *private,
};
let private_key_share = PrivateKeyShare(*private);
let b = E::ScalarField::rand(rng);
let mut blinded_key_shares = private_key_share.blind(b);
blinded_key_shares.multiply_by_omega_inv(domain_inv);
Expand All @@ -159,9 +157,7 @@ pub mod test_common {
});
public_contexts.push(PublicDecryptionContextFast::<E> {
domain: *domain,
public_key_share: PublicKeyShare::<E> {
public_key_share: *public,
},
public_key_share: PublicKeyShare::<E>(*public),
blinded_key_share: blinded_key_shares,
lagrange_n_0: *domain,
h_inv: E::G2Prepared::from(-h.into_group()),
Expand All @@ -172,12 +168,8 @@ pub mod test_common {
}

(
PublicKeyShare {
public_key_share: pubkey.into(),
},
PrivateKeyShare {
private_key_share: privkey.into(),
},
PublicKeyShare(pubkey.into()),
PrivateKeyShare(privkey.into()),
private_contexts,
)
}
Expand Down Expand Up @@ -235,9 +227,7 @@ pub mod test_common {
izip!(shares_x.iter(), pubkey_shares.iter(), privkey_shares.iter())
.enumerate()
{
let private_key_share = PrivateKeyShare::<E> {
private_key_share: *private,
};
let private_key_share = PrivateKeyShare::<E>(*private);
let b = E::ScalarField::rand(rng);
let blinded_key_share = private_key_share.blind(b);
private_contexts.push(PrivateDecryptionContextSimple::<E> {
Expand All @@ -255,9 +245,7 @@ pub mod test_common {
});
public_contexts.push(PublicDecryptionContextSimple::<E> {
domain: *domain,
public_key_share: PublicKeyShare::<E> {
public_key_share: *public,
},
public_key_share: PublicKeyShare::<E>(*public),
blinded_key_share,
h,
validator_public_key: h.mul(b),
Expand All @@ -268,12 +256,8 @@ pub mod test_common {
}

(
PublicKeyShare {
public_key_share: pubkey.into(),
},
PrivateKeyShare {
private_key_share: privkey.into(),
},
PublicKeyShare(pubkey.into()),
PrivateKeyShare(privkey.into()),
private_contexts,
)
}
Expand Down
2 changes: 1 addition & 1 deletion ferveo-wasm/examples/node/src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function setupTest(
// Client creates a ciphertext and requests decryption shares from validators
const msg = Buffer.from("my-msg");
const aad = Buffer.from("my-aad");
const ciphertext = ferveoEncrypt(msg, aad, dkg.publicKey());
const ciphertext = ferveoEncrypt(msg, aad, clientAggregate.publicKey);

return {
validatorKeypairs,
Expand Down
3 changes: 2 additions & 1 deletion ferveo-wasm/tests/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ fn setup_dkg(
// In the meantime, the client creates a ciphertext and decryption request
let msg = "my-msg".as_bytes().to_vec();
let aad = "my-aad".as_bytes().to_vec();
let ciphertext = ferveo_encrypt(&msg, &aad, &dkg.public_key()).unwrap();
let ciphertext =
ferveo_encrypt(&msg, &aad, &client_aggregate.public_key()).unwrap();

(
validator_keypairs,
Expand Down
21 changes: 8 additions & 13 deletions ferveo/benches/benchmarks/validity_checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,14 @@ fn setup_dkg(
fn setup(
shares_num: u32,
rng: &mut StdRng,
) -> (PubliclyVerifiableDkg<Bls12_381>, Message<Bls12_381>) {
) -> (
PubliclyVerifiableDkg<Bls12_381>,
PubliclyVerifiableSS<Bls12_381>,
) {
let mut transcripts = vec![];
for i in 0..shares_num {
let mut dkg = setup_dkg(i as usize, shares_num);
transcripts.push(dkg.share(rng).expect("Test failed"));
let dkg = setup_dkg(i as usize, shares_num);
transcripts.push(dkg.generate_transcript(rng).expect("Test failed"));
}
let dkg = setup_dkg(0, shares_num);
let transcript = transcripts[0].clone();
Expand All @@ -78,20 +81,12 @@ pub fn bench_verify_full(c: &mut Criterion) {

let pvss_verify_optimistic = {
move || {
if let Message::Deal(ss) = transcript {
black_box(ss.verify_optimistic());
} else {
panic!("Expected Deal");
}
black_box(transcript.verify_optimistic());
}
};
let pvss_verify_full = {
move || {
if let Message::Deal(ss) = transcript {
black_box(ss.verify_full(&dkg));
} else {
panic!("Expected Deal");
}
black_box(transcript.verify_full(&dkg).unwrap());
}
};

Expand Down
25 changes: 11 additions & 14 deletions ferveo/examples/bench_primitives_size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,18 @@ fn setup(
shares_num: u32,
security_threshold: u32,
rng: &mut StdRng,
) -> PubliclyVerifiableDkg<EllipticCurve> {
) -> (
PubliclyVerifiableDkg<EllipticCurve>,
Vec<PubliclyVerifiableSS<EllipticCurve>>,
) {
let mut transcripts = vec![];
for i in 0..shares_num {
let mut dkg = setup_dkg(i as usize, shares_num, security_threshold);
let message = dkg.share(rng).expect("Test failed");
let sender = dkg.get_validator(&dkg.me.public_key).unwrap();
transcripts.push((sender.clone(), message.clone()));
}

let mut dkg = setup_dkg(0, shares_num, security_threshold);
for (sender, pvss) in transcripts.into_iter() {
dkg.apply_message(&sender, &pvss).expect("Setup failed");
let dkg = setup_dkg(i as usize, shares_num, security_threshold);
let transcript = dkg.generate_transcript(rng).expect("Test failed");
transcripts.push(transcript.clone());
}
dkg
let dkg = setup_dkg(0, shares_num, security_threshold);
(dkg, transcripts)
}

fn main() {
Expand All @@ -128,9 +126,8 @@ fn main() {

for (shares_num, threshold) in configs {
println!("shares_num: {shares_num}, threshold: {threshold}");
let dkg = setup(*shares_num as u32, threshold, rng);
let transcript = &dkg.vss.values().next().unwrap();
let transcript_bytes = bincode::serialize(&transcript).unwrap();
let (_, transcripts) = setup(*shares_num as u32, threshold, rng);
let transcript_bytes = bincode::serialize(&transcripts[0]).unwrap();

save_data(
*shares_num as usize,
Expand Down
Loading

0 comments on commit a9e7f44

Please sign in to comment.