Skip to content

Commit

Permalink
Implement new inversion tweaks from #66
Browse files Browse the repository at this point in the history
  • Loading branch information
cronokirby committed Jan 12, 2024
1 parent ad80ae2 commit 4ed337a
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 95 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ hashbrown = "0.14.3"
# a default feature of std - without the ark-std std feature, decaf377 doesn't
# compile
[features]
default = ["std", "u64"]
default = ["std"]
std = ["ark-std/std", "tracing/std", "anyhow/std", "tracing-subscriber/std", "zeroize/std", "once_cell/std", "num-bigint/std", "hex/std" ]
parallel = ["ark-ff/parallel", "ark-ec/parallel", "ark-groth16/parallel", "ark-std/parallel", "ark-r1cs-std/parallel"]
r1cs = ["ark-r1cs-std", "ark-groth16", "ark-snark"]
# TODO: eventually, feature-gate all arkworks deps behind this feature.
arkworks = []
u32 = []
u64 = []
u32_backend = []
u64_backend = []

[dev-dependencies]
proptest = "1"
Expand Down
4 changes: 2 additions & 2 deletions src/fields/fp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ pub mod arkworks;
pub mod u32;
pub mod u64;

#[cfg(all(not(feature = "u32"), not(feature = "u64")))]
#[cfg(all(not(feature = "u32_backend"), not(feature = "u64_backend")))]
compile_error!("No backend selected. Please select either: 'u32_backend' or 'u64_backend'.");

Check failure on line 11 in src/fields/fp.rs

View workflow job for this annotation

GitHub Actions / Check

No backend selected. Please select either: 'u32_backend' or 'u64_backend'.

Check failure on line 11 in src/fields/fp.rs

View workflow job for this annotation

GitHub Actions / no_std compatibility check

No backend selected. Please select either: 'u32_backend' or 'u64_backend'.

Check failure on line 11 in src/fields/fp.rs

View workflow job for this annotation

GitHub Actions / Test Suite

No backend selected. Please select either: 'u32_backend' or 'u64_backend'.

Check failure on line 11 in src/fields/fp.rs

View workflow job for this annotation

GitHub Actions / no_std compatibility check

No backend selected. Please select either: 'u32_backend' or 'u64_backend'.

Check failure on line 11 in src/fields/fp.rs

View workflow job for this annotation

GitHub Actions / Test Suite

No backend selected. Please select either: 'u32_backend' or 'u64_backend'.

Check failure on line 11 in src/fields/fp.rs

View workflow job for this annotation

GitHub Actions / Check

No backend selected. Please select either: 'u32_backend' or 'u64_backend'.
#[cfg(all(feature = "u32", feature = "u64"))]
compile_error!(
"Multiple backends selected. Please select only one: 'u32_backend' or 'u64_backend'."
);

