Skip to content

Commit

Permalink
Move specific implementations of PaillierParams into CGGMP parameters…
Browse files Browse the repository at this point in the history
… module

Since the test params must have some values set to accommodate CGGMP requirements,
which is out of scope of `paillier` submodule.
  • Loading branch information
fjarri committed Nov 5, 2023
1 parent ab7bcbb commit 4616b0c
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 58 deletions.
67 changes: 65 additions & 2 deletions synedrion/src/cggmp21/params.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,69 @@
use crate::curve::ORDER;
use crate::paillier::{PaillierParams, PaillierProduction, PaillierTest};
use crate::uint::upcast_uint;
use crate::paillier::PaillierParams;
use crate::uint::{
upcast_uint, U1024Mod, U2048Mod, U4096Mod, U512Mod, U1024, U2048, U4096, U512, U8192,
};

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct PaillierTest;

impl PaillierParams for PaillierTest {
// We need 257-bit primes because we need MODULUS_BITS to accommodate all the possible
// values of curve scalar squared, which is 512 bits.

/*
The prime size is chosen to be minimal for which the `TestSchemeParams` still work.
In the presigning, we are effectively constructing a ciphertext of
d = x * sum(j=1..P) y_i + sum(j=1..2*(P-1)) z_j
where
0 < x, y_i < q < 2^L, and
-2^LP < z < 2^LP
(`q` is the curve order, `L` and `LP` are constants in `TestSchemeParams`,
`P` is the number of parties).
This is `delta_i`, an additive share of the product of two secret values.
We need the final result to be `-N/2 < d < N/2`
(that is, it may be negative, and it cannot wrap around modulo N).
`N` is a product of two primes of the size `PRIME_BITS`, so `N > 2^(2 * PRIME_BITS - 2)`.
The upper bound on `log2(d)` is
max(2 * L, LP + 2) + ceil(log2(P))
Note in reality, due to numbers being random, the distribution will have a distinct peak,
and the upper bound will have a low probability of being reached.
Therefore we require `max(2 * L, LP + 2) + ceil(log2(P)) < 2 * PRIME_BITS - 2`.
For tests we assume `ceil(log2(P)) = 5` (we won't run tests with more than 32 nodes),
and since in `TestSchemeParams` `L = LP = 256`, this leads to `PRIME_BITS >= L + 4`.
For production it does not matter since both 2*L and LP are much smaller than 2*PRIME_BITS.
TODO: add an assertion for `SchemeParams` checking that?
*/

const PRIME_BITS: usize = 260;
type HalfUint = U512;
type HalfUintMod = U512Mod;
type Uint = U1024;
type UintMod = U1024Mod;
type WideUint = U2048;
type WideUintMod = U2048Mod;
type ExtraWideUint = U4096;
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct PaillierProduction;

impl PaillierParams for PaillierProduction {
const PRIME_BITS: usize = 1024;
type HalfUint = U1024;
type HalfUintMod = U1024Mod;
type Uint = U2048;
type UintMod = U2048Mod;
type WideUint = U4096;
type WideUintMod = U4096Mod;
type ExtraWideUint = U8192;
}

/// Signing scheme parameters.
// TODO (#27): this trait can include curve scalar/point types as well,
Expand Down
2 changes: 1 addition & 1 deletion synedrion/src/paillier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ pub(crate) use keys::{
PublicKeyPaillier, PublicKeyPaillierPrecomputed, SecretKeyPaillier,
SecretKeyPaillierPrecomputed,
};
pub(crate) use params::{PaillierParams, PaillierProduction, PaillierTest};
pub(crate) use params::PaillierParams;
pub(crate) use ring_pedersen::{RPCommitment, RPParams, RPParamsMod, RPSecret};
4 changes: 3 additions & 1 deletion synedrion/src/paillier/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,10 @@ impl<P: PaillierParams> Hashable for Ciphertext<P> {
mod tests {
use rand_core::OsRng;

use super::super::params::PaillierTest;
use super::super::{PaillierParams, SecretKeyPaillier};
use super::{Ciphertext, RandomizerMod};
use crate::paillier::{PaillierParams, PaillierTest, SecretKeyPaillier};

use crate::uint::{
subtle::ConditionallyNegatable, HasWide, NonZero, RandomMod, Signed, UintLike,
};
Expand Down
2 changes: 1 addition & 1 deletion synedrion/src/paillier/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ impl<P: PaillierParams> Hashable for PublicKeyPaillier<P> {
mod tests {
use rand_core::OsRng;

use super::super::params::PaillierTest;
use super::SecretKeyPaillier;
use crate::paillier::PaillierTest;

#[test]
fn basics() {
Expand Down
62 changes: 9 additions & 53 deletions synedrion/src/paillier/params.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use serde::{Deserialize, Serialize};

use crate::uint::{
FromScalar, HasWide, U1024Mod, U2048Mod, U4096Mod, U512Mod, UintLike, UintModLike, U1024,
U2048, U4096, U512, U8192,
};
use crate::uint::{FromScalar, HasWide, UintLike, UintModLike};

#[cfg(test)]
use crate::uint::{U1024Mod, U2048Mod, U512Mod, U1024, U2048, U4096, U512};

pub trait PaillierParams: PartialEq + Eq + Clone + core::fmt::Debug + Send {
/// The size of one of the pair of RSA primes.
Expand Down Expand Up @@ -38,44 +38,14 @@ pub trait PaillierParams: PartialEq + Eq + Clone + core::fmt::Debug + Send {
type ExtraWideUint: UintLike + Serialize + for<'de> Deserialize<'de>;
}

/// Paillier parameters for unit tests in this submodule.
#[cfg(test)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct PaillierTest;
pub(crate) struct PaillierTest;

#[cfg(test)]
impl PaillierParams for PaillierTest {
// We need 257-bit primes because we need MODULUS_BITS to accommodate all the possible
// values of curve scalar squared, which is 512 bits.

/*
The prime size is chosen to be minimal for which the `TestSchemeParams` still work.
In the presigning, we are effectively constructing a ciphertext of
d = x * sum(j=1..P) y_i + sum(j=1..2*(P-1)) z_j
where
0 < x, y_i < q < 2^L, and
-2^LP < z < 2^LP
(`q` is the curve order, `L` and `LP` are constants in `TestSchemeParams`,
`P` is the number of parties).
This is `delta_i`, an additive share of the product of two secret values.
We need the final result to be `-N/2 < d < N/2`
(that is, it may be negative, and it cannot wrap around modulo N).
`N` is a product of two primes of the size `PRIME_BITS`, so `N > 2^(2 * PRIME_BITS - 2)`.
The upper bound on `log2(d)` is
max(2 * L, LP + 2) + ceil(log2(P))
Note in reality, due to numbers being random, the distribution will have a distinct peak,
and the upper bound will have a low probability of being reached.
Therefore we require `max(2 * L, LP + 2) + ceil(log2(P)) < 2 * PRIME_BITS - 2`.
For tests we assume `ceil(log2(P)) = 5` (we won't run tests with more than 32 nodes),
and since in `TestSchemeParams` `L = LP = 256`, this leads to `PRIME_BITS >= L + 4`.
For production it does not matter since both 2*L and LP are much smaller than 2*PRIME_BITS.
TODO: add an assertion for `SchemeParams` checking that?
*/

const PRIME_BITS: usize = 260;
const PRIME_BITS: usize = 512;
type HalfUint = U512;
type HalfUintMod = U512Mod;
type Uint = U1024;
Expand All @@ -84,17 +54,3 @@ impl PaillierParams for PaillierTest {
type WideUintMod = U2048Mod;
type ExtraWideUint = U4096;
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct PaillierProduction;

impl PaillierParams for PaillierProduction {
const PRIME_BITS: usize = 1024;
type HalfUint = U1024;
type HalfUintMod = U1024Mod;
type Uint = U2048;
type UintMod = U2048Mod;
type WideUint = U4096;
type WideUintMod = U4096Mod;
type ExtraWideUint = U8192;
}

0 comments on commit 4616b0c

Please sign in to comment.