arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
Add UInt128 for u128 (#21)

Weikeng Chen w.k@berkeley.edu
Mon, 23 Nov 2020 15:26:10 -0800
commit

68f08b94d23dd6cb87a332f020c3df7625caf498

parent

77dfd7dac624420994f7b04fc4089c32238e79e1

3 files changed, 23 insertions(+), 13 deletions(-)

jump to
M Cargo.toml → Cargo.toml

@@ -20,13 +20,15 @@ ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features = false }

derivative = { version = "2", features = ["use_core"] } tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } +num-bigint = {version = "0.3", default-features = false } +num-traits = {version = "0.2", default-features = false } [dev-dependencies] rand = { version = "0.7", default-features = false } rand_xorshift = "0.2" -ark-test-curves = { git = "https://github.com/arkworks-rs/algebra", default-features = false, features = ["bls12_381_scalar_field"] } +ark-test-curves = { git = "https://github.com/arkworks-rs/algebra", default-features = false, features = ["bls12_381_scalar_field", "mnt4_753_scalar_field"] } [features] default = ["std"] -std = [ "ark-ff/std", "ark-relations/std", "ark-std/std" ] +std = [ "ark-ff/std", "ark-relations/std", "ark-std/std", "num-bigint/std" ] parallel = [ "std", "ark-ff/parallel" ]
M src/bits/mod.rs → src/bits/mod.rs

@@ -17,6 +17,7 @@

make_uint!(UInt16, 16, u16, uint16, "16"); make_uint!(UInt32, 32, u32, uint32, "32"); make_uint!(UInt64, 64, u64, uint64, "64"); +make_uint!(UInt128, 128, u128, uint128, "128"); /// Specifies constraints for conversion to a little-endian bit representation /// of `self`.
M src/bits/uint.rs → src/bits/uint.rs

@@ -6,9 +6,11 @@ #[doc = "`, a R1CS equivalent of the `u"]

#[doc = $native_doc_name] #[doc = "`type."] pub mod $mod_name { - use ark_ff::{Field, FpParameters, PrimeField}; + use ark_ff::{Field, FpParameters, One, PrimeField, Zero}; use core::borrow::Borrow; use core::convert::TryFrom; + use num_bigint::BigUint; + use num_traits::cast::ToPrimitive; use ark_relations::r1cs::{ ConstraintSystemRef, LinearCombination, Namespace, SynthesisError, Variable,

@@ -183,6 +185,9 @@ // Make some arbitrary bounds for ourselves to avoid overflows

// in the scalar field assert!(F::Params::MODULUS_BITS >= 2 * $size); + // Support up to 128 + assert!($size <= 128); + assert!(operands.len() >= 1); assert!($size * operands.len() <= F::Params::MODULUS_BITS as usize);

@@ -192,10 +197,10 @@ }

// Compute the maximum value of the sum so we allocate enough bits for // the result - let mut max_value = (operands.len() as u128) * u128::from($native::max_value()); + let mut max_value = BigUint::from($native::max_value()) * BigUint::from(operands.len()); // Keep track of the resulting value - let mut result_value = Some(0u128); + let mut result_value = Some(BigUint::zero()); // This is a linear combination that we will enforce to be "zero" let mut lc = LinearCombination::zero();

@@ -207,7 +212,7 @@ for op in operands {

// Accumulate the value match op.value { Some(val) => { - result_value.as_mut().map(|v| *v += u128::from(val)); + result_value.as_mut().map(|v| *v += BigUint::from(val)); } None => {

@@ -246,7 +251,12 @@ }

} // The value of the actual result is modulo 2^$size - let modular_value = result_value.map(|v| v as $native); + let modular_value = result_value.clone().map(|v| + { + let modulus = BigUint::from(1u64) << ($size as u32); + (v % modulus).to_u128().unwrap() as $native + } + ); if all_constants && modular_value.is_some() { // We can just return a constant, rather than

@@ -262,11 +272,9 @@

// Allocate each bit_gadget of the result let mut coeff = F::one(); let mut i = 0; - while max_value != 0 { + while max_value != BigUint::zero() { // Allocate the bit_gadget - let b = AllocatedBit::new_witness(cs.clone(), || { - result_value.map(|v| (v >> i) & 1 == 1).get() - })?; + let b = AllocatedBit::new_witness(cs.clone(), || result_value.clone().map(|v| (v >> i) & BigUint::one() == BigUint::one()).get())?; // Subtract this bit_gadget from the linear combination to ensure the sums // balance out

@@ -384,7 +392,7 @@ #[cfg(test)]

mod test { use super::$name; use crate::{bits::boolean::Boolean, prelude::*, Vec}; - use ark_test_curves::bls12_381::Fr; + use ark_test_curves::mnt4_753::Fr; use ark_relations::r1cs::{ConstraintSystem, SynthesisError}; use rand::{Rng, SeedableRng}; use rand_xorshift::XorShiftRng;

@@ -517,7 +525,6 @@ let r = a_bit.xor(&b_bit).unwrap();

let r = $name::addmany(&[r, c_bit, d_bit]).unwrap(); assert!(cs.is_satisfied().unwrap()); - assert!(r.value == Some(expected)); for b in r.bits.iter() {