cfg_if! {
if #[cfg(feature = "u32")] {
if #[cfg(feature = "u32_backend")] {
pub type Fp = u32::Fp;

pub mod arkworks_constants {
Expand Down
90 changes: 47 additions & 43 deletions src/fields/fp/u32/wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use super::fiat;

const B: usize = 377;
const N_64: usize = (B + 63) / 64;
const N_8: usize = (B + 7) / 8;
const N: usize = (B + 31) / 32;

#[derive(Copy, Clone)]
pub struct Fp(pub fiat::FpMontgomeryDomainFieldElement);

Expand All @@ -21,56 +26,56 @@ impl zeroize::Zeroize for Fp {
}

impl Fp {
pub fn from_le_limbs(limbs: [u64; 6]) -> Fp {
pub fn from_le_limbs(limbs: [u64; N_64]) -> Fp {
let limbs = {
let mut out = [0u32; 12];
for i in 0..6 {
let mut out = [0u32; N];
for i in 0..N_64 {
out[2 * i] = (limbs[i] & 0xFFFF_FFFF_FFFF_FFFF) as u32;
out[2 * i + 1] = (limbs[i] >> 32) as u32;
}
out
};
let x_non_monty = fiat::FpNonMontgomeryDomainFieldElement(limbs);
let mut x = fiat::FpMontgomeryDomainFieldElement([0; 12]);
let mut x = fiat::FpMontgomeryDomainFieldElement([0; N]);
fiat::fp_to_montgomery(&mut x, &x_non_monty);
Self(x)
}

pub fn from_bytes(bytes: &[u8; 48]) -> Fp {
let mut x_non_montgomery = fiat::FpNonMontgomeryDomainFieldElement([0; 12]);
let mut x = fiat::FpMontgomeryDomainFieldElement([0; 12]);
pub fn from_bytes(bytes: &[u8; N_8]) -> Fp {
let mut x_non_montgomery = fiat::FpNonMontgomeryDomainFieldElement([0; N]);
let mut x = fiat::FpMontgomeryDomainFieldElement([0; N]);

fiat::fp_from_bytes(&mut x_non_montgomery.0, &bytes);
fiat::fp_to_montgomery(&mut x, &x_non_montgomery);

Self(x)
}

pub fn to_le_limbs(&self) -> [u64; 6] {
let mut x_non_montgomery = fiat::FpNonMontgomeryDomainFieldElement([0; 12]);
pub fn to_le_limbs(&self) -> [u64; N_64] {
let mut x_non_montgomery = fiat::FpNonMontgomeryDomainFieldElement([0; N]);
fiat::fp_from_montgomery(&mut x_non_montgomery, &self.0);
let limbs = x_non_montgomery.0;
let mut out = [0u64; 6];
for i in 0..6 {
let mut out = [0u64; N_64];
for i in 0..N_64 {
out[i] = (limbs[2 * i] as u64) | ((limbs[2 * i + 1] as u64) << 32);
}
out
}

pub fn to_bytes_le(&self) -> [u8; 48] {
let mut bytes = [0u8; 48];
let mut x_non_montgomery = fiat::FpNonMontgomeryDomainFieldElement([0; 12]);
pub fn to_bytes_le(&self) -> [u8; N_8] {
let mut bytes = [0u8; N_8];
let mut x_non_montgomery = fiat::FpNonMontgomeryDomainFieldElement([0; N]);
fiat::fp_from_montgomery(&mut x_non_montgomery, &self.0);
fiat::fp_to_bytes(&mut bytes, &x_non_montgomery.0);
bytes
}

pub const fn from_montgomery_limbs(limbs: [u32; 12]) -> Fp {
pub const fn from_montgomery_limbs(limbs: [u32; N]) -> Fp {
Self(fiat::FpMontgomeryDomainFieldElement(limbs))
}

pub const fn zero() -> Fp {
Self(fiat::FpMontgomeryDomainFieldElement([0; 12]))
Self(fiat::FpMontgomeryDomainFieldElement([0; N]))
}

pub const fn one() -> Self {
Expand All @@ -81,7 +86,7 @@ impl Fp {
}

pub fn square(&self) -> Fp {
let mut result = fiat::FpMontgomeryDomainFieldElement([0; 12]);
let mut result = fiat::FpMontgomeryDomainFieldElement([0; N]);
fiat::fp_square(&mut result, &self.0);
Self(result)
}
Expand All @@ -91,37 +96,36 @@ impl Fp {
return None;
}

const LEN_PRIME: usize = 377;
const ITERATIONS: usize = (49 * LEN_PRIME + 57) / 17;
const I: usize = (49 * B + 57) / 17;

let mut a = fiat::FpNonMontgomeryDomainFieldElement([0; 12]);
let mut a = fiat::FpNonMontgomeryDomainFieldElement([0; N]);
fiat::fp_from_montgomery(&mut a, &self.0);
let mut d = 1;
let mut f: [u32; 13] = [0u32; 13];
let mut f: [u32; N + 1] = [0u32; N + 1];
fiat::fp_msat(&mut f);
let mut g = [0u32; 13];
let mut v = [0u32; 12];
let mut r: [u32; 12] = Fp::one().0 .0;
let mut g: [u32; N + 1] = [0u32; N + 1];
let mut v: [u32; N] = [0u32; N];
let mut r: [u32; N] = Fp::one().0 .0;
let mut i = 0;
let mut j = 0;

while j < 12 {
while j < N {
g[j] = a[j];
j += 1;
}

let mut out1: u32 = 0;
let mut out2: [u32; 13] = [0; 13];
let mut out3: [u32; 13] = [0; 13];
let mut out4: [u32; 12] = [0; 12];
let mut out5: [u32; 12] = [0; 12];
let mut out2: [u32; N + 1] = [0; N + 1];
let mut out3: [u32; N + 1] = [0; N + 1];
let mut out4: [u32; N] = [0; N];
let mut out5: [u32; N] = [0; N];
let mut out6: u32 = 0;
let mut out7: [u32; 13] = [0; 13];
let mut out8: [u32; 13] = [0; 13];
let mut out9: [u32; 12] = [0; 12];
let mut out10: [u32; 12] = [0; 12];
let mut out7: [u32; N + 1] = [0; N + 1];
let mut out8: [u32; N + 1] = [0; N + 1];
let mut out9: [u32; N] = [0; N];
let mut out10: [u32; N] = [0; N];

while i < ITERATIONS - ITERATIONS % 2 {
while i < I - I % 2 {
fiat::fp_divstep(
&mut out1, &mut out2, &mut out3, &mut out4, &mut out5, d, &f, &g, &v, &r,
);
Expand All @@ -137,7 +141,7 @@ impl Fp {
i += 2;
}

if ITERATIONS % 2 != 0 {
if I % 2 != 0 {
fiat::fp_divstep(
&mut out1, &mut out2, &mut out3, &mut out4, &mut out5, d, &f, &g, &v, &r,
);
Expand All @@ -146,16 +150,16 @@ impl Fp {
}

let s = ((f[f.len() - 1] >> 32 - 1) & 1) as u8;
let mut neg = fiat::FpMontgomeryDomainFieldElement([0; 12]);
let mut neg = fiat::FpMontgomeryDomainFieldElement([0; N]);
fiat::fp_opp(&mut neg, &fiat::FpMontgomeryDomainFieldElement(v));

let mut v_prime: [u32; 12] = [0u32; 12];
let mut v_prime: [u32; N] = [0u32; N];
fiat::fp_selectznz(&mut v_prime, s, &v, &neg.0);

let mut pre_comp: [u32; 12] = [0u32; 12];
let mut pre_comp: [u32; N] = [0u32; N];
fiat::fp_divstep_precomp(&mut pre_comp);

let mut result = fiat::FpMontgomeryDomainFieldElement([0; 12]);
let mut result = fiat::FpMontgomeryDomainFieldElement([0; N]);
fiat::fp_mul(
&mut result,
&fiat::FpMontgomeryDomainFieldElement(v_prime),
Expand All @@ -166,25 +170,25 @@ impl Fp {
}

pub fn add(self, other: &Fp) -> Fp {
let mut result = fiat::FpMontgomeryDomainFieldElement([0; 12]);
let mut result = fiat::FpMontgomeryDomainFieldElement([0; N]);
fiat::fp_add(&mut result, &self.0, &other.0);
Fp(result)
}

pub fn sub(self, other: &Fp) -> Fp {
let mut result = fiat::FpMontgomeryDomainFieldElement([0; 12]);
let mut result = fiat::FpMontgomeryDomainFieldElement([0; N]);
fiat::fp_sub(&mut result, &self.0, &other.0);
Fp(result)
}

pub fn mul(self, other: &Fp) -> Fp {
let mut result = fiat::FpMontgomeryDomainFieldElement([0; 12]);
let mut result = fiat::FpMontgomeryDomainFieldElement([0; N]);
fiat::fp_mul(&mut result, &self.0, &other.0);
Fp(result)
}

pub fn neg(self) -> Fp {
let mut result = fiat::FpMontgomeryDomainFieldElement([0; 12]);
let mut result = fiat::FpMontgomeryDomainFieldElement([0; N]);
fiat::fp_opp(&mut result, &self.0);
Fp(result)
}
Expand Down
Loading

0 comments on commit 4ed337a

Please sign in to comment.