mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-11 00:11:29 +01:00
Refactor bit iteration infrastructure:
* `to_bits` -> `to_bits_le` * `BitIterator` -> `BitIteratorLE` + `BitIteratorBE` * `found_one`/`seen_one` -> `BitIteratorBE::without_leading_zeros`
This commit is contained in:
@@ -31,7 +31,7 @@ impl<F: PrimeField> CommitmentGadget<blake2s::Commitment, F> for CommGadget {
|
||||
) -> Result<Self::OutputVar, SynthesisError> {
|
||||
let mut input_bits = Vec::with_capacity(512);
|
||||
for byte in input.iter().chain(r.0.iter()) {
|
||||
input_bits.extend_from_slice(&byte.into_bits_le());
|
||||
input_bits.extend_from_slice(&byte.to_bits_le()?);
|
||||
}
|
||||
let mut result = Vec::new();
|
||||
for int in evaluate_blake2s(&input_bits)?.into_iter() {
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
};
|
||||
use algebra_core::{
|
||||
fields::{Field, PrimeField},
|
||||
to_bytes, ProjectiveCurve, ToBytes, Zero,
|
||||
to_bytes, ProjectiveCurve, Zero,
|
||||
};
|
||||
use r1cs_core::{Namespace, SynthesisError};
|
||||
|
||||
@@ -73,17 +73,20 @@ where
|
||||
assert_eq!(parameters.params.generators.len(), W::NUM_WINDOWS);
|
||||
|
||||
// Allocate new variable for commitment output.
|
||||
let input_in_bits: Vec<_> = padded_input
|
||||
let input_in_bits: Vec<Boolean<_>> = padded_input
|
||||
.iter()
|
||||
.flat_map(|byte| byte.into_bits_le())
|
||||
.flat_map(|byte| byte.to_bits_le().unwrap())
|
||||
.collect();
|
||||
let input_in_bits = input_in_bits.chunks(W::WINDOW_SIZE);
|
||||
let mut result =
|
||||
GG::precomputed_base_multiscalar_mul(¶meters.params.generators, input_in_bits)?;
|
||||
GG::precomputed_base_multiscalar_mul_le(¶meters.params.generators, input_in_bits)?;
|
||||
|
||||
// Compute h^r
|
||||
let rand_bits: Vec<_> = r.0.iter().flat_map(|byte| byte.into_bits_le()).collect();
|
||||
result.precomputed_base_scalar_mul(
|
||||
let rand_bits: Vec<_> =
|
||||
r.0.iter()
|
||||
.flat_map(|byte| byte.to_bits_le().unwrap())
|
||||
.collect();
|
||||
result.precomputed_base_scalar_mul_le(
|
||||
rand_bits
|
||||
.iter()
|
||||
.zip(¶meters.params.randomness_generator),
|
||||
|
||||
@@ -2,7 +2,8 @@ use crate::{Error, Vec};
|
||||
use algebra_core::{
|
||||
bytes::ToBytes,
|
||||
io::{Result as IoResult, Write},
|
||||
BitIterator, Field, FpParameters, PrimeField, ProjectiveCurve, ToConstraintField, UniformRand,
|
||||
BitIteratorLE, Field, FpParameters, PrimeField, ProjectiveCurve, ToConstraintField,
|
||||
UniformRand,
|
||||
};
|
||||
|
||||
use core::marker::PhantomData;
|
||||
@@ -99,9 +100,7 @@ impl<C: ProjectiveCurve, W: Window> CommitmentScheme for Commitment<C, W> {
|
||||
let randomize_time = start_timer!(|| "Randomize");
|
||||
|
||||
// Compute h^r.
|
||||
let mut scalar_bits = BitIterator::new(randomness.0.into_repr()).collect::<Vec<_>>();
|
||||
scalar_bits.reverse();
|
||||
for (bit, power) in scalar_bits
|
||||
for (bit, power) in BitIteratorLE::new(randomness.0.into_repr())
|
||||
.into_iter()
|
||||
.zip(¶meters.randomness_generator)
|
||||
{
|
||||
|
||||
@@ -56,7 +56,10 @@ where
|
||||
input: &[UInt8<ConstraintF<P>>],
|
||||
) -> Result<Self::OutputVar, SynthesisError> {
|
||||
// Pad the input if it is not the current length.
|
||||
let mut input_in_bits: Vec<_> = input.iter().flat_map(|byte| byte.into_bits_le()).collect();
|
||||
let mut input_in_bits: Vec<Boolean<_>> = input
|
||||
.iter()
|
||||
.flat_map(|byte| byte.to_bits_le().unwrap())
|
||||
.collect();
|
||||
if (input_in_bits.len()) % CHUNK_SIZE != 0 {
|
||||
let current_length = input_in_bits.len();
|
||||
for _ in 0..(CHUNK_SIZE - current_length % CHUNK_SIZE) {
|
||||
|
||||
@@ -190,7 +190,8 @@ mod test {
|
||||
|
||||
let rng = &mut test_rng();
|
||||
let params = <CRH<EdwardsParameters, TestWindow> as FixedLengthCRH>::setup(rng).unwrap();
|
||||
<CRH<EdwardsParameters, TestWindow> as FixedLengthCRH>::evaluate(¶ms, &[1, 2, 3])
|
||||
.unwrap();
|
||||
let _ =
|
||||
<CRH<EdwardsParameters, TestWindow> as FixedLengthCRH>::evaluate(¶ms, &[1, 2, 3])
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,11 +61,13 @@ where
|
||||
assert_eq!(parameters.params.generators.len(), W::NUM_WINDOWS);
|
||||
|
||||
// Allocate new variable for the result.
|
||||
let input_in_bits: Vec<_> = padded_input.iter().flat_map(|b| b.into_bits_le()).collect();
|
||||
let input_in_bits: Vec<Boolean<_>> = padded_input
|
||||
.iter()
|
||||
.flat_map(|b| b.to_bits_le().unwrap())
|
||||
.collect();
|
||||
let input_in_bits = input_in_bits.chunks(W::WINDOW_SIZE);
|
||||
let result =
|
||||
GG::precomputed_base_multiscalar_mul(¶meters.params.generators, input_in_bits)?;
|
||||
|
||||
GG::precomputed_base_multiscalar_mul_le(¶meters.params.generators, input_in_bits)?;
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ pub trait NIZKVerifierGadget<N: NIZK, ConstraintF: Field> {
|
||||
|
||||
fn verify<'a, T: 'a + ToBitsGadget<ConstraintF> + ?Sized>(
|
||||
verification_key: &Self::VerificationKeyVar,
|
||||
input: impl Iterator<Item = &'a T>,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
proof: &Self::ProofVar,
|
||||
) -> Result<(), SynthesisError> {
|
||||
Self::conditional_verify(verification_key, input, proof, &Boolean::constant(true))
|
||||
@@ -45,14 +45,14 @@ pub trait NIZKVerifierGadget<N: NIZK, ConstraintF: Field> {
|
||||
|
||||
fn conditional_verify<'a, T: 'a + ToBitsGadget<ConstraintF> + ?Sized>(
|
||||
verification_key: &Self::VerificationKeyVar,
|
||||
input: impl Iterator<Item = &'a T>,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
proof: &Self::ProofVar,
|
||||
condition: &Boolean<ConstraintF>,
|
||||
) -> Result<(), SynthesisError>;
|
||||
|
||||
fn conditional_verify_prepared<'a, T: 'a + ToBitsGadget<ConstraintF> + ?Sized>(
|
||||
prepared_verification_key: &Self::PreparedVerificationKeyVar,
|
||||
input: impl Iterator<Item = &'a T>,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
proof: &Self::ProofVar,
|
||||
condition: &Boolean<ConstraintF>,
|
||||
) -> Result<(), SynthesisError>;
|
||||
|
||||
@@ -178,7 +178,7 @@ where
|
||||
|
||||
fn conditional_verify<'a, T: 'a + ToBitsGadget<E::Fq> + ?Sized>(
|
||||
vk: &Self::VerificationKeyVar,
|
||||
input: impl Iterator<Item = &'a T>,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
proof: &Self::ProofVar,
|
||||
condition: &Boolean<E::Fq>,
|
||||
) -> Result<(), SynthesisError> {
|
||||
@@ -190,7 +190,7 @@ where
|
||||
|
||||
fn conditional_verify_prepared<'a, T: 'a + ToBitsGadget<E::Fq> + ?Sized>(
|
||||
pvk: &Self::PreparedVerificationKeyVar,
|
||||
mut input: impl Iterator<Item = &'a T>,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
proof: &Self::ProofVar,
|
||||
condition: &Boolean<E::Fq>,
|
||||
) -> Result<(), SynthesisError> {
|
||||
@@ -200,9 +200,10 @@ where
|
||||
let g_psi = {
|
||||
let mut g_psi = pvk.query[0].clone();
|
||||
let mut input_len = 1;
|
||||
let mut input = input.into_iter();
|
||||
for (input, b) in input.by_ref().zip(pvk.query.iter().skip(1)) {
|
||||
let input_bits = input.to_bits()?;
|
||||
g_psi += b.mul_bits(input_bits.iter())?;
|
||||
let input_bits = input.to_bits_le()?;
|
||||
g_psi += b.scalar_mul_le(input_bits.iter())?;
|
||||
input_len += 1;
|
||||
}
|
||||
// Check that the input and the query in the verification are of the
|
||||
@@ -398,7 +399,7 @@ mod test {
|
||||
use super::*;
|
||||
use algebra::{
|
||||
bls12_377::{Bls12_377, Fq, Fr},
|
||||
test_rng, BitIterator, Field, PrimeField,
|
||||
test_rng, BitIteratorLE, Field, PrimeField,
|
||||
};
|
||||
use r1cs_std::{bls12_377::PairingVar as Bls12_377PairingVar, boolean::Boolean, Assignment};
|
||||
use rand::Rng;
|
||||
@@ -486,10 +487,7 @@ mod test {
|
||||
|
||||
{
|
||||
for (i, input) in inputs.into_iter().enumerate() {
|
||||
let mut input_bits = BitIterator::new(input.into_repr()).collect::<Vec<_>>();
|
||||
// Input must be in little-endian, but BitIterator outputs in big-endian.
|
||||
input_bits.reverse();
|
||||
|
||||
let input_bits: Vec<_> = BitIteratorLE::new(input.into_repr()).collect();
|
||||
let input_bits =
|
||||
Vec::<Boolean<Fq>>::new_input(cs.ns(format!("Input {}", i)), || {
|
||||
Ok(input_bits)
|
||||
@@ -505,7 +503,7 @@ mod test {
|
||||
println!("Time to verify!\n\n\n\n");
|
||||
<TestVerifierGadget as NIZKVerifierGadget<TestProofSystem, Fq>>::verify(
|
||||
&vk_gadget,
|
||||
input_gadgets.iter(),
|
||||
&input_gadgets,
|
||||
&proof_gadget,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -637,7 +635,7 @@ mod test_recursive {
|
||||
.map(|chunk| {
|
||||
chunk
|
||||
.iter()
|
||||
.flat_map(|byte| byte.into_bits_le())
|
||||
.flat_map(|byte| byte.to_bits_le().unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@@ -648,7 +646,7 @@ mod test_recursive {
|
||||
TestProofVar1::new_witness(cs.ns("Proof"), || Ok(proof.clone())).unwrap();
|
||||
<TestVerifierGadget1 as NIZKVerifierGadget<TestProofSystem1, MNT6Fq>>::verify(
|
||||
&vk_gadget,
|
||||
input_gadgets.iter(),
|
||||
&input_gadgets,
|
||||
&proof_gadget,
|
||||
)?;
|
||||
Ok(())
|
||||
@@ -721,12 +719,7 @@ mod test_recursive {
|
||||
for (i, input) in inputs.into_iter().enumerate() {
|
||||
let input_gadget =
|
||||
FpVar::new_input(cs.ns(format!("Input {}", i)), || Ok(input)).unwrap();
|
||||
let mut fp_bits = input_gadget.to_bits().unwrap();
|
||||
|
||||
// FpVar::to_bits outputs a big-endian binary representation of
|
||||
// fe_gadget's value, so we have to reverse it to get the little-endian
|
||||
// form.
|
||||
fp_bits.reverse();
|
||||
let mut fp_bits = input_gadget.to_bits_le().unwrap();
|
||||
|
||||
// Use 320 bits per element.
|
||||
for _ in fp_bits.len()..bigint_size {
|
||||
@@ -756,7 +749,7 @@ mod test_recursive {
|
||||
println!("Time to verify!\n\n\n\n");
|
||||
<TestVerifierGadget2 as NIZKVerifierGadget<TestProofSystem2, MNT4Fq>>::verify(
|
||||
&vk_gadget,
|
||||
input_gadgets.iter(),
|
||||
&input_gadgets,
|
||||
&proof_gadget,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -166,7 +166,7 @@ where
|
||||
|
||||
fn conditional_verify<'a, T: 'a + ToBitsGadget<E::Fq> + ?Sized>(
|
||||
vk: &Self::VerificationKeyVar,
|
||||
input: impl Iterator<Item = &'a T>,
|
||||
input: impl IntoIterator<Item = &'a T>,
|
||||
proof: &Self::ProofVar,
|
||||
condition: &Boolean<E::Fq>,
|
||||
) -> Result<(), SynthesisError> {
|
||||
@@ -178,7 +178,7 @@ where
|
||||
|
||||
fn conditional_verify_prepared<'a, T: 'a + ToBitsGadget<E::Fq> + ?Sized>(
|
||||
pvk: &Self::PreparedVerificationKeyVar,
|
||||
mut public_inputs: impl Iterator<Item = &'a T>,
|
||||
public_inputs: impl IntoIterator<Item = &'a T>,
|
||||
proof: &Self::ProofVar,
|
||||
condition: &Boolean<E::Fq>,
|
||||
) -> Result<(), SynthesisError> {
|
||||
@@ -187,8 +187,9 @@ where
|
||||
let g_ic = {
|
||||
let mut g_ic: P::G1Var = pvk.gamma_abc_g1[0].clone();
|
||||
let mut input_len = 1;
|
||||
let mut public_inputs = public_inputs.into_iter();
|
||||
for (input, b) in public_inputs.by_ref().zip(pvk.gamma_abc_g1.iter().skip(1)) {
|
||||
let encoded_input_i: P::G1Var = b.mul_bits(input.to_bits()?.iter())?;
|
||||
let encoded_input_i: P::G1Var = b.scalar_mul_le(input.to_bits_le()?.iter())?;
|
||||
g_ic += encoded_input_i;
|
||||
input_len += 1;
|
||||
}
|
||||
@@ -359,7 +360,7 @@ mod test {
|
||||
use super::*;
|
||||
use algebra::{
|
||||
bls12_377::{Bls12_377, Fq, Fr},
|
||||
test_rng, BitIterator, Field, PrimeField,
|
||||
test_rng, BitIteratorLE, Field, PrimeField,
|
||||
};
|
||||
use r1cs_std::{bls12_377::PairingVar as Bls12_377PairingVar, boolean::Boolean, Assignment};
|
||||
use rand::Rng;
|
||||
@@ -447,9 +448,7 @@ mod test {
|
||||
|
||||
{
|
||||
for (i, input) in inputs.into_iter().enumerate() {
|
||||
let mut input_bits = BitIterator::new(input.into_repr()).collect::<Vec<_>>();
|
||||
// Input must be in little-endian, but BitIterator outputs in big-endian.
|
||||
input_bits.reverse();
|
||||
let input_bits = BitIteratorLE::new(input.into_repr()).collect::<Vec<_>>();
|
||||
|
||||
let input_bits =
|
||||
Vec::<Boolean<Fq>>::new_input(cs.ns(format!("Input {}", i)), || {
|
||||
@@ -466,7 +465,7 @@ mod test {
|
||||
println!("Time to verify!\n\n\n\n");
|
||||
<TestVerifierGadget as NIZKVerifierGadget<TestProofSystem, Fq>>::verify(
|
||||
&vk_gadget,
|
||||
input_gadgets.iter(),
|
||||
&input_gadgets,
|
||||
&proof_gadget,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -598,7 +597,7 @@ mod test_recursive {
|
||||
.map(|chunk| {
|
||||
chunk
|
||||
.iter()
|
||||
.flat_map(|byte| byte.into_bits_le())
|
||||
.flat_map(|byte| byte.to_bits_le().unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@@ -609,7 +608,7 @@ mod test_recursive {
|
||||
TestProofVar1::new_witness(cs.ns("Proof"), || Ok(proof.clone())).unwrap();
|
||||
<TestVerifierGadget1 as NIZKVerifierGadget<TestProofSystem1, MNT6Fq>>::verify(
|
||||
&vk_gadget,
|
||||
input_gadgets.iter(),
|
||||
&input_gadgets,
|
||||
&proof_gadget,
|
||||
)?;
|
||||
Ok(())
|
||||
@@ -682,12 +681,7 @@ mod test_recursive {
|
||||
for (i, input) in inputs.into_iter().enumerate() {
|
||||
let input_gadget =
|
||||
FpVar::new_input(cs.ns(format!("Input {}", i)), || Ok(input)).unwrap();
|
||||
let mut fp_bits = input_gadget.to_bits().unwrap();
|
||||
|
||||
// FpVar::to_bits outputs a big-endian binary representation of
|
||||
// fe_gadget's value, so we have to reverse it to get the little-endian
|
||||
// form.
|
||||
fp_bits.reverse();
|
||||
let mut fp_bits = input_gadget.to_bits_le().unwrap();
|
||||
|
||||
// Use 320 bits per element.
|
||||
for _ in fp_bits.len()..bigint_size {
|
||||
@@ -717,7 +711,7 @@ mod test_recursive {
|
||||
println!("Time to verify!\n\n\n\n");
|
||||
<TestVerifierGadget2 as NIZKVerifierGadget<TestProofSystem2, MNT4Fq>>::verify(
|
||||
&vk_gadget,
|
||||
input_gadgets.iter(),
|
||||
&input_gadgets,
|
||||
&proof_gadget,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -728,7 +722,6 @@ mod test_recursive {
|
||||
println!("=========================================================");
|
||||
}
|
||||
|
||||
// cs.print_named_objects();
|
||||
assert!(cs.is_satisfied().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ impl<F: PrimeField> PRFGadget<Blake2s, F> for Blake2sGadget {
|
||||
let input: Vec<_> = seed
|
||||
.iter()
|
||||
.chain(input)
|
||||
.flat_map(|b| b.into_bits_le())
|
||||
.flat_map(|b| b.to_bits_le().unwrap())
|
||||
.collect();
|
||||
let result: Vec<_> = evaluate_blake2s(&input)?
|
||||
.into_iter()
|
||||
|
||||
@@ -54,7 +54,7 @@ pub trait SignatureScheme {
|
||||
mod test {
|
||||
use crate::signature::{schnorr, *};
|
||||
use algebra::{
|
||||
ed_on_bls12_381::EdwardsProjective as JubJub, groups::Group, test_rng, to_bytes, ToBytes,
|
||||
ed_on_bls12_381::EdwardsProjective as JubJub, groups::Group, test_rng, to_bytes,
|
||||
UniformRand,
|
||||
};
|
||||
use blake2::Blake2s;
|
||||
|
||||
@@ -64,9 +64,9 @@ where
|
||||
let base = parameters.generator.clone();
|
||||
let randomness = randomness
|
||||
.iter()
|
||||
.flat_map(|b| b.into_bits_le())
|
||||
.flat_map(|b| b.to_bits_le().unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
let rand_pk = &public_key.pub_key + &base.mul_bits(randomness.iter())?;
|
||||
let rand_pk = &public_key.pub_key + &base.scalar_mul_le(randomness.iter())?;
|
||||
Ok(PublicKeyVar {
|
||||
pub_key: rand_pk,
|
||||
_group: PhantomData,
|
||||
|
||||
@@ -163,14 +163,12 @@ where
|
||||
let randomized_pk = *public_key;
|
||||
let base = parameters.generator;
|
||||
let mut encoded = C::zero();
|
||||
let mut found_one = false;
|
||||
for bit in bytes_to_bits(randomness).into_iter().rev() {
|
||||
if found_one {
|
||||
encoded.double_in_place();
|
||||
} else {
|
||||
found_one |= bit;
|
||||
}
|
||||
|
||||
for bit in bytes_to_bits(randomness)
|
||||
.into_iter()
|
||||
.rev()
|
||||
.skip_while(|b| !b)
|
||||
{
|
||||
encoded.double_in_place();
|
||||
if bit {
|
||||
encoded.add_assign_mixed(&base)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user