Browse Source

Add UInt128 for u128 (#21)

master
Weikeng Chen 4 years ago
committed by GitHub
parent
commit
68f08b94d2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 13 deletions
  1. +4
    -2
      Cargo.toml
  2. +1
    -0
      src/bits/mod.rs
  3. +18
    -11
      src/bits/uint.rs

+ 4
- 2
Cargo.toml

@ -20,13 +20,15 @@ ark-relations = { git = "https://github.com/arkworks-rs/snark", default-features
derivative = { version = "2", features = ["use_core"] } derivative = { version = "2", features = ["use_core"] }
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } 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] [dev-dependencies]
rand = { version = "0.7", default-features = false } rand = { version = "0.7", default-features = false }
rand_xorshift = "0.2" 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] [features]
default = ["std"] 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" ] parallel = [ "std", "ark-ff/parallel" ]

+ 1
- 0
src/bits/mod.rs

@ -17,6 +17,7 @@ pub mod uint;
make_uint!(UInt16, 16, u16, uint16, "16"); make_uint!(UInt16, 16, u16, uint16, "16");
make_uint!(UInt32, 32, u32, uint32, "32"); make_uint!(UInt32, 32, u32, uint32, "32");
make_uint!(UInt64, 64, u64, uint64, "64"); make_uint!(UInt64, 64, u64, uint64, "64");
make_uint!(UInt128, 128, u128, uint128, "128");
/// Specifies constraints for conversion to a little-endian bit representation /// Specifies constraints for conversion to a little-endian bit representation
/// of `self`. /// of `self`.

+ 18
- 11
src/bits/uint.rs

@ -6,9 +6,11 @@ macro_rules! make_uint {
#[doc = $native_doc_name] #[doc = $native_doc_name]
#[doc = "`type."] #[doc = "`type."]
pub mod $mod_name { pub mod $mod_name {
use ark_ff::{Field, FpParameters, PrimeField};
use ark_ff::{Field, FpParameters, One, PrimeField, Zero};
use core::borrow::Borrow; use core::borrow::Borrow;
use core::convert::TryFrom; use core::convert::TryFrom;
use num_bigint::BigUint;
use num_traits::cast::ToPrimitive;
use ark_relations::r1cs::{ use ark_relations::r1cs::{
ConstraintSystemRef, LinearCombination, Namespace, SynthesisError, Variable, ConstraintSystemRef, LinearCombination, Namespace, SynthesisError, Variable,
@ -183,6 +185,9 @@ macro_rules! make_uint {
// in the scalar field // in the scalar field
assert!(F::Params::MODULUS_BITS >= 2 * $size); assert!(F::Params::MODULUS_BITS >= 2 * $size);
// Support up to 128
assert!($size <= 128);
assert!(operands.len() >= 1); assert!(operands.len() >= 1);
assert!($size * operands.len() <= F::Params::MODULUS_BITS as usize); assert!($size * operands.len() <= F::Params::MODULUS_BITS as usize);
@ -192,10 +197,10 @@ macro_rules! make_uint {
// Compute the maximum value of the sum so we allocate enough bits for // Compute the maximum value of the sum so we allocate enough bits for
// the result // 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 // 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" // This is a linear combination that we will enforce to be "zero"
let mut lc = LinearCombination::zero(); let mut lc = LinearCombination::zero();
@ -207,7 +212,7 @@ macro_rules! make_uint {
// Accumulate the value // Accumulate the value
match op.value { match op.value {
Some(val) => { Some(val) => {
result_value.as_mut().map(|v| *v += u128::from(val));
result_value.as_mut().map(|v| *v += BigUint::from(val));
} }
None => { None => {
@ -246,7 +251,12 @@ macro_rules! make_uint {
} }
// The value of the actual result is modulo 2^$size // 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() { if all_constants && modular_value.is_some() {
// We can just return a constant, rather than // We can just return a constant, rather than
@ -262,11 +272,9 @@ macro_rules! make_uint {
// Allocate each bit_gadget of the result // Allocate each bit_gadget of the result
let mut coeff = F::one(); let mut coeff = F::one();
let mut i = 0; let mut i = 0;
while max_value != 0 {
while max_value != BigUint::zero() {
// Allocate the bit_gadget // 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 // Subtract this bit_gadget from the linear combination to ensure the sums
// balance out // balance out
@ -384,7 +392,7 @@ macro_rules! make_uint {
mod test { mod test {
use super::$name; use super::$name;
use crate::{bits::boolean::Boolean, prelude::*, Vec}; 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 ark_relations::r1cs::{ConstraintSystem, SynthesisError};
use rand::{Rng, SeedableRng}; use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng; use rand_xorshift::XorShiftRng;
@ -517,7 +525,6 @@ macro_rules! make_uint {
let r = $name::addmany(&[r, c_bit, d_bit]).unwrap(); let r = $name::addmany(&[r, c_bit, d_bit]).unwrap();
assert!(cs.is_satisfied().unwrap()); assert!(cs.is_satisfied().unwrap());
assert!(r.value == Some(expected)); assert!(r.value == Some(expected));
for b in r.bits.iter() { for b in r.bits.iter() {

Loading…
Cancel
Save