Initial commit to extract crypto-primitives to new crate

This commit is contained in:
Pratyush Mishra
2019-09-24 20:21:49 -07:00
parent 5a78e24e15
commit a244e719d1
33 changed files with 4746 additions and 1 deletions

View File

@@ -0,0 +1,169 @@
use crate::crypto_primitives::commitment::blake2s::Blake2sCommitment;
use r1cs_core::{ConstraintSystem, SynthesisError};
use crate::gadgets::{
prf::blake2s::{blake2s_gadget, Blake2sOutputGadget},
CommitmentGadget,
};
use algebra::{PrimeField, Field};
use r1cs_std::prelude::*;
use std::borrow::Borrow;
#[derive(Clone)]
pub struct Blake2sParametersGadget;
#[derive(Clone)]
pub struct Blake2sRandomnessGadget(pub Vec<UInt8>);
pub struct Blake2sCommitmentGadget;
impl<ConstraintF: PrimeField> CommitmentGadget<Blake2sCommitment, ConstraintF> for Blake2sCommitmentGadget {
type OutputGadget = Blake2sOutputGadget;
type ParametersGadget = Blake2sParametersGadget;
type RandomnessGadget = Blake2sRandomnessGadget;
fn check_commitment_gadget<CS: ConstraintSystem<ConstraintF>>(
mut cs: CS,
_: &Self::ParametersGadget,
input: &[UInt8],
r: &Self::RandomnessGadget,
) -> Result<Self::OutputGadget, SynthesisError> {
let mut input_bits = Vec::with_capacity(512);
for byte in input.into_iter().chain(r.0.iter()) {
input_bits.extend_from_slice(&byte.into_bits_le());
}
let mut result = Vec::new();
for (i, int) in blake2s_gadget(cs.ns(|| "Blake2s Eval"), &input_bits)?
.into_iter()
.enumerate()
{
let chunk = int.to_bytes(&mut cs.ns(|| format!("Result ToBytes {}", i)))?;
result.extend_from_slice(&chunk);
}
Ok(Blake2sOutputGadget(result))
}
}
impl<ConstraintF: Field> AllocGadget<(), ConstraintF> for Blake2sParametersGadget {
fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(_: CS, _: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<()>,
{
Ok(Blake2sParametersGadget)
}
fn alloc_input<F, T, CS: ConstraintSystem<ConstraintF>>(_: CS, _: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<()>,
{
Ok(Blake2sParametersGadget)
}
}
impl<ConstraintF: PrimeField> AllocGadget<[u8; 32], ConstraintF> for Blake2sRandomnessGadget {
#[inline]
fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(cs: CS, value_gen: F) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<[u8; 32]>,
{
let zeros = [0u8; 32];
let value = match value_gen() {
Ok(val) => *(val.borrow()),
Err(_) => zeros,
};
let bytes = <UInt8>::alloc_vec(cs, &value)?;
Ok(Blake2sRandomnessGadget(bytes))
}
#[inline]
fn alloc_input<F, T, CS: ConstraintSystem<ConstraintF>>(
cs: CS,
value_gen: F,
) -> Result<Self, SynthesisError>
where
F: FnOnce() -> Result<T, SynthesisError>,
T: Borrow<[u8; 32]>,
{
let zeros = [0u8; 32];
let value = match value_gen() {
Ok(val) => *(val.borrow()),
Err(_) => zeros,
};
let bytes = <UInt8>::alloc_input_vec(cs, &value)?;
Ok(Blake2sRandomnessGadget(bytes))
}
}
#[cfg(test)]
mod test {
use algebra::fields::bls12_381::Fr;
use rand::{thread_rng, Rng};
use crate::{
crypto_primitives::commitment::{blake2s::Blake2sCommitment, CommitmentScheme},
gadgets::commitment::{
blake2s::{Blake2sCommitmentGadget, Blake2sRandomnessGadget},
CommitmentGadget,
},
};
use r1cs_core::ConstraintSystem;
use r1cs_std::prelude::*;
use r1cs_std::test_constraint_system::TestConstraintSystem;
#[test]
fn commitment_gadget_test() {
let mut cs = TestConstraintSystem::<Fr>::new();
let input = [1u8; 32];
let rng = &mut thread_rng();
type TestCOMM = Blake2sCommitment;
type TestCOMMGadget = Blake2sCommitmentGadget;
let mut randomness = [0u8; 32];
rng.fill(&mut randomness);
let parameters = ();
let primitive_result = Blake2sCommitment::commit(&parameters, &input, &randomness).unwrap();
let mut input_bytes = vec![];
for (byte_i, input_byte) in input.into_iter().enumerate() {
let cs = cs.ns(|| format!("input_byte_gadget_{}", byte_i));
input_bytes.push(UInt8::alloc(cs, || Ok(*input_byte)).unwrap());
}
let mut randomness_bytes = vec![];
for (byte_i, random_byte) in randomness.into_iter().enumerate() {
let cs = cs.ns(|| format!("randomness_byte_gadget_{}", byte_i));
randomness_bytes.push(UInt8::alloc(cs, || Ok(*random_byte)).unwrap());
}
let randomness_bytes = Blake2sRandomnessGadget(randomness_bytes);
let gadget_parameters =
<TestCOMMGadget as CommitmentGadget<TestCOMM, Fr>>::ParametersGadget::alloc(
&mut cs.ns(|| "gadget_parameters"),
|| Ok(&parameters),
)
.unwrap();
let gadget_result =
<TestCOMMGadget as CommitmentGadget<TestCOMM, Fr>>::check_commitment_gadget(
&mut cs.ns(|| "gadget_evaluation"),
&gadget_parameters,
&input_bytes,
&randomness_bytes,
)
.unwrap();
for i in 0..32 {
assert_eq!(primitive_result[i], gadget_result.0[i].get_value().unwrap());
}
assert!(cs.is_satisfied());
}
}

View File

@@ -0,0 +1,30 @@
use super::CommitmentScheme;
use blake2::Blake2s as b2s;
use digest::Digest;
use crate::Error;
use rand::Rng;
pub struct Blake2sCommitment;
impl CommitmentScheme for Blake2sCommitment {
type Parameters = ();
type Randomness = [u8; 32];
type Output = [u8; 32];
fn setup<R: Rng>(_: &mut R) -> Result<Self::Parameters, Error> {
Ok(())
}
fn commit(
_: &Self::Parameters,
input: &[u8],
randomness: &Self::Randomness,
) -> Result<Self::Output, Error> {
let mut h = b2s::new();
h.input(input);
h.input(randomness.as_ref());
let mut result = [0u8; 32];
result.copy_from_slice(&h.result());
Ok(result)
}
}