Skip to content

Commit

Permalink
Move uint_from_xof to uint::traits
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Dec 21, 2024
1 parent 726380a commit b61ecf7
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 37 deletions.
6 changes: 3 additions & 3 deletions synedrion/src/paillier/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize};

use super::params::PaillierParams;
use crate::{
tools::{hashing::uint_from_xof, Secret},
uint::{HasWide, IsInvertible, PublicSigned, SecretSigned, SecretUnsigned, ToMontgomery},
tools::Secret,
uint::{FromXofReader, HasWide, IsInvertible, PublicSigned, SecretSigned, SecretUnsigned, ToMontgomery},
};

fn random_paillier_blum_prime<P: PaillierParams>(rng: &mut impl CryptoRngCore) -> P::HalfUint {
Expand Down Expand Up @@ -270,7 +270,7 @@ impl<P: PaillierParams> PublicModulus<P> {
pub fn invertible_residue_from_xof_reader(&self, reader: &mut impl XofReader) -> P::Uint {
let modulus_bits = self.modulus().bits_vartime();
loop {
let r = uint_from_xof::<P::Uint>(reader, modulus_bits);
let r = P::Uint::from_xof_reader(reader, modulus_bits);
if r.is_invertible(&self.modulus.0) {
return r;
}
Expand Down
31 changes: 1 addition & 30 deletions synedrion/src/tools/hashing.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crypto_bigint::{Bounded, Encoding, Integer};
use digest::{Digest, ExtendableOutput, Update, XofReader};
use digest::{Digest, ExtendableOutput, Update};
use hashing_serializer::HashingSerializer;
use serde::{Deserialize, Serialize};
use serde_encoded_bytes::{ArrayLike, Hex};
Expand Down Expand Up @@ -140,31 +139,3 @@ impl<T: Serialize> Hashable for T {
digest
}
}

pub(crate) fn uint_from_xof<T>(reader: &mut impl XofReader, n_bits: u32) -> T
where
T: Integer + Bounded + Encoding,
{
assert!(n_bits <= T::BITS);
let n_bytes = n_bits.div_ceil(8) as usize;

// If the number of bits is not a multiple of 8, use a mask to zeroize the high bits in the
// gererated random bytestring, so that we don't have to reject too much.
let mask = if n_bits & 7 != 0 {
(1 << (n_bits & 7)) - 1
} else {
u8::MAX
};

let mut bytes = T::zero().to_le_bytes();
let buf = bytes
.as_mut()
.get_mut(0..n_bytes)
.expect("`n_bytes` does not exceed `T::BYTES` as asserted above");
reader.read(buf);
bytes.as_mut().last_mut().map(|byte| {
*byte &= mask;
Some(byte)
});
T::from_le_bytes(bytes)
}
4 changes: 3 additions & 1 deletion synedrion/src/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ mod traits;
pub(crate) use public_signed::PublicSigned;
pub(crate) use secret_signed::SecretSigned;
pub(crate) use secret_unsigned::SecretUnsigned;
pub(crate) use traits::{Exponentiable, HasWide, IsInvertible, ToMontgomery, U1024Mod, U2048Mod, U4096Mod, U512Mod};
pub(crate) use traits::{
Exponentiable, FromXofReader, HasWide, IsInvertible, ToMontgomery, U1024Mod, U2048Mod, U4096Mod, U512Mod,
};
5 changes: 2 additions & 3 deletions synedrion/src/uint/public_signed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use digest::XofReader;
use serde::{Deserialize, Serialize};
use serde_encoded_bytes::{Hex, SliceLike};

use super::HasWide;
use crate::tools::hashing::uint_from_xof;
use super::{FromXofReader, HasWide};

/// A packed representation for serializing Signed objects.
/// Usually they have the bound set much lower than the full size of the integer,
Expand Down Expand Up @@ -188,7 +187,7 @@ where
T::BITS
);

let positive_result = uint_from_xof::<T>(reader, exp);
let positive_result = T::from_xof_reader(reader, exp);
let shift = T::one()
.overflowing_shl_vartime(exp - 1)
.expect("does not overflow because of the assertions above")
Expand Down
39 changes: 39 additions & 0 deletions synedrion/src/uint/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,49 @@ use crypto_bigint::{
Bounded, ConcatMixed, Encoding, Gcd, Integer, Invert, Limb, Monty, PowBoundedExp, RandomMod, SplitMixed,
WideningMul, Zero, U1024, U2048, U4096, U512, U8192,
};
use digest::XofReader;
use zeroize::Zeroize;

use crate::uint::{PublicSigned, SecretSigned, SecretUnsigned};

pub trait FromXofReader {
/// Returns an integer derived deterministically from an externsible output hash,
/// with the bit size limited to `n_bits`.
///
/// Panics if `n_bits` exceed the capacity of the integer type.
fn from_xof_reader(reader: &mut impl XofReader, n_bits: u32) -> Self;
}

impl<T> FromXofReader for T
where
T: Integer + Bounded + Encoding,
{
fn from_xof_reader(reader: &mut impl XofReader, n_bits: u32) -> Self {
assert!(n_bits <= Self::BITS);
let n_bytes = n_bits.div_ceil(8) as usize;

// If the number of bits is not a multiple of 8, use a mask to zeroize the high bits in the
// gererated random bytestring, so that we don't have to reject too much.
let mask = if n_bits & 7 != 0 {
(1 << (n_bits & 7)) - 1
} else {
u8::MAX
};

let mut bytes = Self::zero().to_le_bytes();
let buf = bytes
.as_mut()
.get_mut(0..n_bytes)
.expect("`n_bytes` does not exceed `Self::BYTES` as asserted above");
reader.read(buf);
bytes.as_mut().last_mut().map(|byte| {
*byte &= mask;
Some(byte)
});
Self::from_le_bytes(bytes)
}
}

pub trait IsInvertible {
/// Returns `true` if `self` is invertible modulo `modulus`.
fn is_invertible(&self, modulus: &Self) -> bool;
Expand Down

0 comments on commit b61ecf7

Please sign in to comment.