Skip to content

Commit

Permalink
sketch the server api
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-roslaniec committed Feb 2, 2023
1 parent c85ea43 commit 5ba7451
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 38 deletions.
89 changes: 76 additions & 13 deletions ferveo-python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,102 @@ use pyo3::prelude::*;

#[pyclass(module = "ferveo")]
#[derive(Clone, derive_more::From, derive_more::AsRef)]
pub struct ExternalValidator(ferveo::api::ExternalValidator);
pub struct Validator(ferveo::api::Validator);

#[pyclass(module = "ferveo")]
#[derive(Clone, derive_more::From, derive_more::AsRef)]
pub struct Transcript(ferveo::api::Transcript);

#[derive(FromPyObject)]
pub struct ValidatorMessage(Validator, Transcript);

#[pyclass(module = "ferveo")]
#[derive(derive_more::From, derive_more::AsRef)]
pub struct PubliclyVerifiableDkg(ferveo::api::PubliclyVerifiableDkg);
pub struct Dkg(ferveo::api::Dkg);

#[pymethods]
impl PubliclyVerifiableDkg {
impl Dkg {
#[new]
pub fn new(
tau: u64,
shares_num: u32,
security_threshold: u32,
validators: Vec<ExternalValidator>,
me: ExternalValidator,
validators: Vec<Validator>,
me: Validator,
) -> Self {
let validators = validators.into_iter().map(|v| v.0).collect();
let me = me.0;
Self(ferveo::api::PubliclyVerifiableDkg::new(
let validators: Vec<_> = validators.into_iter().map(|v| v.0).collect();
Self(ferveo::api::Dkg::new(
tau,
shares_num,
security_threshold,
validators,
me,
&validators,
&me.0,
))
}

pub fn generate_transcript(&self) -> Transcript {
Transcript(self.0.generate_transcript())
}

pub fn aggregate_transcripts(
&self,
messages: Vec<ValidatorMessage>,
) -> AggregatedTranscript {
let messages = messages
.into_iter()
.map(|message| (message.0 .0, message.1 .0))
.collect();
AggregatedTranscript(self.0.aggregate_transcripts(messages))
}
}

#[pyclass(module = "ferveo")]
#[derive(derive_more::From, derive_more::AsRef)]
pub struct Ciphertext(ferveo::api::Ciphertext);

#[pyclass(module = "ferveo")]
#[derive(derive_more::From, derive_more::AsRef)]
pub struct UnblindingKey(ferveo::api::UnblindingKey);

#[pyclass(module = "ferveo")]
#[derive(derive_more::From, derive_more::AsRef)]
pub struct DecryptionShare(ferveo::api::DecryptionShare);

#[pyclass(module = "ferveo")]
#[derive(derive_more::From, derive_more::AsRef)]
pub struct AggregatedTranscript(ferveo::api::AggregatedTranscript);

#[pymethods]
impl AggregatedTranscript {
pub fn validate(&self, dkg: &Dkg) -> bool {
self.0.validate(&dkg.0)
}

pub fn create_decryption_share(
&self,
dkg: &Dkg,
ciphertext: &Ciphertext,
aad: &[u8],
unblinding_key: &UnblindingKey,
) -> DecryptionShare {
DecryptionShare(self.0.create_decryption_share(
&dkg.0,
&ciphertext.0,
aad,
&unblinding_key.0,
))
}
}

/// A Python module implemented in Rust.
#[pymodule]
fn _ferveo(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<PubliclyVerifiableDkg>()?;
m.add_class::<ExternalValidator>()?;

m.add_class::<Validator>()?;
m.add_class::<Transcript>()?;
m.add_class::<Dkg>()?;
m.add_class::<Ciphertext>()?;
m.add_class::<UnblindingKey>()?;
m.add_class::<DecryptionShare>()?;
m.add_class::<AggregatedTranscript>()?;
Ok(())
}
2 changes: 1 addition & 1 deletion ferveo/benches/benchmarks/validity_checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn setup_dkg(
let validators = gen_validators(&keypairs);
let me = validators[validator].clone();
PubliclyVerifiableDkg::new(
validators,
&validators,
Params {
tau: 0,
security_threshold: shares_num / 3,
Expand Down
2 changes: 1 addition & 1 deletion ferveo/examples/pvdkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn setup_dkg(
let validators = gen_validators(&keypairs);
let me = validators[validator].clone();
PubliclyVerifiableDkg::new(
validators,
&validators,
Params {
tau: 0,
security_threshold: shares_num / 3,
Expand Down
81 changes: 71 additions & 10 deletions ferveo/src/api.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
use ark_poly::EvaluationDomain;
use group_threshold_cryptography as tpke;
use rand::thread_rng;

pub type E = ark_bls12_381::Bls12_381;

#[derive(Clone)]
pub struct ExternalValidator(ferveo_common::ExternalValidator<E>);
pub struct Validator(ferveo_common::ExternalValidator<E>);

pub struct PubliclyVerifiableDkg(crate::PubliclyVerifiableDkg<E>);
#[derive(Clone)]
pub struct Transcript(crate::PubliclyVerifiableSS<E>);

impl PubliclyVerifiableDkg {
#[derive(Clone)]
pub struct Dkg(crate::PubliclyVerifiableDkg<E>);

impl Dkg {
pub fn new(
tau: u64,
shares_num: u32,
security_threshold: u32,
validators: Vec<ExternalValidator>,
me: ExternalValidator,
validators: &[Validator],
me: &Validator,
) -> Self {
let validators = validators
.into_iter()
.map(|v| v.0)
let validators = &validators
.iter()
.map(|v| v.0.clone())
.collect::<Vec<ferveo_common::ExternalValidator<E>>>();
let me = me.0;
let me = &me.0;
let params = crate::Params {
tau,
security_threshold,
Expand All @@ -29,10 +37,63 @@ impl PubliclyVerifiableDkg {
let dkg = crate::PubliclyVerifiableDkg::<E>::new(
validators,
params,
&me,
me,
session_keypair,
)
.unwrap();
Self(dkg)
}

pub fn generate_transcript(&self) -> Transcript {
let rng = &mut thread_rng();
Transcript(self.0.create_share(rng).unwrap())
}

pub fn aggregate_transcripts(
&self,
messages: Vec<(Validator, Transcript)>,
) -> AggregatedTranscript {
// Avoid mutating current state
// TODO: Rewrite `apply_message` to not require mutability after validating this API design
let mut dkg = self.0.clone();
for (validator, transcript) in messages {
dkg.apply_message(validator.0, crate::Message::Deal(transcript.0))
.unwrap();
}

AggregatedTranscript(crate::pvss::aggregate(&self.0))
}
}

pub struct Ciphertext(tpke::api::TpkeCiphertext);

pub struct UnblindingKey(tpke::api::TpkeUnblindingKey);

pub struct DecryptionShare(tpke::api::TpkeDecryptionShareSimplePrecomputed);

pub struct AggregatedTranscript(
crate::PubliclyVerifiableSS<E, crate::Aggregated>,
);

impl AggregatedTranscript {
pub fn validate(&self, dkg: &Dkg) -> bool {
self.0.verify_full(&dkg.0)
}

pub fn create_decryption_share(
&self,
dkg: &Dkg,
ciphertext: &Ciphertext,
aad: &[u8],
unblinding_key: &UnblindingKey,
) -> DecryptionShare {
let domain_points: Vec<_> = dkg.0.domain.elements().collect();
DecryptionShare(self.0.make_decryption_share_simple_precomputed(
&ciphertext.0,
aad,
&unblinding_key.0,
dkg.0.me,
&domain_points,
))
}
}
2 changes: 1 addition & 1 deletion ferveo/src/dkg/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ferveo_common::ExternalValidator;
use itertools::izip;

pub fn make_validators<E: PairingEngine>(
validators: Vec<ExternalValidator<E>>,
validators: &[ExternalValidator<E>],
) -> Vec<ferveo_common::Validator<E>> {
validators
.iter()
Expand Down
24 changes: 18 additions & 6 deletions ferveo/src/dkg/pv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ use ark_ff::Field;
use ark_serialize::*;
use ark_std::{end_timer, start_timer};
use ferveo_common::{ExternalValidator, PublicKey};
use rand::RngCore;
use std::collections::BTreeMap;

/// The DKG context that holds all of the local state for participating in the DKG
#[derive(Debug, CanonicalSerialize, CanonicalDeserialize)]
// TODO: Consider removing Clone to avoid accidentally NOT-mutating state.
// Currently, we're assuming that the DKG is only mutated by the owner of the instance.
// Consider removing Clone after finalizing ferveo::api
#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)]
pub struct PubliclyVerifiableDkg<E: PairingEngine> {
pub params: Params,
pub pvss_params: PubliclyVerifiableParams<E>,
Expand All @@ -30,7 +34,7 @@ impl<E: PairingEngine> PubliclyVerifiableDkg<E> {
/// `me` the validator creating this instance
/// `session_keypair` the keypair for `me`
pub fn new(
validators: Vec<ExternalValidator<E>>,
validators: &[ExternalValidator<E>],
params: Params,
me: &ExternalValidator<E>,
session_keypair: ferveo_common::Keypair<E>,
Expand Down Expand Up @@ -69,10 +73,10 @@ impl<E: PairingEngine> PubliclyVerifiableDkg<E> {
/// Create a new PVSS instance within this DKG session, contributing to the final key
/// `rng` is a cryptographic random number generator
/// Returns a PVSS dealing message to post on-chain
pub fn share<R: Rng>(&mut self, rng: &mut R) -> Result<Message<E>> {
pub fn share<R: RngCore>(&mut self, rng: &mut R) -> Result<Message<E>> {
use ark_std::UniformRand;
print_time!("PVSS Sharing");
let vss = Pvss::<E>::new(&E::Fr::rand(rng), self, rng)?;
let vss = self.create_share(rng)?;
match self.state {
DkgState::Sharing { .. } | DkgState::Dealt => {
Ok(Message::Deal(vss))
Expand All @@ -83,6 +87,14 @@ impl<E: PairingEngine> PubliclyVerifiableDkg<E> {
}
}

pub fn create_share<R: RngCore>(
&self,
rng: &mut R,
) -> Result<PubliclyVerifiableSS<E>> {
use ark_std::UniformRand;
Pvss::<E>::new(&E::Fr::rand(rng), self, rng)
}

/// Aggregate all received PVSS messages into a single message, prepared to post on-chain
pub fn aggregate(&self) -> Result<Message<E>> {
match self.state {
Expand Down Expand Up @@ -278,7 +290,7 @@ pub(crate) mod test_common {
let validators = gen_n_validators(&keypairs, shares_num);
let me = validators[my_index].clone();
PubliclyVerifiableDkg::new(
validators,
&validators,
Params {
tau: 0,
security_threshold,
Expand Down Expand Up @@ -348,7 +360,7 @@ mod test_dkg_init {
let keypairs = gen_keypairs();
let keypair = ferveo_common::Keypair::<EllipticCurve>::new(rng);
let err = PubliclyVerifiableDkg::<EllipticCurve>::new(
gen_validators(&keypairs),
&gen_validators(&keypairs),
Params {
tau: 0,
security_threshold: 4,
Expand Down
3 changes: 2 additions & 1 deletion ferveo/src/vss/pvss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use group_threshold_cryptography::{
DecryptionShareSimple, DecryptionShareSimplePrecomputed, PrivateKeyShare,
};
use itertools::{zip_eq, Itertools};
use rand::RngCore;
use subproductdomain::fast_multiexp;

/// These are the blinded evaluations of shares of a single random polynomial
Expand Down Expand Up @@ -70,7 +71,7 @@ impl<E: PairingEngine, T> PubliclyVerifiableSS<E, T> {
/// `s`: the secret constant coefficient to share
/// `dkg`: the current DKG session
/// `rng` a cryptographic random number generator
pub fn new<R: Rng>(
pub fn new<R: RngCore>(
s: &E::Fr,
dkg: &PubliclyVerifiableDkg<E>,
rng: &mut R,
Expand Down
2 changes: 1 addition & 1 deletion tpke-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ pub struct SharedSecret(TpkeSharedSecret);
#[wasm_bindgen]
#[derive(Clone, Debug)]
pub struct SharedSecretBuilder {
shares: Vec<TpkeDecryptionShare>,
shares: Vec<TpkeDecryptionShareFast>,
contexts: Vec<TpkePublicDecryptionContext>,
}

Expand Down
11 changes: 7 additions & 4 deletions tpke/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ use std::convert::TryInto;
pub type E = ark_bls12_381::Bls12_381;
pub type TpkePublicKey = ark_bls12_381::G1Affine;
pub type TpkePrivateKey = ark_bls12_381::G2Affine;
pub type TpkeUnblindingKey = ark_bls12_381::Fr;
pub type TpkeCiphertext = crate::Ciphertext<E>;
pub type TpkeDecryptionShare = crate::DecryptionShareFast<E>;
pub type TpkeDecryptionShareFast = crate::DecryptionShareFast<E>;
pub type TpkeDecryptionShareSimplePrecomputed =
crate::DecryptionShareSimplePrecomputed<E>;
pub type TpkePublicDecryptionContext = crate::PublicDecryptionContextFast<E>;
pub type TpkeSharedSecret =
<ark_bls12_381::Bls12_381 as ark_ec::PairingEngine>::Fqk;
Expand Down Expand Up @@ -99,15 +102,15 @@ impl PrivateDecryptionContext {
}

#[derive(Clone, Debug)]
pub struct DecryptionShare(pub TpkeDecryptionShare);
pub struct DecryptionShare(pub TpkeDecryptionShareFast);

impl DecryptionShare {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes()
}

pub fn from_bytes(bytes: &[u8]) -> Self {
let share = TpkeDecryptionShare::from_bytes(bytes);
let share = TpkeDecryptionShareFast::from_bytes(bytes);
Self(share)
}
}
Expand Down Expand Up @@ -162,7 +165,7 @@ impl ParticipantPayload {
.mul(self.decryption_context.b_inv)
.into_affine();

DecryptionShare(TpkeDecryptionShare {
DecryptionShare(TpkeDecryptionShareFast {
decrypter_index: self.decryption_context.decrypter_index,
decryption_share,
})
Expand Down

0 comments on commit 5ba7451

Please sign in to comment.