Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove statefullness from DKG instances #183

Merged
merged 6 commits into from
Mar 19, 2024
Merged
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 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
6 changes: 2 additions & 4 deletions ferveo-python/ferveo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@
ValidatorMessage,
FerveoVariant,
ThresholdEncryptionError,
InvalidDkgStateToDeal,
InvalidDkgStateToAggregate,
InvalidDkgStateToVerify,
InvalidDkgStateToIngest,
DealerNotInValidatorSet,
UnknownDealer,
DuplicateDealer,
Expand All @@ -40,4 +36,6 @@
NoTranscriptsToAggregate,
InvalidAggregateVerificationParameters,
UnknownValidator,
TooManyTranscripts,
DuplicateTranscript,
)
24 changes: 5 additions & 19 deletions ferveo-python/ferveo/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class DecryptionSharePrecomputed:

@final
class AggregatedTranscript:
public_key: DkgPublicKey
def __init__(self, messages: Sequence[ValidatorMessage]): ...
def verify(
self, validators_num: int, messages: Sequence[ValidatorMessage]
Expand Down Expand Up @@ -157,18 +158,6 @@ def decrypt_with_shared_secret(
class ThresholdEncryptionError(Exception):
pass

class InvalidDkgStateToDeal(Exception):
pass

class InvalidDkgStateToAggregate(Exception):
pass

class InvalidDkgStateToVerify(Exception):
pass

class InvalidDkgStateToIngest(Exception):
pass

class DealerNotInValidatorSet(Exception):
pass

Expand All @@ -181,12 +170,6 @@ class DuplicateDealer(Exception):
class InvalidPvssTranscript(Exception):
pass

class InsufficientTranscriptsForAggregate(Exception):
pass

class InvalidDkgPublicKey(Exception):
pass

class InsufficientValidators(Exception):
pass

Expand Down Expand Up @@ -220,5 +203,8 @@ class NoTranscriptsToAggregate(Exception):
class InvalidAggregateVerificationParameters(Exception):
pass

class UnknownValidator(Exception):
class TooManyTranscripts(Exception):
pass

class DuplicateTranscript(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
2 changes: 1 addition & 1 deletion ferveo-tdec/benches/tpke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct SetupShared {
shares_num: usize,
msg: Vec<u8>,
aad: Vec<u8>,
pubkey: PublicKeyShare<E>,
pubkey: PublicKey<E>,
privkey: PrivateKeyShare<E>,
ciphertext: Ciphertext<E>,
shared_secret: SharedSecret<E>,
Expand Down
9 changes: 4 additions & 5 deletions ferveo-tdec/src/ciphertext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use sha2::{digest::Digest, Sha256};
use zeroize::ZeroizeOnDrop;

use crate::{
htp_bls12381_g2, Error, PrivateKeyShare, PublicKeyShare, Result, SecretBox,
htp_bls12381_g2, Error, PrivateKeyShare, PublicKey, Result, SecretBox,
SharedSecret,
};

Expand Down Expand Up @@ -98,7 +98,7 @@ impl<E: Pairing> CiphertextHeader<E> {
pub fn encrypt<E: Pairing>(
message: SecretBox<Vec<u8>>,
aad: &[u8],
pubkey: &PublicKeyShare<E>,
pubkey: &PublicKey<E>,
rng: &mut impl rand::Rng,
) -> Result<Ciphertext<E>> {
// r
Expand All @@ -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
6 changes: 3 additions & 3 deletions ferveo-tdec/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ use ark_ec::{pairing::Pairing, CurveGroup};
use crate::{
prepare_combine_simple, BlindedKeyShare, Ciphertext, CiphertextHeader,
DecryptionShareFast, DecryptionSharePrecomputed, DecryptionShareSimple,
PrivateKeyShare, PublicKeyShare, Result,
PrivateKeyShare, PublicKey, Result,
};

#[derive(Clone, Debug)]
pub struct PublicDecryptionContextFast<E: Pairing> {
pub domain: E::ScalarField,
pub public_key_share: PublicKeyShare<E>,
pub public_key: PublicKey<E>,
pub blinded_key_share: BlindedKeyShare<E>,
// This decrypter's contribution to N(0), namely (-1)^|domain| * \prod_i omega_i
pub lagrange_n_0: E::ScalarField,
Expand All @@ -21,7 +21,7 @@ pub struct PublicDecryptionContextFast<E: Pairing> {
#[derive(Clone, Debug)]
pub struct PublicDecryptionContextSimple<E: Pairing> {
pub domain: E::ScalarField,
pub public_key_share: PublicKeyShare<E>,
pub public_key: PublicKey<E>,
pub blinded_key_share: BlindedKeyShare<E>,
pub h: E::G2Affine,
pub validator_public_key: E::G2,
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
27 changes: 12 additions & 15 deletions ferveo-tdec/src/key_share.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use zeroize::{Zeroize, ZeroizeOnDrop};

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

#[derive(Debug, Clone)]
pub struct BlindedKeyShare<E: Pairing> {
Expand All @@ -24,15 +24,14 @@ pub struct BlindedKeyShare<E: Pairing> {
impl<E: Pairing> BlindedKeyShare<E> {
pub fn verify_blinding<R: RngCore>(
&self,
public_key_share: &PublicKeyShare<E>,
public_key: &PublicKey<E>,
rng: &mut R,
) -> bool {
let g = E::G1Affine::generator();
let alpha = E::ScalarField::rand(rng);

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

// \sum_i(Y_i)
let alpha_z = E::G2Prepared::from(
Expand All @@ -56,18 +55,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(),
}
}
}
Loading
Loading