Skip to content

Commit

Permalink
chore: migrate prev utils mod to refactored metal msm
Browse files Browse the repository at this point in the history
  • Loading branch information
moven0831 committed Nov 4, 2024
1 parent 06c1cb0 commit e938c02
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 0 deletions.
91 changes: 91 additions & 0 deletions mopro-msm/src/msm/metal_msm/utils/limbs_conversion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use ark_bn254::Fq;
use ark_ff::biginteger::{BigInteger, BigInteger256};

use crate::msm::metal::abstraction::mont_reduction;

// implement to_u32_limbs and from_u32_limbs for BigInt<4>
pub trait ToLimbs {
fn to_u32_limbs(&self) -> Vec<u32>;
}

pub trait FromLimbs {
fn from_u32_limbs(limbs: &[u32]) -> Self;
fn from_u128(num: u128) -> Self;
fn from_u32(num: u32) -> Self;
}

// convert from little endian to big endian
impl ToLimbs for BigInteger256 {
fn to_u32_limbs(&self) -> Vec<u32> {
let mut limbs = Vec::new();
self.to_bytes_be().chunks(8).for_each(|chunk| {
let high = u32::from_be_bytes(chunk[0..4].try_into().unwrap());
let low = u32::from_be_bytes(chunk[4..8].try_into().unwrap());
limbs.push(high);
limbs.push(low);
});
limbs
}
}

// convert from little endian to big endian
impl ToLimbs for Fq {
fn to_u32_limbs(&self) -> Vec<u32> {
let mut limbs = Vec::new();
self.0.to_bytes_be().chunks(8).for_each(|chunk| {
let high = u32::from_be_bytes(chunk[0..4].try_into().unwrap());
let low = u32::from_be_bytes(chunk[4..8].try_into().unwrap());
limbs.push(high);
limbs.push(low);
});
limbs
}
}

impl FromLimbs for BigInteger256 {
// convert from big endian to little endian for metal
fn from_u32_limbs(limbs: &[u32]) -> Self {
let mut big_int = [0u64; 4];
for (i, limb) in limbs.chunks(2).rev().enumerate() {
let high = u64::from(limb[0]);
let low = u64::from(limb[1]);
big_int[i] = (high << 32) | low;
}
BigInteger256::new(big_int)
}
// provide little endian u128 since arkworks use this value as well
fn from_u128(num: u128) -> Self {
let high = (num >> 64) as u64;
let low = num as u64;
BigInteger256::new([low, high, 0, 0])
}
// provide little endian u32 since arkworks use this value as well
fn from_u32(num: u32) -> Self {
BigInteger256::new([num as u64, 0, 0, 0])
}
}

impl FromLimbs for Fq {
// convert from big endian to little endian for metal
fn from_u32_limbs(limbs: &[u32]) -> Self {
let mut big_int = [0u64; 4];
for (i, limb) in limbs.chunks(2).rev().enumerate() {
let high = u64::from(limb[0]);
let low = u64::from(limb[1]);
big_int[i] = (high << 32) | low;
}
Fq::new(mont_reduction::raw_reduction(BigInteger256::new(big_int)))
}
fn from_u128(num: u128) -> Self {
let high = (num >> 64) as u64;
let low = num as u64;
Fq::new(mont_reduction::raw_reduction(BigInteger256::new([
low, high, 0, 0,
])))
}
fn from_u32(num: u32) -> Self {
Fq::new(mont_reduction::raw_reduction(BigInteger256::new([
num as u64, 0, 0, 0,
])))
}
}
2 changes: 2 additions & 0 deletions mopro-msm/src/msm/metal_msm/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod limbs_conversion;
pub mod mont_reduction;
40 changes: 40 additions & 0 deletions mopro-msm/src/msm/metal_msm/utils/mont_reduction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use ark_bn254::FqConfig;
use ark_ff::{
biginteger::{arithmetic as fa, BigInt},
fields::models::{MontBackend, MontConfig},
Fp,
};

// Reference: https://github.com/arkworks-rs/algebra/blob/master/ff/src/fields/models/fp/montgomery_backend.rs#L373-L389
const N: usize = 4;
pub fn into_bigint(a: Fp<MontBackend<FqConfig, N>, N>) -> BigInt<N> {
let a = a.0;
raw_reduction(a)
}

pub fn raw_reduction(a: BigInt<N>) -> BigInt<N> {
let mut r = a.0; // parse into [u64; N]

// Montgomery Reduction
for i in 0..N {
let k = r[i].wrapping_mul(<FqConfig as MontConfig<N>>::INV);
let mut carry = 0;

fa::mac_with_carry(
r[i],
k,
<FqConfig as MontConfig<N>>::MODULUS.0[0],
&mut carry,
);
for j in 1..N {
r[(j + i) % N] = fa::mac_with_carry(
r[(j + i) % N],
k,
<FqConfig as MontConfig<N>>::MODULUS.0[j],
&mut carry,
);
}
r[i % N] = carry;
}
BigInt::new(r)
}

0 comments on commit e938c02

Please sign in to comment.