Skip to content

Commit

Permalink
Change to the new range definition.
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Dec 19, 2024
1 parent 341d39d commit 68a123a
Show file tree
Hide file tree
Showing 12 changed files with 308 additions and 357 deletions.
27 changes: 9 additions & 18 deletions synedrion/src/cggmp21/conversion.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crypto_bigint::{Encoding, Zero};
use crypto_bigint::{BitOps, Encoding, Zero};

use super::params::SchemeParams;
use crate::{
curve::{Scalar, ORDER},
paillier::PaillierParams,
tools::Secret,
uint::{PublicSigned, SecretSigned, SecretUnsigned},
uint::{PublicSigned, SecretSigned},
};

fn uint_from_scalar<P: SchemeParams>(value: &Scalar) -> <P::Paillier as PaillierParams>::Uint {
Expand Down Expand Up @@ -93,9 +93,7 @@ pub(crate) fn scalar_from_wide_signed<P: SchemeParams>(
}

/// Converts a secret-wrapped uint to a secret-wrapped [`Scalar`], reducing the value modulo curve order.
pub(crate) fn secret_scalar_from_uint<P: SchemeParams>(
value: &Secret<<P::Paillier as PaillierParams>::Uint>,
) -> Secret<Scalar> {
fn secret_scalar_from_uint<P: SchemeParams>(value: &Secret<<P::Paillier as PaillierParams>::Uint>) -> Secret<Scalar> {
let r = value % &P::CURVE_ORDER;

let repr = Secret::init_with(|| r.expose_secret().to_be_bytes());
Expand Down Expand Up @@ -130,25 +128,18 @@ fn secret_uint_from_scalar<P: SchemeParams>(value: &Secret<Scalar>) -> Secret<<P
Secret::init_with(|| <P::Paillier as PaillierParams>::Uint::from_be_bytes(*repr.expose_secret()))
}

/// Converts a secret-wrapped [`Scalar`] to a [`SecretUnsigned`].
///
/// Assumes using a curve whose order fits in a [`PaillierParams::Uint`].
pub(crate) fn secret_unsigned_from_scalar<P: SchemeParams>(
value: &Secret<Scalar>,
) -> 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`"
])
}

/// Converts a secret-wrapped [`Scalar`] to a [`SecretSigned`].
///
/// Assumes using a curve whose order is at most the width of `Uint` minus 1 bit.
pub(crate) fn secret_signed_from_scalar<P: SchemeParams>(
value: &Secret<Scalar>,
) -> SecretSigned<<P::Paillier as PaillierParams>::Uint> {
SecretSigned::new_positive(secret_uint_from_scalar::<P>(value), ORDER.bits_vartime() as u32).expect(concat![
SecretSigned::new_modulo(
secret_uint_from_scalar::<P>(value),
&P::CURVE_ORDER,
P::CURVE_ORDER.as_ref().bits_vartime(),
)
.expect(concat![
"a curve scalar value is smaller than the curve order, ",
"and the curve order fits in `PaillierParams::Uint`"
])
Expand Down
28 changes: 13 additions & 15 deletions synedrion/src/cggmp21/interactive_signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize};

use super::{
conversion::{
public_signed_from_scalar, secret_scalar_from_signed, secret_signed_from_scalar, secret_unsigned_from_scalar,
},
conversion::{public_signed_from_scalar, secret_scalar_from_signed, secret_signed_from_scalar},
entities::{AuxInfo, AuxInfoPrecomputed, KeyShare, PresigningData, PresigningValues, PublicAuxInfoPrecomputed},
params::SchemeParams,
sigma::{
Expand Down Expand Up @@ -166,10 +164,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_unsigned_from_scalar::<P>(&gamma), &nu);
let cap_g = Ciphertext::new_with_randomizer(pk, &secret_signed_from_scalar::<P>(&gamma), &nu);

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

Ok(BoxedRound::new_dynamic(Round1 {
context: Context {
Expand Down Expand Up @@ -483,8 +481,8 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {

let target_pk = &self.context.public_aux(destination)?.paillier_pk;

let beta = SecretSigned::random_in_exp_range(rng, P::LP_BOUND);
let hat_beta = SecretSigned::random_in_exp_range(rng, P::LP_BOUND);
let beta = SecretSigned::random_in_exponent_range(rng, P::LP_BOUND);
let hat_beta = SecretSigned::random_in_exponent_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 All @@ -498,12 +496,12 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {
.get(destination)
.ok_or(LocalError::new("destination={destination:?} is missing in all_cap_k"))?;

let cap_f = Ciphertext::new_with_randomizer_signed(pk, &beta, &r);
let cap_d = others_cap_k * &gamma + Ciphertext::new_with_randomizer_signed(target_pk, &-&beta, &s);
let cap_f = Ciphertext::new_with_randomizer(pk, &beta, &r);
let cap_d = others_cap_k * &gamma + Ciphertext::new_with_randomizer(target_pk, &-&beta, &s);

let hat_cap_f = Ciphertext::new_with_randomizer_signed(pk, &hat_beta, &hat_r);
let hat_cap_f = Ciphertext::new_with_randomizer(pk, &hat_beta, &hat_r);
let hat_cap_d = others_cap_k * &secret_signed_from_scalar::<P>(&self.context.key_share.secret_share)
+ Ciphertext::new_with_randomizer_signed(target_pk, &-&hat_beta, &hat_s);
+ Ciphertext::new_with_randomizer(target_pk, &-&hat_beta, &hat_s);

let cap_g = self.all_cap_g.get(&self.context.my_id).ok_or(LocalError::new(format!(
"my_id={:?} is missing in all_cap_g",
Expand Down Expand Up @@ -680,8 +678,8 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {
)));
}

let alpha = cap_d.decrypt_signed(&self.context.aux_info.secret_aux.paillier_sk);
let hat_alpha = hat_cap_d.decrypt_signed(&self.context.aux_info.secret_aux.paillier_sk);
let alpha = cap_d.decrypt(&self.context.aux_info.secret_aux.paillier_sk);
let hat_alpha = hat_cap_d.decrypt(&self.context.aux_info.secret_aux.paillier_sk);

// `alpha == x * y + z` where `0 <= x, y < q`, and `-2^l' <= z <= 2^l'`,
// where `q` is the curve order.
Expand Down Expand Up @@ -1041,7 +1039,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {
.all_cap_g
.get(my_id)
.ok_or_else(|| LocalError::new("my_id={my_id:?} is missing in all_cap_g"))?;
let cap_h = (cap_g * &secret_unsigned_from_scalar::<P>(&self.context.k)).mul_randomizer(&rho);
let cap_h = (cap_g * &secret_signed_from_scalar::<P>(&self.context.k)).mul_randomizer(&rho);

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

View check run for this annotation

Codecov / codecov/patch

synedrion/src/cggmp21/interactive_signing.rs#L1042

Added line #L1042 was not covered by tests

let p_mul = MulProof::<P>::new(
rng,
Expand Down Expand Up @@ -1287,7 +1285,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round4<P, I> {
let cap_x = self.context.public_share(&my_id)?;

let rho = Randomizer::random(rng, pk);
let hat_cap_h = (&self.presigning.cap_k * &secret_unsigned_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
6 changes: 3 additions & 3 deletions synedrion/src/cggmp21/key_refresh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize};

use super::{
conversion::{secret_scalar_from_uint, secret_unsigned_from_scalar},
conversion::{secret_scalar_from_signed, secret_signed_from_scalar},
entities::{AuxInfo, KeyShareChange, PublicAuxInfo, SecretAuxInfo},
params::SchemeParams,
sigma::{FacProof, ModProof, PrmProof, SchCommitment, SchProof, SchSecret},
Expand Down Expand Up @@ -620,7 +620,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {
.cap_x_to_send
.get(destination_idx)
.ok_or_else(|| LocalError::new("destination_idx={destination_idx} is missing in cap_x_to_send"))?;
let ciphertext = Ciphertext::new(rng, &data.paillier_pk, &secret_unsigned_from_scalar::<P>(x_secret));
let ciphertext = Ciphertext::new(rng, &data.paillier_pk, &secret_signed_from_scalar::<P>(x_secret));
let proof_secret = self
.context
.tau_x
Expand Down Expand Up @@ -671,7 +671,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round3<P, I> {
.paillier_enc_x
.to_precomputed(&self.context.data_precomp.paillier_pk);

let x = secret_scalar_from_uint::<P>(&enc_x.decrypt(&self.context.paillier_sk));
let x = secret_scalar_from_signed::<P>(&enc_x.decrypt(&self.context.paillier_sk));

let my_idx = *self
.context
Expand Down
32 changes: 16 additions & 16 deletions synedrion/src/cggmp21/sigma/aff_g.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,20 @@ impl<P: SchemeParams> AffGProof<P> {

let hat_cap_n = setup.modulus();

let alpha = SecretSigned::random_in_exp_range(rng, P::L_BOUND + P::EPS_BOUND);
let beta = SecretSigned::random_in_exp_range(rng, P::LP_BOUND + P::EPS_BOUND);
let alpha = SecretSigned::random_in_exponent_range(rng, P::L_BOUND + P::EPS_BOUND);
let beta = SecretSigned::random_in_exponent_range(rng, P::LP_BOUND + P::EPS_BOUND);

let r = Randomizer::random(rng, public.pk0);
let r_y = Randomizer::random(rng, public.pk1);

let gamma = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let m = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND, hat_cap_n);
let delta = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let mu = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND, hat_cap_n);
let gamma = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let m = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND, hat_cap_n);
let delta = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let mu = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND, hat_cap_n);

let cap_a = (public.cap_c * &alpha + Ciphertext::new_with_randomizer_signed(public.pk0, &beta, &r)).to_wire();
let cap_a = (public.cap_c * &alpha + Ciphertext::new_with_randomizer(public.pk0, &beta, &r)).to_wire();
let cap_b_x = secret_scalar_from_signed::<P>(&alpha).mul_by_generator();
let cap_b_y = Ciphertext::new_with_randomizer_signed(public.pk1, &beta, &r_y).to_wire();
let cap_b_y = Ciphertext::new_with_randomizer(public.pk1, &beta, &r_y).to_wire();
let cap_e = setup.commit(&alpha, &gamma).to_wire();
let cap_s = setup.commit(secret.x, &m).to_wire();
let cap_f = setup.commit(&beta, &delta).to_wire();
Expand Down Expand Up @@ -212,7 +212,7 @@ impl<P: SchemeParams> AffGProof<P> {

// C^{z_1} (1 + N_0)^{z_2} \omega^{N_0} = A D^e \mod N_0^2
// => C (*) z_1 (+) encrypt_0(z_2, \omega) = A (+) D (*) e
if public.cap_c * &self.z1 + Ciphertext::new_public_with_randomizer_signed(public.pk0, &self.z2, &self.omega)
if public.cap_c * &self.z1 + Ciphertext::new_public_with_randomizer(public.pk0, &self.z2, &self.omega)
!= public.cap_d * &e + self.cap_a.to_precomputed(public.pk0)
{
return false;
Expand All @@ -230,7 +230,7 @@ impl<P: SchemeParams> AffGProof<P> {
// Original: `Y^e`. Modified `Y^{-e}`.
// (1 + N_1)^{z_2} \omega_y^{N_1} = B_y Y^(-e) \mod N_1^2
// => encrypt_1(z_2, \omega_y) = B_y (+) Y (*) (-e)
if Ciphertext::new_public_with_randomizer_signed(public.pk1, &self.z2, &self.omega_y)
if Ciphertext::new_public_with_randomizer(public.pk1, &self.z2, &self.omega_y)
!= public.cap_y * &(-e) + self.cap_b_y.to_precomputed(public.pk1)
{
return false;
Expand Down Expand Up @@ -280,16 +280,16 @@ mod tests {

let aux: &[u8] = b"abcde";

let x = SecretSigned::random_in_exp_range(&mut OsRng, Params::L_BOUND);
let y = SecretSigned::random_in_exp_range(&mut OsRng, Params::LP_BOUND);
let x = SecretSigned::random_in_exponent_range(&mut OsRng, Params::L_BOUND);
let y = SecretSigned::random_in_exponent_range(&mut OsRng, Params::LP_BOUND);

let rho = Randomizer::random(&mut OsRng, pk0);
let rho_y = Randomizer::random(&mut OsRng, pk1);
let secret = SecretSigned::random_in_exp_range(&mut OsRng, Params::L_BOUND);
let cap_c = Ciphertext::new_signed(&mut OsRng, pk0, &secret);
let secret = SecretSigned::random_in_exponent_range(&mut OsRng, Params::L_BOUND);
let cap_c = Ciphertext::new(&mut OsRng, pk0, &secret);

let cap_d = &cap_c * &x + Ciphertext::new_with_randomizer_signed(pk0, &-&y, &rho);
let cap_y = Ciphertext::new_with_randomizer_signed(pk1, &y, &rho_y);
let cap_d = &cap_c * &x + Ciphertext::new_with_randomizer(pk0, &-&y, &rho);
let cap_y = Ciphertext::new_with_randomizer(pk1, &y, &rho_y);
let cap_x = secret_scalar_from_signed::<TestParams>(&x).mul_by_generator();

let proof = AffGProof::<Params>::new(
Expand Down
12 changes: 6 additions & 6 deletions synedrion/src/cggmp21/sigma/dec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ impl<P: SchemeParams> DecProof<P> {

let hat_cap_n = setup.modulus(); // $\hat{N}$

let alpha = SecretSigned::random_in_exp_range(rng, P::L_BOUND + P::EPS_BOUND);
let mu = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND, hat_cap_n);
let nu = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let alpha = SecretSigned::random_in_exponent_range(rng, P::L_BOUND + P::EPS_BOUND);
let mu = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND, hat_cap_n);
let nu = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let r = Randomizer::random(rng, public.pk0);

let cap_s = setup.commit(secret.y, &mu).to_wire();
let cap_t = setup.commit(&alpha, &nu).to_wire();
let cap_a = Ciphertext::new_with_randomizer_signed(public.pk0, &alpha, &r).to_wire();
let cap_a = Ciphertext::new_with_randomizer(public.pk0, &alpha, &r).to_wire();

// `alpha` is secret, but `gamma` only uncovers $\ell$ bits of `alpha`'s full $\ell + \eps$ bits,
// and it's transmitted to another node, so it can be considered public.
Expand Down Expand Up @@ -182,11 +182,11 @@ mod tests {
let aux: &[u8] = b"abcde";

// We need something within the range -N/2..N/2 so that it doesn't wrap around.
let y = SecretSigned::random_in_exp_range(&mut OsRng, Paillier::PRIME_BITS * 2 - 2);
let y = SecretSigned::random_in_exponent_range(&mut OsRng, Paillier::PRIME_BITS * 2 - 2);
let x = *secret_scalar_from_signed::<Params>(&y).expose_secret();

let rho = Randomizer::random(&mut OsRng, pk);
let cap_c = Ciphertext::new_with_randomizer_signed(pk, &y, &rho);
let cap_c = Ciphertext::new_with_randomizer(pk, &y, &rho);

let proof = DecProof::<Params>::new(
&mut OsRng,
Expand Down
14 changes: 7 additions & 7 deletions synedrion/src/cggmp21/sigma/enc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ impl<P: SchemeParams> EncProof<P> {

// TODO (#86): should we instead sample in range $+- 2^{\ell + \eps} - q 2^\ell$?
// This will ensure that the range check on the prover side will pass.
let alpha = SecretSigned::random_in_exp_range(rng, P::L_BOUND + P::EPS_BOUND);
let mu = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND, hat_cap_n);
let alpha = SecretSigned::random_in_exponent_range(rng, P::L_BOUND + P::EPS_BOUND);
let mu = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND, hat_cap_n);
let r = Randomizer::random(rng, public.pk0);
let gamma = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let gamma = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);

let cap_s = setup.commit(secret.k, &mu).to_wire();
let cap_a = Ciphertext::new_with_randomizer_signed(public.pk0, &alpha, &r).to_wire();
let cap_a = Ciphertext::new_with_randomizer(public.pk0, &alpha, &r).to_wire();
let cap_c = setup.commit(&alpha, &gamma).to_wire();

let mut reader = XofHasher::new_with_dst(HASH_TAG)
Expand Down Expand Up @@ -123,7 +123,7 @@ impl<P: SchemeParams> EncProof<P> {
}

// enc_0(z1, z2) == A (+) K (*) e
let c = Ciphertext::new_public_with_randomizer_signed(public.pk0, &self.z1, &self.z2);
let c = Ciphertext::new_public_with_randomizer(public.pk0, &self.z1, &self.z2);
if c != self.cap_a.to_precomputed(public.pk0) + public.cap_k * &e {
return false;
}
Expand Down Expand Up @@ -162,9 +162,9 @@ mod tests {

let aux: &[u8] = b"abcde";

let secret = SecretSigned::random_in_exp_range(&mut OsRng, Params::L_BOUND);
let secret = SecretSigned::random_in_exponent_range(&mut OsRng, Params::L_BOUND);
let randomizer = Randomizer::random(&mut OsRng, pk);
let ciphertext = Ciphertext::new_with_randomizer_signed(pk, &secret, &randomizer);
let ciphertext = Ciphertext::new_with_randomizer(pk, &secret, &randomizer);

let proof = EncProof::<Params>::new(
&mut OsRng,
Expand Down
16 changes: 8 additions & 8 deletions synedrion/src/cggmp21/sigma/fac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,27 +59,27 @@ impl<P: SchemeParams> FacProof<P> {
let sqrt_cap_n =
<P::Paillier as PaillierParams>::Uint::one() << (<P::Paillier as PaillierParams>::PRIME_BITS - 2);

let alpha = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, &sqrt_cap_n);
let beta = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, &sqrt_cap_n);
let mu = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND, hat_cap_n);
let nu = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND, hat_cap_n);
let alpha = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, &sqrt_cap_n);
let beta = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, &sqrt_cap_n);
let mu = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND, hat_cap_n);
let nu = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND, hat_cap_n);

// N_0 \hat{N}
let scale = pk0.modulus().mul_wide(hat_cap_n);

let sigma = SecretSigned::<<P::Paillier as PaillierParams>::Uint>::random_in_exp_range_scaled_wide(
let sigma = SecretSigned::<<P::Paillier as PaillierParams>::Uint>::random_in_exponent_range_scaled_wide(
rng,
P::L_BOUND,
&scale,
)
.to_public();
let r = SecretSigned::<<P::Paillier as PaillierParams>::Uint>::random_in_exp_range_scaled_wide(
let r = SecretSigned::<<P::Paillier as PaillierParams>::Uint>::random_in_exponent_range_scaled_wide(
rng,
P::L_BOUND + P::EPS_BOUND,
&scale,
);
let x = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let y = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let x = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let y = SecretSigned::random_in_exponent_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);

let p = sk0.p_signed();
let q = sk0.q_signed();
Expand Down
Loading

0 comments on commit 68a123a

Please sign in to comment.