Skip to content

Commit

Permalink
Split Signed/Bounded into SecretSigned/PublicSigned/SecretUnsigned
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Dec 13, 2024
1 parent 4c04dcf commit 0b9eba1
Show file tree
Hide file tree
Showing 28 changed files with 1,770 additions and 1,885 deletions.
6 changes: 3 additions & 3 deletions synedrion/src/cggmp21/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
SecretKeyPaillier, SecretKeyPaillierWire,
},
tools::Secret,
uint::Signed,
uint::SecretSigned,
};

/// The result of the KeyInit protocol.
Expand Down Expand Up @@ -101,7 +101,7 @@ pub(crate) struct PresigningData<P: SchemeParams, I> {

// Values generated during presigning,
// kept in case we need to generate a proof of correctness.
pub(crate) product_share_nonreduced: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
pub(crate) product_share_nonreduced: SecretSigned<<P::Paillier as PaillierParams>::Uint>,

// $K_i$.
pub(crate) cap_k: Ciphertext<P::Paillier>,
Expand All @@ -112,7 +112,7 @@ pub(crate) struct PresigningData<P: SchemeParams, I> {

#[derive(Debug, Clone)]
pub(crate) struct PresigningValues<P: SchemeParams> {
pub(crate) hat_beta: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
pub(crate) hat_beta: SecretSigned<<P::Paillier as PaillierParams>::Uint>,
pub(crate) hat_r: Randomizer<P::Paillier>,
pub(crate) hat_s: Randomizer<P::Paillier>,
pub(crate) cap_k: Ciphertext<P::Paillier>,
Expand Down
63 changes: 28 additions & 35 deletions synedrion/src/cggmp21/interactive_signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use serde::{Deserialize, Serialize};
use super::{
entities::{AuxInfo, AuxInfoPrecomputed, KeyShare, PresigningData, PresigningValues},
params::{
bounded_from_scalar, secret_bounded_from_scalar, secret_scalar_from_signed, secret_signed_from_scalar,
secret_uint_from_scalar, signed_from_scalar, SchemeParams,
public_signed_from_scalar, secret_scalar_from_signed, secret_signed_from_scalar, secret_unsigned_from_scalar,
SchemeParams,
},
sigma::{AffGProof, DecProof, EncProof, LogStarProof, MulProof, MulStarProof},
};
Expand All @@ -32,7 +32,7 @@ use crate::{
hashing::{Chain, FofHasher, HashOutput},
DowncastMap, Secret, Without,
},
uint::Signed,
uint::SecretSigned,
};

/// A protocol for creating all the data necessary for signing
Expand Down Expand Up @@ -162,10 +162,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, &secret_uint_from_scalar::<P>(&gamma), &nu);
let cap_g = Ciphertext::new_with_randomizer(pk, &secret_unsigned_from_scalar::<P>(&gamma), &nu);

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

Ok(BoxedRound::new_dynamic(Round1 {
context: Context {
Expand Down Expand Up @@ -389,8 +389,8 @@ struct Round2Message<P: SchemeParams> {

#[derive(Debug, Clone)]
struct Round2Artifact<P: SchemeParams> {
beta: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
hat_beta: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
beta: SecretSigned<<P::Paillier as PaillierParams>::Uint>,
hat_beta: SecretSigned<<P::Paillier as PaillierParams>::Uint>,
r: Randomizer<P::Paillier>,
s: Randomizer<P::Paillier>,
hat_r: Randomizer<P::Paillier>,
Expand All @@ -403,8 +403,8 @@ struct Round2Artifact<P: SchemeParams> {

struct Round2Payload<P: SchemeParams> {
cap_gamma: Point,
alpha: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
hat_alpha: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
alpha: SecretSigned<<P::Paillier as PaillierParams>::Uint>,
hat_alpha: SecretSigned<<P::Paillier as PaillierParams>::Uint>,
cap_d: Ciphertext<P::Paillier>,
hat_cap_d: Ciphertext<P::Paillier>,
}
Expand Down Expand Up @@ -441,8 +441,8 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {

let target_pk = &self.context.aux_info.public_aux[destination].paillier_pk;

let beta = Secret::init_with(|| Signed::random_bounded_bits(rng, P::LP_BOUND));
let hat_beta = Secret::init_with(|| Signed::random_bounded_bits(rng, P::LP_BOUND));
let beta = SecretSigned::random_in_exp_range(rng, P::LP_BOUND);
let hat_beta = SecretSigned::random_in_exp_range(rng, P::LP_BOUND);
let r = Randomizer::random(rng, pk);
let s = Randomizer::random(rng, target_pk);
let hat_r = Randomizer::random(rng, pk);
Expand Down Expand Up @@ -611,18 +611,10 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {
// `alpha == x * y + z` where `0 <= x, y < q`, and `-2^l' <= z <= 2^l'`,
// where `q` is the curve order.
// We will need this bound later, so we're asserting it.
let alpha = Secret::try_init_with(|| {
alpha
.expose_secret()
.assert_bit_bound(core::cmp::max(2 * P::L_BOUND, P::LP_BOUND) + 1)
.ok_or_else(|| ReceiveError::protocol(InteractiveSigningError::OutOfBoundsAlpha))
})?;
let hat_alpha = Secret::try_init_with(|| {
hat_alpha
.expose_secret()
.assert_bit_bound(core::cmp::max(2 * P::L_BOUND, P::LP_BOUND) + 1)
.ok_or_else(|| ReceiveError::protocol(InteractiveSigningError::OutOfBoundsHatAlpha))
})?;
let alpha = Option::from(alpha.ensure_bound(core::cmp::max(2 * P::L_BOUND, P::LP_BOUND) + 1))
.ok_or_else(|| ReceiveError::protocol(InteractiveSigningError::OutOfBoundsAlpha))?;
let hat_alpha = Option::from(hat_alpha.ensure_bound(core::cmp::max(2 * P::L_BOUND, P::LP_BOUND) + 1))
.ok_or_else(|| ReceiveError::protocol(InteractiveSigningError::OutOfBoundsHatAlpha))?;

Ok(Payload::new(Round2Payload::<P> {
cap_gamma: direct_message.cap_gamma,
Expand All @@ -647,15 +639,15 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {

let cap_delta = cap_gamma * &self.context.k;

let alpha_sum: Secret<Signed<_>> = payloads.values().map(|payload| &payload.alpha).sum();
let beta_sum: Secret<Signed<_>> = artifacts.values().map(|artifact| &artifact.beta).sum();
let alpha_sum: SecretSigned<_> = payloads.values().map(|payload| &payload.alpha).sum();
let beta_sum: SecretSigned<_> = artifacts.values().map(|artifact| &artifact.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: Secret<Signed<_>> = payloads.values().map(|payload| &payload.hat_alpha).sum();
let hat_beta_sum: Secret<Signed<_>> = artifacts.values().map(|artifact| &artifact.hat_beta).sum();
let hat_alpha_sum: SecretSigned<_> = payloads.values().map(|payload| &payload.hat_alpha).sum();
let hat_beta_sum: SecretSigned<_> = artifacts.values().map(|artifact| &artifact.hat_beta).sum();
let chi = secret_signed_from_scalar::<P>(&self.context.key_share.secret_share)
* secret_signed_from_scalar::<P>(&self.context.k)
+ &hat_alpha_sum
Expand Down Expand Up @@ -684,8 +676,8 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {
#[derive(Debug)]
struct Round3<P: SchemeParams, I: Ord> {
context: Context<P, I>,
delta: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
chi: Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
delta: SecretSigned<<P::Paillier as PaillierParams>::Uint>,
chi: SecretSigned<<P::Paillier as PaillierParams>::Uint>,
cap_delta: Point,
cap_gamma: Point,
all_cap_k: BTreeMap<I, Ciphertext<P::Paillier>>,
Expand Down Expand Up @@ -919,7 +911,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {
// Mul proof

let rho = Randomizer::random(rng, pk);
let cap_h = (&self.all_cap_g[&self.context.my_id] * secret_bounded_from_scalar::<P>(&self.context.k))
let cap_h = (&self.all_cap_g[&self.context.my_id] * secret_signed_from_scalar::<P>(&self.context.k))

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

View check run for this annotation

Codecov / codecov/patch

synedrion/src/cggmp21/interactive_signing.rs#L914

Added line #L914 was not covered by tests
.mul_randomizer(&rho);

let p_mul = MulProof::<P>::new(
Expand Down Expand Up @@ -1148,7 +1140,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round4<P, I> {
let cap_x = self.context.key_share.public_shares[&my_id];

let rho = Randomizer::random(rng, pk);
let hat_cap_h = (&self.presigning.cap_k * secret_bounded_from_scalar::<P>(x)).mul_randomizer(&rho);
let hat_cap_h = (&self.presigning.cap_k * secret_signed_from_scalar::<P>(x)).mul_randomizer(&rho);

let aux = (&self.context.ssid_hash, &my_id);

Expand Down Expand Up @@ -1192,16 +1184,17 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round4<P, I> {
}

let r = self.presigning.nonce;
let signed_r = public_signed_from_scalar::<P>(&r);
let signed_message = public_signed_from_scalar::<P>(&self.context.message);

let ciphertext = ciphertext * bounded_from_scalar::<P>(&r)
+ &self.presigning.cap_k * bounded_from_scalar::<P>(&self.context.message);
let ciphertext = ciphertext * &signed_r + &self.presigning.cap_k * &signed_message;

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 = secret_signed_from_scalar::<P>(&self.presigning.ephemeral_scalar_share)
* signed_from_scalar::<P>(&self.context.message)
+ self.presigning.product_share_nonreduced.clone() * signed_from_scalar::<P>(&r);
* signed_message
+ &self.presigning.product_share_nonreduced * signed_r;

let mut dec_proofs = Vec::new();
for id_l in self.context.other_ids.iter() {
Expand Down
4 changes: 2 additions & 2 deletions synedrion/src/cggmp21/key_refresh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use serde::{Deserialize, Serialize};

use super::{
entities::{AuxInfo, KeyShareChange, PublicAuxInfo, SecretAuxInfo},
params::{secret_scalar_from_uint, secret_uint_from_scalar, SchemeParams},
params::{secret_scalar_from_uint, secret_unsigned_from_scalar, SchemeParams},
sigma::{FacProof, ModProof, PrmProof, SchCommitment, SchProof, SchSecret},
};
use crate::{
Expand Down Expand Up @@ -605,7 +605,7 @@ 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, &secret_uint_from_scalar::<P>(x_secret));
let ciphertext = Ciphertext::new(rng, &data.paillier_pk, &secret_unsigned_from_scalar::<P>(x_secret));

let psi_sch = SchProof::new(
&self.context.tau_x[destination],
Expand Down
83 changes: 36 additions & 47 deletions synedrion/src/cggmp21/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use core::fmt::Debug;
// and `k256` depends on the released one.
// So as long as that is the case, `k256` `Uint` is separate
// from the one used throughout the crate.
use crypto_bigint::{Encoding, NonZero, Uint, Zero, U1024, U2048, U4096, U512, U8192};
use k256::elliptic_curve::bigint::Uint as K256Uint;
use serde::{Deserialize, Serialize};

Expand All @@ -14,10 +15,7 @@ use crate::{
hashing::{Chain, HashableType},
Secret,
},
uint::{
subtle::ConditionallySelectable, Bounded, Encoding, NonZero, Signed, U1024Mod, U2048Mod, U4096Mod, U512Mod,
Uint, Zero, U1024, U2048, U4096, U512, U8192,
},
uint::{PublicSigned, SecretSigned, SecretUnsigned, U1024Mod, U2048Mod, U4096Mod, U512Mod},
};

#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand Down Expand Up @@ -141,17 +139,11 @@ pub(crate) fn uint_from_scalar<P: SchemeParams>(value: &Scalar) -> <P::Paillier
<P::Paillier as PaillierParams>::Uint::from_be_bytes(repr)
}

/// Converts a curve scalar to the associated integer type, wrapped in `Bounded`.
pub(crate) fn bounded_from_scalar<P: SchemeParams>(value: &Scalar) -> Bounded<<P::Paillier as PaillierParams>::Uint> {
Bounded::new(uint_from_scalar::<P>(value), 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`"
])
}

/// Converts a curve scalar to the associated integer type, wrapped in `Signed`.
pub(crate) fn signed_from_scalar<P: SchemeParams>(value: &Scalar) -> Signed<<P::Paillier as PaillierParams>::Uint> {
bounded_from_scalar::<P>(value).into_signed().expect(concat![
pub(crate) fn public_signed_from_scalar<P: SchemeParams>(
value: &Scalar,
) -> PublicSigned<<P::Paillier as PaillierParams>::Uint> {
PublicSigned::new_positive(uint_from_scalar::<P>(value), ORDER.bits_vartime() as u32).expect(concat![
"a curve scalar value is smaller than the half of `PaillierParams::Uint` range, ",
"so it is still positive when treated as a 2-complement signed value"
])
Expand All @@ -171,9 +163,15 @@ pub(crate) fn scalar_from_uint<P: SchemeParams>(value: &<P::Paillier as Paillier
}

/// Converts a `Signed`-wrapped integer to the associated curve scalar type.
pub(crate) fn scalar_from_signed<P: SchemeParams>(value: &Signed<<P::Paillier as PaillierParams>::Uint>) -> Scalar {
pub(crate) fn scalar_from_signed<P: SchemeParams>(
value: &PublicSigned<<P::Paillier as PaillierParams>::Uint>,
) -> Scalar {
let abs_value = scalar_from_uint::<P>(&value.abs());
Scalar::conditional_select(&abs_value, &-abs_value, value.is_negative())
if value.is_negative() {
-abs_value
} else {
abs_value
}
}

/// Converts a wide integer to the associated curve scalar type.
Expand All @@ -191,10 +189,14 @@ pub(crate) fn scalar_from_wide_uint<P: SchemeParams>(value: &<P::Paillier as Pai

/// Converts a `Signed`-wrapped wide integer to the associated curve scalar type.
pub(crate) fn scalar_from_wide_signed<P: SchemeParams>(
value: &Signed<<P::Paillier as PaillierParams>::WideUint>,
value: &PublicSigned<<P::Paillier as PaillierParams>::WideUint>,
) -> Scalar {
let abs_value = scalar_from_wide_uint::<P>(&value.abs());
Scalar::conditional_select(&abs_value, &-abs_value, value.is_negative())
if value.is_negative() {
-abs_value
} else {
abs_value
}
}

pub(crate) fn secret_scalar_from_uint<P: SchemeParams>(
Expand All @@ -213,7 +215,7 @@ pub(crate) fn secret_scalar_from_uint<P: SchemeParams>(
})
}

pub(crate) fn secret_uint_from_scalar<P: SchemeParams>(
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_be_bytes());
Expand All @@ -227,42 +229,29 @@ pub(crate) fn secret_uint_from_scalar<P: SchemeParams>(
Secret::init_with(|| <P::Paillier as PaillierParams>::Uint::from_be_bytes(*repr.expose_secret()))
}

pub(crate) fn secret_signed_from_scalar<P: SchemeParams>(
pub(crate) fn secret_unsigned_from_scalar<P: SchemeParams>(
value: &Secret<Scalar>,
) -> Secret<Signed<<P::Paillier as PaillierParams>::Uint>> {
Secret::init_with(|| {
Signed::new_positive(
*secret_uint_from_scalar::<P>(value).expose_secret(),
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`"
])
})
) -> SecretUnsigned<<P::Paillier as PaillierParams>::Uint> {
SecretUnsigned::new(secret_uint_from_scalar::<P>(value), 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`"
])
}

pub(crate) fn secret_bounded_from_scalar<P: SchemeParams>(
pub(crate) fn secret_signed_from_scalar<P: SchemeParams>(
value: &Secret<Scalar>,
) -> Secret<Bounded<<P::Paillier as PaillierParams>::Uint>> {
Secret::init_with(|| {
Bounded::new(
*secret_uint_from_scalar::<P>(value).expose_secret(),
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`"
])
})
) -> SecretSigned<<P::Paillier as PaillierParams>::Uint> {
SecretSigned::new_positive(secret_uint_from_scalar::<P>(value), 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`"
])
}

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

impl<P: SchemeParams> HashableType for P {
Expand Down
Loading

0 comments on commit 0b9eba1

Please sign in to comment.