mirror of
https://github.com/arnaucube/miden-crypto.git
synced 2026-01-12 09:01:29 +01:00
Tracking PR for v0.9.0 release (#278)
* chore: update crate version to v0.9.0 * chore: remove deprecated re-exports * chore: remove Box re-export * feat: implement pure-Rust keygen and signing for RpoFalcon512 (#285) * feat: add reproducible builds (#296) * fix: address a few issues for migrating Miden VM (#298) * feat: add RngCore supertrait for FeltRng (#299) --------- Co-authored-by: Al-Kindi-0 <82364884+Al-Kindi-0@users.noreply.github.com> Co-authored-by: Paul-Henry Kajfasz <42912740+phklive@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
2be17b74fb
commit
5a2e917dd5
172
src/dsa/rpo_falcon512/math/field.rs
Normal file
172
src/dsa/rpo_falcon512/math/field.rs
Normal file
@@ -0,0 +1,172 @@
|
||||
use super::{fft::CyclotomicFourier, Inverse, MODULUS};
|
||||
use alloc::string::String;
|
||||
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
use num::{One, Zero};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub struct FalconFelt(u32);
|
||||
|
||||
impl FalconFelt {
|
||||
pub const fn new(value: i16) -> Self {
|
||||
let gtz_bool = value >= 0;
|
||||
let gtz_int = gtz_bool as i16;
|
||||
let gtz_sign = gtz_int - ((!gtz_bool) as i16);
|
||||
let reduced = gtz_sign * (gtz_sign * value) % MODULUS;
|
||||
let canonical_representative = (reduced + MODULUS * (1 - gtz_int)) as u32;
|
||||
FalconFelt(canonical_representative)
|
||||
}
|
||||
|
||||
pub const fn value(&self) -> i16 {
|
||||
self.0 as i16
|
||||
}
|
||||
|
||||
pub fn balanced_value(&self) -> i16 {
|
||||
let value = self.value();
|
||||
let g = (value > ((MODULUS) / 2)) as i16;
|
||||
value - (MODULUS) * g
|
||||
}
|
||||
|
||||
pub const fn multiply(&self, other: Self) -> Self {
|
||||
FalconFelt((self.0 * other.0) % MODULUS as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for FalconFelt {
|
||||
type Output = Self;
|
||||
|
||||
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
let (s, _) = self.0.overflowing_add(rhs.0);
|
||||
let (d, n) = s.overflowing_sub(MODULUS as u32);
|
||||
let (r, _) = d.overflowing_add(MODULUS as u32 * (n as u32));
|
||||
FalconFelt(r)
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for FalconFelt {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for FalconFelt {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
self + -rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl SubAssign for FalconFelt {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = *self - rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for FalconFelt {
|
||||
type Output = FalconFelt;
|
||||
|
||||
fn neg(self) -> Self::Output {
|
||||
let is_nonzero = self.0 != 0;
|
||||
let r = MODULUS as u32 - self.0;
|
||||
FalconFelt(r * (is_nonzero as u32))
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for FalconFelt {
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
FalconFelt((self.0 * rhs.0) % MODULUS as u32)
|
||||
}
|
||||
|
||||
type Output = Self;
|
||||
}
|
||||
|
||||
impl MulAssign for FalconFelt {
|
||||
fn mul_assign(&mut self, rhs: Self) {
|
||||
*self = *self * rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl Div for FalconFelt {
|
||||
type Output = FalconFelt;
|
||||
|
||||
#[allow(clippy::suspicious_arithmetic_impl)]
|
||||
fn div(self, rhs: Self) -> Self::Output {
|
||||
self * rhs.inverse_or_zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl DivAssign for FalconFelt {
|
||||
fn div_assign(&mut self, rhs: Self) {
|
||||
*self = *self / rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Zero for FalconFelt {
|
||||
fn zero() -> Self {
|
||||
FalconFelt::new(0)
|
||||
}
|
||||
|
||||
fn is_zero(&self) -> bool {
|
||||
self.0 == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl One for FalconFelt {
|
||||
fn one() -> Self {
|
||||
FalconFelt::new(1)
|
||||
}
|
||||
}
|
||||
|
||||
impl Inverse for FalconFelt {
|
||||
fn inverse_or_zero(self) -> Self {
|
||||
// q-2 = 0b10 11 11 11 11 11 11
|
||||
let two = self.multiply(self);
|
||||
let three = two.multiply(self);
|
||||
let six = three.multiply(three);
|
||||
let twelve = six.multiply(six);
|
||||
let fifteen = twelve.multiply(three);
|
||||
let thirty = fifteen.multiply(fifteen);
|
||||
let sixty = thirty.multiply(thirty);
|
||||
let sixty_three = sixty.multiply(three);
|
||||
|
||||
let sixty_three_sq = sixty_three.multiply(sixty_three);
|
||||
let sixty_three_qu = sixty_three_sq.multiply(sixty_three_sq);
|
||||
let sixty_three_oc = sixty_three_qu.multiply(sixty_three_qu);
|
||||
let sixty_three_hx = sixty_three_oc.multiply(sixty_three_oc);
|
||||
let sixty_three_tt = sixty_three_hx.multiply(sixty_three_hx);
|
||||
let sixty_three_sf = sixty_three_tt.multiply(sixty_three_tt);
|
||||
|
||||
let all_ones = sixty_three_sf.multiply(sixty_three);
|
||||
let two_e_twelve = all_ones.multiply(self);
|
||||
let two_e_thirteen = two_e_twelve.multiply(two_e_twelve);
|
||||
|
||||
two_e_thirteen.multiply(all_ones)
|
||||
}
|
||||
}
|
||||
|
||||
impl CyclotomicFourier for FalconFelt {
|
||||
fn primitive_root_of_unity(n: usize) -> Self {
|
||||
let log2n = n.ilog2();
|
||||
assert!(log2n <= 12);
|
||||
// and 1331 is a twelfth root of unity
|
||||
let mut a = FalconFelt::new(1331);
|
||||
let num_squarings = 12 - n.ilog2();
|
||||
for _ in 0..num_squarings {
|
||||
a *= a;
|
||||
}
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for FalconFelt {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||
if value >= MODULUS as u32 {
|
||||
Err(format!("value {value} is greater than or equal to the field modulus {MODULUS}"))
|
||||
} else {
|
||||
Ok(FalconFelt::new(value as i16))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user