use crypto_bigint::modular::MontyParams;
use crypto_bigint::{
NonZero,
Odd,
U256,
U512,
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct LegendrePrfParams256 {
pub p: NonZero<U256>,
pub monty: MontyParams<U256>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct LegendrePrfParams512 {
pub p: U512,
pub monty: MontyParams<U512>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct GoldPrfParams256 {
pub p: U256,
pub monty: MontyParams<U256>,
pub g: U256,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct GoldPrfParams512 {
pub p: U512,
pub monty: MontyParams<U512>,
pub g: U512,
}
pub const P256_BE_HEX: &str = "6f7cfe74b8a1892ed54ec11ae8141a65dad3440973464111361ce7de4a5c5cfb";
pub const P512_BE_HEX: &str = "6fa0e975b4660858abfccfb1a2f3b5f8cda4239a89afa1840e62d758ae53a94059ab27f1f7833146306bf0d1c2647d9ca136b85e4c24dbdf0a4c8ef916f0094f";
#[inline]
fn monty_params_u256(p: U256) -> MontyParams<U256> {
let odd = Odd::new(p).into_option().expect("pilot modulus is odd");
MontyParams::new_vartime(odd)
}
#[inline]
fn monty_params_u512(p: U512) -> MontyParams<U512> {
let odd = Odd::new(p).into_option().expect("pilot modulus is odd");
MontyParams::new_vartime(odd)
}
impl LegendrePrfParams256 {
#[must_use]
pub fn pilot() -> Self {
let p_uint = U256::from_be_hex(P256_BE_HEX);
let p = NonZero::new(p_uint).expect("pilot modulus is non-zero");
let monty = monty_params_u256(p.get());
Self { p, monty }
}
#[must_use]
pub fn sophie_germain_cofactor(&self) -> U256 {
self.p.get().wrapping_sub(&U256::ONE).shr(1)
}
}
impl LegendrePrfParams512 {
#[must_use]
pub fn pilot() -> Self {
let p = U512::from_be_hex(P512_BE_HEX);
let monty = monty_params_u512(p);
Self { p, monty }
}
#[must_use]
pub fn sophie_germain_cofactor(&self) -> U512 {
self.p.wrapping_sub(&U512::ONE).shr(1)
}
}
impl GoldPrfParams256 {
#[must_use]
pub fn pilot() -> Self {
let leg = LegendrePrfParams256::pilot();
let g = leg.sophie_germain_cofactor();
GoldPrfParams256 {
p: leg.p.get(),
monty: leg.monty,
g,
}
}
}
impl GoldPrfParams512 {
#[must_use]
pub fn pilot() -> Self {
let leg = LegendrePrfParams512::pilot();
let g = leg.sophie_germain_cofactor();
GoldPrfParams512 {
p: leg.p,
monty: leg.monty,
g,
}
}
}
#[must_use]
pub fn u256_to_le_bytes(x: &U256) -> [u8; 32] {
x.to_le_bytes().into()
}
#[must_use]
pub fn u512_to_le_bytes(x: &U512) -> [u8; 64] {
x.to_le_bytes().into()
}
#[must_use]
pub fn u256_from_le_bytes(bytes: &[u8; 32]) -> U256 {
U256::from_le_slice(bytes.as_slice())
}
#[must_use]
pub fn u512_from_le_bytes(bytes: &[u8; 64]) -> U512 {
U512::from_le_slice(bytes.as_slice())
}