Skip to content

Commit

Permalink
Stuff works
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Dec 1, 2024
1 parent b5a62ab commit 2d05f4f
Show file tree
Hide file tree
Showing 20 changed files with 578 additions and 190 deletions.
2 changes: 1 addition & 1 deletion synedrion/src/cggmp21/aux_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ impl<P: SchemeParams, I: PartyId> Round3<P, I> {

let pi = SchProof::new(
&context.tau_y,
context.y.expose_secret(),
&context.y,
&context.data_precomp.data.cap_b,
&context.data_precomp.data.cap_y,
&aux,
Expand Down
92 changes: 48 additions & 44 deletions synedrion/src/cggmp21/interactive_signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize};

use super::{
entities::{AuxInfo, AuxInfoPrecomputed, KeyShare, PresigningData, PresigningValues},
params::SchemeParams,
params::{secret_scalar_from_signed, secret_signed_from_scalar, secret_uint_from_scalar, SchemeParams},
sigma::{AffGProof, DecProof, EncProof, LogStarProof, MulProof, MulStarProof},
};
use crate::{
Expand Down Expand Up @@ -160,10 +160,10 @@ impl<P: SchemeParams, I: PartyId> EntryPoint<I> for InteractiveSigning<P, I> {
let pk = aux_info.secret_aux.paillier_sk.public_key();

let nu = Randomizer::<P::Paillier>::random(rng, pk);
let cap_g = Ciphertext::new_with_randomizer(pk, &P::uint_from_scalar(gamma.expose_secret()), &nu.to_wire());
let cap_g = Ciphertext::new_with_randomizer(pk, &secret_uint_from_scalar::<P>(&gamma), &nu.to_wire());

let rho = Randomizer::<P::Paillier>::random(rng, pk);
let cap_k = Ciphertext::new_with_randomizer(pk, &P::uint_from_scalar(k.expose_secret()), &rho.to_wire());
let cap_k = Ciphertext::new_with_randomizer(pk, &secret_uint_from_scalar::<P>(&k), &rho.to_wire());

Ok(BoxedRound::new_dynamic(Round1 {
context: Context {
Expand Down Expand Up @@ -267,7 +267,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round1<P, I> {
let aux = (&self.context.ssid_hash, &destination);
let psi0 = EncProof::new(
rng,
&P::signed_from_scalar(self.context.k.expose_secret()),
&secret_signed_from_scalar::<P>(&self.context.k),
&self.context.rho,
self.context.aux_info.secret_aux.paillier_sk.public_key(),
&self.cap_k,
Expand Down Expand Up @@ -446,21 +446,24 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {
let hat_r = Randomizer::random(rng, pk);
let hat_s = Randomizer::random(rng, target_pk);

let cap_f = Ciphertext::new_with_randomizer_signed(pk, beta.expose_secret(), &r.to_wire());
let cap_d = &self.all_cap_k[destination] * P::signed_from_scalar(self.context.gamma.expose_secret())
+ Ciphertext::new_with_randomizer_signed(target_pk, &-beta.expose_secret(), &s.to_wire());
let gamma = secret_signed_from_scalar::<P>(&self.context.gamma);
let x = secret_signed_from_scalar::<P>(&self.context.key_share.secret_share);

let hat_cap_f = Ciphertext::new_with_randomizer_signed(pk, hat_beta.expose_secret(), &hat_r.to_wire());
let cap_f = Ciphertext::new_with_randomizer_signed(pk, &beta, &r.to_wire());
let cap_d = &self.all_cap_k[destination] * &gamma
+ Ciphertext::new_with_randomizer_signed(target_pk, &-&beta, &s.to_wire());

let hat_cap_f = Ciphertext::new_with_randomizer_signed(pk, &hat_beta, &hat_r.to_wire());
let hat_cap_d = &self.all_cap_k[destination]
* P::signed_from_scalar(self.context.key_share.secret_share.expose_secret())
+ Ciphertext::new_with_randomizer_signed(target_pk, &-hat_beta.expose_secret(), &hat_s.to_wire());
+ Ciphertext::new_with_randomizer_signed(target_pk, &-&hat_beta, &hat_s.to_wire());

let public_aux = &self.context.aux_info.public_aux[destination];
let rp = &public_aux.rp_params;

let psi = AffGProof::new(
rng,
&P::signed_from_scalar(self.context.gamma.expose_secret()),
&gamma,
&beta,
s.clone(),
r.clone(),
Expand All @@ -476,7 +479,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {

let hat_psi = AffGProof::new(
rng,
&P::signed_from_scalar(self.context.key_share.secret_share.expose_secret()),
&x,
&hat_beta,
hat_s.clone(),
hat_r.clone(),
Expand All @@ -492,7 +495,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {

let hat_psi_prime = LogStarProof::new(
rng,
&P::signed_from_scalar(self.context.gamma.expose_secret()),
&gamma,
&self.context.nu,
pk,
&self.all_cap_g[&self.context.my_id],
Expand Down Expand Up @@ -638,18 +641,18 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {

let alpha_sum: Signed<_> = payloads.values().map(|p| p.alpha).sum();
let beta_sum: Signed<_> = artifacts.values().map(|p| p.beta.expose_secret()).sum();
let delta = P::signed_from_scalar(self.context.gamma.expose_secret())
* P::signed_from_scalar(self.context.k.expose_secret())
+ alpha_sum
+ beta_sum;
let delta = secret_signed_from_scalar::<P>(&self.context.gamma)
* secret_signed_from_scalar::<P>(&self.context.k)
+ &alpha_sum
+ &beta_sum;

let hat_alpha_sum: Signed<_> = payloads.values().map(|payload| payload.hat_alpha).sum();
let hat_beta_sum: Signed<_> = artifacts
.values()
.map(|artifact| artifact.hat_beta.expose_secret())
.sum();
let chi = Secret::init_with(|| P::signed_from_scalar(self.context.key_share.secret_share.expose_secret()))
* Secret::init_with(|| P::signed_from_scalar(self.context.k.expose_secret()))
let chi = secret_signed_from_scalar::<P>(&self.context.key_share.secret_share)
* secret_signed_from_scalar::<P>(&self.context.k)
+ &hat_alpha_sum
+ &hat_beta_sum;

Expand All @@ -676,7 +679,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {
#[derive(Debug)]
struct Round3<P: SchemeParams, I: Ord> {
context: Context<P, I>,
delta: Signed<<P::Paillier as PaillierParams>::Uint>,
delta: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
chi: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
cap_delta: Point,
cap_gamma: Point,
Expand All @@ -691,13 +694,13 @@ struct Round3<P: SchemeParams, I: Ord> {
#[serde(bound(serialize = "LogStarProof<P>: Serialize"))]
#[serde(bound(deserialize = "LogStarProof<P>: for<'x> Deserialize<'x>"))]
struct Round3Message<P: SchemeParams> {
delta: Scalar,
delta: Secret<Scalar>,
cap_delta: Point,
psi_pprime: LogStarProof<P>,
}

struct Round3Payload {
delta: Scalar,
delta: Secret<Scalar>,
cap_delta: Point,
}

Expand Down Expand Up @@ -734,7 +737,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {

let psi_pprime = LogStarProof::new(
rng,
&P::signed_from_scalar(self.context.k.expose_secret()),
&secret_signed_from_scalar::<P>(&self.context.k),
&self.context.rho,
pk,
&self.all_cap_k[&self.context.my_id],
Expand All @@ -747,7 +750,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {
let dm = DirectMessage::new(
serializer,
Round3Message::<P> {
delta: P::scalar_from_signed(&self.delta),
delta: secret_scalar_from_signed::<P>(&self.delta),
cap_delta: self.cap_delta,
psi_pprime,
},
Expand Down Expand Up @@ -806,19 +809,20 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {
.map(|(id, payload)| ((id.clone(), payload.delta), (id, payload.cap_delta)))
.unzip();

let scalar_delta = P::scalar_from_signed(&self.delta);
let assembled_delta: Scalar = scalar_delta + deltas.values().sum::<Scalar>();
let assembled_cap_delta: Point = self.cap_delta + cap_deltas.values().sum::<Point>();

if assembled_delta.mul_by_generator() == assembled_cap_delta {
let inv_delta: Scalar = Option::from(assembled_delta.invert()).ok_or_else(|| {
LocalError::new(concat![
"The assembled delta is zero. ",
"Either all other nodes are malicious, or it's a freak accident. ",
"Restart the protocol."
])
})?;
let nonce = (self.cap_gamma * inv_delta).x_coordinate();
let scalar_delta = secret_scalar_from_signed::<P>(&self.delta);
let assembled_delta: Secret<Scalar> = &scalar_delta + deltas.values().sum::<Secret<Scalar>>();
let assembled_cap_delta: Point = self.cap_delta + cap_deltas.values().sum();

if assembled_delta.expose_secret().mul_by_generator() == assembled_cap_delta {
let inv_delta = Secret::try_init_with(|| Option::from(assembled_delta.expose_secret().invert()).ok_or(()))
.map_err(|_err| {
LocalError::new(concat![
"The assembled delta is zero. ",
"Either all other nodes are malicious, or it's a freak accident. ",
"Restart the protocol."
])

Check warning on line 823 in synedrion/src/cggmp21/interactive_signing.rs

View check run for this annotation

Codecov / codecov/patch

synedrion/src/cggmp21/interactive_signing.rs#L819-L823

Added lines #L819 - L823 were not covered by tests
})?;
let nonce = (self.cap_gamma * inv_delta.expose_secret()).x_coordinate();
let my_id = self.context.my_id.clone();

let values = self
Expand Down Expand Up @@ -879,7 +883,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {

let p_aff_g = AffGProof::<P>::new(
rng,
&P::signed_from_scalar(self.context.gamma.expose_secret()),
&secret_signed_from_scalar::<P>(&self.context.gamma),

Check warning on line 886 in synedrion/src/cggmp21/interactive_signing.rs

View check run for this annotation

Codecov / codecov/patch

synedrion/src/cggmp21/interactive_signing.rs#L886

Added line #L886 was not covered by tests
beta,
s.to_precomputed(target_pk),
r.to_precomputed(pk),

Check warning on line 889 in synedrion/src/cggmp21/interactive_signing.rs

View check run for this annotation

Codecov / codecov/patch

synedrion/src/cggmp21/interactive_signing.rs#L888-L889

Added lines #L888 - L889 were not covered by tests
Expand Down Expand Up @@ -916,7 +920,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {

let p_mul = MulProof::<P>::new(
rng,
&P::signed_from_scalar(self.context.k.expose_secret()),
&secret_signed_from_scalar::<P>(&self.context.k),

Check warning on line 923 in synedrion/src/cggmp21/interactive_signing.rs

View check run for this annotation

Codecov / codecov/patch

synedrion/src/cggmp21/interactive_signing.rs#L923

Added line #L923 was not covered by tests
&self.context.rho,
&rho,
pk,
Expand Down Expand Up @@ -958,14 +962,14 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {
&self.delta,
&rho,
pk,
&scalar_delta,
scalar_delta.expose_secret(),

Check warning on line 965 in synedrion/src/cggmp21/interactive_signing.rs

View check run for this annotation

Codecov / codecov/patch

synedrion/src/cggmp21/interactive_signing.rs#L965

Added line #L965 was not covered by tests
&ciphertext,
&self.context.aux_info.public_aux[id_j].rp_params,
&aux,
);
assert!(p_dec.verify(
pk,
&scalar_delta,
scalar_delta.expose_secret(),

Check warning on line 972 in synedrion/src/cggmp21/interactive_signing.rs

View check run for this annotation

Codecov / codecov/patch

synedrion/src/cggmp21/interactive_signing.rs#L972

Added line #L972 was not covered by tests
&ciphertext,
&self.context.aux_info.public_aux[id_j].rp_params,
&aux
Expand Down Expand Up @@ -1105,7 +1109,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round4<P, I> {

let p_aff_g = AffGProof::<P>::new(
rng,
&P::signed_from_scalar(self.context.key_share.secret_share.expose_secret()),
&secret_signed_from_scalar::<P>(&self.context.key_share.secret_share),
&values.hat_beta,
values.hat_s.to_precomputed(target_pk),
values.hat_r.to_precomputed(pk),
Expand Down Expand Up @@ -1150,7 +1154,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round4<P, I> {
for id_l in self.context.other_ids.iter() {
let p_mul = MulStarProof::<P>::new(
rng,
&P::signed_from_scalar(x.expose_secret()),
&secret_signed_from_scalar::<P>(x),
&rho,
pk,
&self.presigning.cap_k,
Expand Down Expand Up @@ -1192,9 +1196,9 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round4<P, I> {
let rho = ciphertext.derive_randomizer(sk);
// This is the same as `s_part` but if all the calculations were performed
// without reducing modulo curve order.
let s_part_nonreduced = P::signed_from_scalar(self.presigning.ephemeral_scalar_share.expose_secret())
let s_part_nonreduced = secret_signed_from_scalar::<P>(&self.presigning.ephemeral_scalar_share)
* P::signed_from_scalar(&self.context.message)
+ *self.presigning.product_share_nonreduced.expose_secret() * P::signed_from_scalar(&r);
+ self.presigning.product_share_nonreduced.clone() * P::signed_from_scalar(&r);

let mut dec_proofs = Vec::new();
for id_l in self.context.other_ids.iter() {
Expand Down
2 changes: 1 addition & 1 deletion synedrion/src/cggmp21/key_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {
let aux = (&self.context.sid_hash, &self.context.my_id, &self.rid);
let psi = SchProof::new(
&self.context.tau,
self.context.x.expose_secret(),
&self.context.x,
&self.context.public_data.cap_a,
&self.context.public_data.cap_x,
&aux,
Expand Down
8 changes: 4 additions & 4 deletions synedrion/src/cggmp21/key_refresh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use serde::{Deserialize, Serialize};

use super::{
entities::{AuxInfo, KeyShareChange, PublicAuxInfo, SecretAuxInfo},
params::SchemeParams,
params::{secret_uint_from_scalar, SchemeParams},
sigma::{FacProof, ModProof, PrmProof, SchCommitment, SchProof, SchSecret},
};
use crate::{
Expand Down Expand Up @@ -540,7 +540,7 @@ impl<P: SchemeParams, I: PartyId> Round3<P, I> {

let pi = SchProof::new(
&context.tau_y,
context.y.expose_secret(),
&context.y,
&context.data_precomp.data.cap_b,
&context.data_precomp.data.cap_y,
&aux,
Expand Down Expand Up @@ -609,11 +609,11 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {

let x_secret = &self.context.x_to_send[destination];
let x_public = self.context.data_precomp.data.cap_x_to_send[destination_idx];
let ciphertext = Ciphertext::new(rng, &data.paillier_pk, &P::uint_from_scalar(x_secret.expose_secret()));
let ciphertext = Ciphertext::new(rng, &data.paillier_pk, &secret_uint_from_scalar::<P>(x_secret));

let psi_sch = SchProof::new(
&self.context.tau_x[destination],
x_secret.expose_secret(),
&x_secret,
&self.context.data_precomp.data.cap_a_to_send[destination_idx],
&x_public,
&aux,
Expand Down
48 changes: 47 additions & 1 deletion synedrion/src/cggmp21/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ use core::fmt::Debug;
// So as long as that is the case, `k256` `Uint` is separate
// from the one used throughout the crate.
use k256::elliptic_curve::bigint::Uint as K256Uint;
use secrecy::{ExposeSecret, ExposeSecretMut};
use serde::{Deserialize, Serialize};
use zeroize::Zeroize;

use crate::{
curve::{Curve, Scalar, ORDER},
paillier::PaillierParams,
tools::hashing::{Chain, HashableType},
tools::{
hashing::{Chain, HashableType},
Secret,
},
uint::{
subtle::ConditionallySelectable, Bounded, Encoding, NonZero, Signed, U1024Mod, U2048Mod, U4096Mod, U512Mod,
Uint, Zero, U1024, U2048, U4096, U512, U8192,
Expand Down Expand Up @@ -192,6 +197,47 @@ pub trait SchemeParams: Debug + Clone + Send + PartialEq + Eq + Send + Sync + 's
}
}

pub(crate) fn secret_uint_from_scalar<P: SchemeParams>(
value: &Secret<Scalar>,
) -> Secret<<P::Paillier as PaillierParams>::Uint> {
let scalar_bytes = Secret::init_with(|| value.expose_secret().to_bytes());
let mut repr = Secret::init_with(|| <P::Paillier as PaillierParams>::Uint::zero().to_be_bytes());

let uint_len = repr.expose_secret().as_ref().len();
let scalar_len = scalar_bytes.expose_secret().len();

debug_assert!(uint_len >= scalar_len);
repr.expose_secret_mut().as_mut()[uint_len - scalar_len..].copy_from_slice(scalar_bytes.expose_secret());
Secret::init_with(|| {
let mut repr = repr.expose_secret().clone();
let result = <P::Paillier as PaillierParams>::Uint::from_be_bytes(repr);
repr.zeroize();
result
})
}

pub(crate) fn secret_signed_from_scalar<P: SchemeParams>(
value: &Secret<Scalar>,
) -> Secret<Signed<<P::Paillier as PaillierParams>::Uint>> {
Secret::init_with(|| {
let mut uint = secret_uint_from_scalar::<P>(value).expose_secret().clone();
let result = Signed::new_positive(uint, ORDER.bits_vartime() as u32).expect(concat![
"a curve scalar value is smaller than the curve order, ",
"and the curve order fits in `PaillierParams::Uint`"
]);
uint.zeroize();
result
})
}

pub(crate) fn secret_scalar_from_signed<P: SchemeParams>(
value: &Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
) -> Secret<Scalar> {
// TODO: wrap in secrets properly
let abs_value = P::scalar_from_uint(&value.expose_secret().abs());
Secret::init_with(|| Scalar::conditional_select(&abs_value, &-abs_value, value.expose_secret().is_negative()))
}

impl<P: SchemeParams> HashableType for P {
fn chain_type<C: Chain>(digest: C) -> C {
digest.chain_type::<Curve>()
Expand Down
Loading

0 comments on commit 2d05f4f

Please sign in to comment.