@ -1,121 +0,0 @@ |
|||||
#[macro_use]
|
|
||||
extern crate criterion;
|
|
||||
|
|
||||
use algebra::{curves::bls12_377::Bls12_377, fields::bls12_377::Fr, Field};
|
|
||||
use crypto_primitives::nizk::*;
|
|
||||
use r1cs_core::{ConstraintSynthesizer, ConstraintSystem, SynthesisError};
|
|
||||
|
|
||||
use criterion::Criterion;
|
|
||||
use rand::{thread_rng, Rng};
|
|
||||
|
|
||||
type TestProofSystem = Gm17<Bls12_377, Bench<Fr>, Fr>;
|
|
||||
|
|
||||
struct Bench<F: Field> {
|
|
||||
inputs: Vec<Option<F>>,
|
|
||||
num_constraints: usize,
|
|
||||
}
|
|
||||
|
|
||||
impl<F: Field> ConstraintSynthesizer<F> for Bench<F> {
|
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(
|
|
||||
self,
|
|
||||
cs: &mut CS,
|
|
||||
) -> Result<(), SynthesisError> {
|
|
||||
assert!(self.inputs.len() >= 2);
|
|
||||
assert!(self.num_constraints >= self.inputs.len());
|
|
||||
|
|
||||
let mut variables: Vec<_> = Vec::with_capacity(self.inputs.len());
|
|
||||
for (i, input) in self.inputs.into_iter().enumerate() {
|
|
||||
let input_var = cs.alloc_input(
|
|
||||
|| format!("Input {}", i),
|
|
||||
|| input.ok_or(SynthesisError::AssignmentMissing),
|
|
||||
)?;
|
|
||||
variables.push((input, input_var));
|
|
||||
}
|
|
||||
|
|
||||
for i in 0..self.num_constraints {
|
|
||||
let new_entry = {
|
|
||||
let (input_1_val, input_1_var) = variables[i];
|
|
||||
let (input_2_val, input_2_var) = variables[i + 1];
|
|
||||
let result_val =
|
|
||||
input_1_val.and_then(|input_1| input_2_val.map(|input_2| input_1 * &input_2));
|
|
||||
let result_var = cs.alloc(
|
|
||||
|| format!("Result {}", i),
|
|
||||
|| result_val.ok_or(SynthesisError::AssignmentMissing),
|
|
||||
)?;
|
|
||||
cs.enforce(
|
|
||||
|| format!("Enforce constraint {}", i),
|
|
||||
|lc| lc + input_1_var,
|
|
||||
|lc| lc + input_2_var,
|
|
||||
|lc| lc + result_var,
|
|
||||
);
|
|
||||
(result_val, result_var)
|
|
||||
};
|
|
||||
variables.push(new_entry);
|
|
||||
}
|
|
||||
Ok(())
|
|
||||
}
|
|
||||
}
|
|
||||
|
|
||||
fn gm17_setup(c: &mut Criterion) {
|
|
||||
let num_inputs = 100;
|
|
||||
let num_constraints = num_inputs;
|
|
||||
let rng = &mut thread_rng();
|
|
||||
let mut inputs: Vec<Option<Fr>> = Vec::with_capacity(num_inputs);
|
|
||||
for _ in 0..num_inputs {
|
|
||||
inputs.push(Some(rng.gen()));
|
|
||||
}
|
|
||||
|
|
||||
c.bench_function("gm17_setup", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
TestProofSystem::setup(
|
|
||||
Bench::<Fr> {
|
|
||||
inputs: vec![None; num_inputs],
|
|
||||
num_constraints,
|
|
||||
},
|
|
||||
rng,
|
|
||||
)
|
|
||||
.unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
fn gm17_prove(c: &mut Criterion) {
|
|
||||
let num_inputs = 100;
|
|
||||
let num_constraints = num_inputs;
|
|
||||
let rng = &mut thread_rng();
|
|
||||
let mut inputs: Vec<Option<Fr>> = Vec::with_capacity(num_inputs);
|
|
||||
for _ in 0..num_inputs {
|
|
||||
inputs.push(Some(rng.gen()));
|
|
||||
}
|
|
||||
|
|
||||
let params = TestProofSystem::setup(
|
|
||||
Bench::<Fr> {
|
|
||||
inputs: vec![None; num_inputs],
|
|
||||
num_constraints,
|
|
||||
},
|
|
||||
rng,
|
|
||||
)
|
|
||||
.unwrap();
|
|
||||
|
|
||||
c.bench_function("gm17_prove", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
TestProofSystem::prove(
|
|
||||
¶ms.0,
|
|
||||
Bench {
|
|
||||
inputs: inputs.clone(),
|
|
||||
num_constraints,
|
|
||||
},
|
|
||||
rng,
|
|
||||
)
|
|
||||
.unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
criterion_group! {
|
|
||||
name = nizk_eval;
|
|
||||
config = Criterion::default().sample_size(10);
|
|
||||
targets = gm17_setup, gm17_prove
|
|
||||
}
|
|
||||
|
|
||||
criterion_main!(nizk_eval);
|
|
@ -1,180 +1,89 @@ |
|||||
#[macro_use]
|
#[macro_use]
|
||||
extern crate criterion;
|
extern crate criterion;
|
||||
|
|
||||
mod affine {
|
|
||||
use algebra::ed_on_bls12_377::EdwardsAffine as Edwards;
|
|
||||
use blake2::Blake2s;
|
|
||||
use criterion::Criterion;
|
|
||||
use crypto_primitives::signature::{schnorr::*, SignatureScheme};
|
|
||||
use rand::{self, Rng};
|
|
||||
|
|
||||
type SchnorrEdwards = SchnorrSignature<Edwards, Blake2s>;
|
|
||||
fn schnorr_signature_setup(c: &mut Criterion) {
|
|
||||
c.bench_function("SchnorrEdwardsAffine: Setup", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
SchnorrEdwards::setup(&mut rng).unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
fn schnorr_signature_keygen(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsAffine: KeyGen", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
SchnorrEdwards::keygen(¶meters, &mut rng).unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
fn schnorr_signature_sign(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
let (_, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
|
||||
let message = [100u8; 128];
|
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsAffine: Sign", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
fn schnorr_signature_verify(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
let (pk, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
|
||||
let message = [100u8; 128];
|
|
||||
let signature = SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap();
|
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsAffine: Verify", move |b| {
|
|
||||
b.iter(|| SchnorrEdwards::verify(¶meters, &pk, &message, &signature).unwrap())
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
fn schnorr_signature_randomize_pk(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
let (pk, _) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
|
||||
let randomness: [u8; 32] = rng.gen();
|
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsAffine: Randomize PubKey", move |b| {
|
|
||||
b.iter(|| SchnorrEdwards::randomize_public_key(¶meters, &pk, &randomness).unwrap())
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
fn schnorr_signature_randomize_signature(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
let (_, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
|
||||
let randomness: [u8; 32] = rng.gen();
|
|
||||
let message = [100u8; 128];
|
|
||||
let signature = SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap();
|
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsAffine: Randomize Signature", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
SchnorrEdwards::randomize_signature(¶meters, &signature, &randomness).unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
criterion_group! {
|
|
||||
name = schnorr_sig_affine;
|
|
||||
config = Criterion::default().sample_size(20);
|
|
||||
targets = schnorr_signature_setup, schnorr_signature_keygen, schnorr_signature_sign,
|
|
||||
schnorr_signature_verify, schnorr_signature_randomize_pk, schnorr_signature_randomize_signature
|
|
||||
}
|
|
||||
|
use algebra::ed_on_bls12_377::EdwardsProjective as Edwards;
|
||||
|
use blake2::Blake2s;
|
||||
|
use criterion::Criterion;
|
||||
|
use crypto_primitives::signature::{schnorr::*, SignatureScheme};
|
||||
|
use rand::{self, Rng};
|
||||
|
|
||||
|
type SchnorrEdwards = Schnorr<Edwards, Blake2s>;
|
||||
|
fn schnorr_signature_setup(c: &mut Criterion) {
|
||||
|
c.bench_function("SchnorrEdwards: Setup", move |b| {
|
||||
|
b.iter(|| {
|
||||
|
let mut rng = &mut rand::thread_rng();
|
||||
|
SchnorrEdwards::setup(&mut rng).unwrap()
|
||||
|
})
|
||||
|
});
|
||||
}
|
}
|
||||
|
|
||||
mod projective {
|
|
||||
use algebra::ed_on_bls12_377::EdwardsProjective as Edwards;
|
|
||||
use blake2::Blake2s;
|
|
||||
use criterion::Criterion;
|
|
||||
use crypto_primitives::signature::{schnorr::*, SignatureScheme};
|
|
||||
use rand::{self, Rng};
|
|
||||
|
|
||||
type SchnorrEdwards = SchnorrSignature<Edwards, Blake2s>;
|
|
||||
fn schnorr_signature_setup(c: &mut Criterion) {
|
|
||||
c.bench_function("SchnorrEdwardsProjective: Setup", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
SchnorrEdwards::setup(&mut rng).unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
fn schnorr_signature_keygen(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsProjective: KeyGen", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
SchnorrEdwards::keygen(¶meters, &mut rng).unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
|
|
||||
fn schnorr_signature_sign(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
let (_, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
|
||||
let message = [100u8; 128];
|
|
||||
|
fn schnorr_signature_keygen(c: &mut Criterion) {
|
||||
|
let mut rng = &mut rand::thread_rng();
|
||||
|
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsProjective: Sign", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
|
c.bench_function("SchnorrEdwards: KeyGen", move |b| {
|
||||
|
b.iter(|| {
|
||||
|
let mut rng = &mut rand::thread_rng();
|
||||
|
SchnorrEdwards::keygen(¶meters, &mut rng).unwrap()
|
||||
|
})
|
||||
|
});
|
||||
|
}
|
||||
|
|
||||
fn schnorr_signature_verify(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
let (pk, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
|
||||
let message = [100u8; 128];
|
|
||||
let signature = SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap();
|
|
||||
|
fn schnorr_signature_sign(c: &mut Criterion) {
|
||||
|
let mut rng = &mut rand::thread_rng();
|
||||
|
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
||||
|
let (_, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
||||
|
let message = [100u8; 128];
|
||||
|
|
||||
|
c.bench_function("SchnorrEdwards: Sign", move |b| {
|
||||
|
b.iter(|| {
|
||||
|
let mut rng = &mut rand::thread_rng();
|
||||
|
SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap()
|
||||
|
})
|
||||
|
});
|
||||
|
}
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsProjective: Verify", move |b| {
|
|
||||
b.iter(|| SchnorrEdwards::verify(¶meters, &pk, &message, &signature).unwrap())
|
|
||||
});
|
|
||||
}
|
|
||||
|
fn schnorr_signature_verify(c: &mut Criterion) {
|
||||
|
let mut rng = &mut rand::thread_rng();
|
||||
|
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
||||
|
let (pk, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
||||
|
let message = [100u8; 128];
|
||||
|
let signature = SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap();
|
||||
|
|
||||
fn schnorr_signature_randomize_pk(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
let (pk, _) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
|
||||
let randomness: [u8; 32] = rng.gen();
|
|
||||
|
c.bench_function("SchnorrEdwards: Verify", move |b| {
|
||||
|
b.iter(|| SchnorrEdwards::verify(¶meters, &pk, &message, &signature).unwrap())
|
||||
|
});
|
||||
|
}
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsProjective: Randomize PubKey", move |b| {
|
|
||||
b.iter(|| SchnorrEdwards::randomize_public_key(¶meters, &pk, &randomness).unwrap())
|
|
||||
});
|
|
||||
}
|
|
||||
|
fn schnorr_signature_randomize_pk(c: &mut Criterion) {
|
||||
|
let mut rng = &mut rand::thread_rng();
|
||||
|
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
||||
|
let (pk, _) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
||||
|
let randomness: [u8; 32] = rng.gen();
|
||||
|
|
||||
fn schnorr_signature_randomize_signature(c: &mut Criterion) {
|
|
||||
let mut rng = &mut rand::thread_rng();
|
|
||||
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
|
||||
let (_, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
|
||||
let randomness: [u8; 32] = rng.gen();
|
|
||||
let message = [100u8; 128];
|
|
||||
let signature = SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap();
|
|
||||
|
c.bench_function("SchnorrEdwards: Randomize PubKey", move |b| {
|
||||
|
b.iter(|| SchnorrEdwards::randomize_public_key(¶meters, &pk, &randomness).unwrap())
|
||||
|
});
|
||||
|
}
|
||||
|
|
||||
c.bench_function("SchnorrEdwardsProjective: Randomize Signature", move |b| {
|
|
||||
b.iter(|| {
|
|
||||
SchnorrEdwards::randomize_signature(¶meters, &signature, &randomness).unwrap()
|
|
||||
})
|
|
||||
});
|
|
||||
}
|
|
||||
criterion_group! {
|
|
||||
name = schnorr_sig_projective;
|
|
||||
config = Criterion::default().sample_size(20);
|
|
||||
targets = schnorr_signature_setup, schnorr_signature_keygen, schnorr_signature_sign,
|
|
||||
schnorr_signature_verify, schnorr_signature_randomize_pk, schnorr_signature_randomize_signature
|
|
||||
}
|
|
||||
|
fn schnorr_signature_randomize_signature(c: &mut Criterion) {
|
||||
|
let mut rng = &mut rand::thread_rng();
|
||||
|
let parameters = SchnorrEdwards::setup(&mut rng).unwrap();
|
||||
|
let (_, sk) = SchnorrEdwards::keygen(¶meters, &mut rng).unwrap();
|
||||
|
let randomness: [u8; 32] = rng.gen();
|
||||
|
let message = [100u8; 128];
|
||||
|
let signature = SchnorrEdwards::sign(¶meters, &sk, &message, &mut rng).unwrap();
|
||||
|
|
||||
|
c.bench_function("SchnorrEdwards: Randomize Signature", move |b| {
|
||||
|
b.iter(|| {
|
||||
|
SchnorrEdwards::randomize_signature(¶meters, &signature, &randomness).unwrap()
|
||||
|
})
|
||||
|
});
|
||||
|
}
|
||||
|
criterion_group! {
|
||||
|
name = schnorr_sig;
|
||||
|
config = Criterion::default().sample_size(20);
|
||||
|
targets = schnorr_signature_setup, schnorr_signature_keygen, schnorr_signature_sign,
|
||||
|
schnorr_signature_verify, schnorr_signature_randomize_pk, schnorr_signature_randomize_signature
|
||||
}
|
}
|
||||
use crate::{affine::schnorr_sig_affine, projective::schnorr_sig_projective};
|
|
||||
criterion_main!(schnorr_sig_affine, schnorr_sig_projective);
|
|
||||
|
criterion_main!(schnorr_sig);
|
@ -1,23 +1,23 @@ |
|||||
use crate::CommitmentScheme;
|
|
||||
|
use crate::commitment::CommitmentScheme;
|
||||
use algebra_core::Field;
|
use algebra_core::Field;
|
||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||
use r1cs_core::{ConstraintSystem, SynthesisError};
|
|
||||
|
use r1cs_core::SynthesisError;
|
||||
use r1cs_std::prelude::*;
|
use r1cs_std::prelude::*;
|
||||
|
|
||||
pub trait CommitmentGadget<C: CommitmentScheme, ConstraintF: Field> {
|
pub trait CommitmentGadget<C: CommitmentScheme, ConstraintF: Field> {
|
||||
type OutputGadget: EqGadget<ConstraintF>
|
|
||||
|
type OutputVar: EqGadget<ConstraintF>
|
||||
+ ToBytesGadget<ConstraintF>
|
+ ToBytesGadget<ConstraintF>
|
||||
+ AllocGadget<C::Output, ConstraintF>
|
|
||||
|
+ AllocVar<C::Output, ConstraintF>
|
||||
|
+ R1CSVar<ConstraintF>
|
||||
+ Clone
|
+ Clone
|
||||
+ Sized
|
+ Sized
|
||||
+ Debug;
|
+ Debug;
|
||||
type ParametersGadget: AllocGadget<C::Parameters, ConstraintF> + Clone;
|
|
||||
type RandomnessGadget: AllocGadget<C::Randomness, ConstraintF> + Clone;
|
|
||||
|
type ParametersVar: AllocVar<C::Parameters, ConstraintF> + Clone;
|
||||
|
type RandomnessVar: AllocVar<C::Randomness, ConstraintF> + Clone;
|
||||
|
|
||||
fn check_commitment_gadget<CS: ConstraintSystem<ConstraintF>>(
|
|
||||
cs: CS,
|
|
||||
parameters: &Self::ParametersGadget,
|
|
||||
input: &[UInt8],
|
|
||||
r: &Self::RandomnessGadget,
|
|
||||
) -> Result<Self::OutputGadget, SynthesisError>;
|
|
||||
|
fn commit(
|
||||
|
parameters: &Self::ParametersVar,
|
||||
|
input: &[UInt8<ConstraintF>],
|
||||
|
r: &Self::RandomnessVar,
|
||||
|
) -> Result<Self::OutputVar, SynthesisError>;
|
||||
}
|
}
|
@ -1,62 +1,59 @@ |
|||||
use algebra_core::{Field, PrimeField};
|
|
||||
|
|
||||
use crate::commitment::{
|
use crate::commitment::{
|
||||
injective_map::{InjectiveMap, PedersenCommCompressor},
|
injective_map::{InjectiveMap, PedersenCommCompressor},
|
||||
pedersen::{
|
pedersen::{
|
||||
constraints::{
|
|
||||
PedersenCommitmentGadget, PedersenCommitmentGadgetParameters, PedersenRandomnessGadget,
|
|
||||
},
|
|
||||
PedersenWindow,
|
|
||||
|
constraints::{CommGadget, ParametersVar, RandomnessVar},
|
||||
|
Window,
|
||||
},
|
},
|
||||
CommitmentGadget,
|
|
||||
};
|
};
|
||||
|
|
||||
pub use crate::crh::injective_map::constraints::InjectiveMapGadget;
|
pub use crate::crh::injective_map::constraints::InjectiveMapGadget;
|
||||
use algebra_core::groups::Group;
|
|
||||
use r1cs_core::{ConstraintSystem, SynthesisError};
|
|
||||
use r1cs_std::{groups::GroupGadget, uint8::UInt8};
|
|
||||
|
use algebra_core::{Field, PrimeField, ProjectiveCurve};
|
||||
|
use r1cs_core::SynthesisError;
|
||||
|
use r1cs_std::{
|
||||
|
groups::{CurveVar, GroupOpsBounds},
|
||||
|
uint8::UInt8,
|
||||
|
};
|
||||
|
|
||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||
|
|
||||
pub struct PedersenCommitmentCompressorGadget<G, I, ConstraintF, GG, IG>
|
|
||||
|
type ConstraintF<C> = <<C as ProjectiveCurve>::BaseField as Field>::BasePrimeField;
|
||||
|
|
||||
|
pub struct CommitmentCompressorGadget<C, I, W, GG, IG>
|
||||
where
|
where
|
||||
G: Group,
|
|
||||
I: InjectiveMap<G>,
|
|
||||
ConstraintF: Field,
|
|
||||
GG: GroupGadget<G, ConstraintF>,
|
|
||||
IG: InjectiveMapGadget<G, I, ConstraintF, GG>,
|
|
||||
|
C: ProjectiveCurve,
|
||||
|
I: InjectiveMap<C>,
|
||||
|
W: Window,
|
||||
|
GG: CurveVar<C, ConstraintF<C>>,
|
||||
|
IG: InjectiveMapGadget<C, I, GG>,
|
||||
|
for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
|
||||
{
|
{
|
||||
_compressor: PhantomData<I>,
|
_compressor: PhantomData<I>,
|
||||
_compressor_gadget: PhantomData<IG>,
|
_compressor_gadget: PhantomData<IG>,
|
||||
_crh: PedersenCommitmentGadget<G, ConstraintF, GG>,
|
|
||||
|
_comm: PhantomData<CommGadget<C, GG, W>>,
|
||||
}
|
}
|
||||
|
|
||||
impl<G, I, ConstraintF, GG, IG, W> CommitmentGadget<PedersenCommCompressor<G, I, W>, ConstraintF>
|
|
||||
for PedersenCommitmentCompressorGadget<G, I, ConstraintF, GG, IG>
|
|
||||
|
impl<C, I, GG, IG, W>
|
||||
|
crate::commitment::CommitmentGadget<PedersenCommCompressor<C, I, W>, ConstraintF<C>>
|
||||
|
for CommitmentCompressorGadget<C, I, W, GG, IG>
|
||||
where
|
where
|
||||
G: Group,
|
|
||||
I: InjectiveMap<G>,
|
|
||||
ConstraintF: PrimeField,
|
|
||||
GG: GroupGadget<G, ConstraintF>,
|
|
||||
IG: InjectiveMapGadget<G, I, ConstraintF, GG>,
|
|
||||
W: PedersenWindow,
|
|
||||
|
C: ProjectiveCurve,
|
||||
|
I: InjectiveMap<C>,
|
||||
|
GG: CurveVar<C, ConstraintF<C>>,
|
||||
|
ConstraintF<C>: PrimeField,
|
||||
|
IG: InjectiveMapGadget<C, I, GG>,
|
||||
|
W: Window,
|
||||
|
for<'a> &'a GG: GroupOpsBounds<'a, C, GG>,
|
||||
{
|
{
|
||||
type OutputGadget = IG::OutputGadget;
|
|
||||
type ParametersGadget = PedersenCommitmentGadgetParameters<G, W, ConstraintF>;
|
|
||||
type RandomnessGadget = PedersenRandomnessGadget;
|
|
||||
|
type OutputVar = IG::OutputVar;
|
||||
|
type ParametersVar = ParametersVar<C, GG>;
|
||||
|
type RandomnessVar = RandomnessVar<ConstraintF<C>>;
|
||||
|
|
||||
fn check_commitment_gadget<CS: ConstraintSystem<ConstraintF>>(
|
|
||||
mut cs: CS,
|
|
||||
parameters: &Self::ParametersGadget,
|
|
||||
input: &[UInt8],
|
|
||||
r: &Self::RandomnessGadget,
|
|
||||
) -> Result<Self::OutputGadget, SynthesisError> {
|
|
||||
let result = PedersenCommitmentGadget::<G, ConstraintF, GG>::check_commitment_gadget(
|
|
||||
cs.ns(|| "PedersenComm"),
|
|
||||
parameters,
|
|
||||
input,
|
|
||||
r,
|
|
||||
)?;
|
|
||||
IG::evaluate_map(cs.ns(|| "InjectiveMap"), &result)
|
|
||||
|
fn commit(
|
||||
|
parameters: &Self::ParametersVar,
|
||||
|
input: &[UInt8<ConstraintF<C>>],
|
||||
|
r: &Self::RandomnessVar,
|
||||
|
) -> Result<Self::OutputVar, SynthesisError> {
|
||||
|
let result = CommGadget::<C, GG, W>::commit(parameters, input, r)?;
|
||||
|
IG::evaluate(&result)
|
||||
}
|
}
|
||||
}
|
}
|
@ -1,47 +1,59 @@ |
|||||
use algebra_core::Field;
|
use algebra_core::Field;
|
||||
use r1cs_core::{ConstraintSystem, SynthesisError};
|
|
||||
|
use core::borrow::Borrow;
|
||||
|
use r1cs_core::{Namespace, SynthesisError};
|
||||
use r1cs_std::prelude::*;
|
use r1cs_std::prelude::*;
|
||||
|
|
||||
use crate::nizk::NIZK;
|
use crate::nizk::NIZK;
|
||||
|
|
||||
pub trait NIZKVerifierGadget<N: NIZK, ConstraintF: Field> {
|
pub trait NIZKVerifierGadget<N: NIZK, ConstraintF: Field> {
|
||||
type PreparedVerificationKeyGadget;
|
|
||||
type VerificationKeyGadget: AllocGadget<N::VerificationParameters, ConstraintF>
|
|
||||
|
type PreparedVerificationKeyVar;
|
||||
|
type VerificationKeyVar: AllocVar<N::VerificationParameters, ConstraintF>
|
||||
+ ToBytesGadget<ConstraintF>;
|
+ ToBytesGadget<ConstraintF>;
|
||||
type ProofGadget: AllocGadget<N::Proof, ConstraintF>;
|
|
||||
|
type ProofVar: AllocVar<N::Proof, ConstraintF>;
|
||||
|
|
||||
fn check_verify<'a, CS, I, T>(
|
|
||||
cs: CS,
|
|
||||
verification_key: &Self::VerificationKeyGadget,
|
|
||||
input: I,
|
|
||||
proof: &Self::ProofGadget,
|
|
||||
) -> Result<(), SynthesisError>
|
|
||||
where
|
|
||||
CS: ConstraintSystem<ConstraintF>,
|
|
||||
I: Iterator<Item = &'a T>,
|
|
||||
T: 'a + ToBitsGadget<ConstraintF> + ?Sized;
|
|
||||
|
/// Optionally allocates `N::Proof` in `cs` without performing
|
||||
|
/// subgroup checks.
|
||||
|
///
|
||||
|
/// The default implementation doesn't omit these checks.
|
||||
|
fn new_proof_unchecked<T: Borrow<N::Proof>>(
|
||||
|
cs: impl Into<Namespace<ConstraintF>>,
|
||||
|
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
|
mode: AllocationMode,
|
||||
|
) -> Result<Self::ProofVar, SynthesisError> {
|
||||
|
Self::ProofVar::new_variable(cs, f, mode)
|
||||
|
}
|
||||
|
|
||||
fn conditional_check_verify<'a, CS, I, T>(
|
|
||||
cs: CS,
|
|
||||
verification_key: &Self::VerificationKeyGadget,
|
|
||||
input: I,
|
|
||||
proof: &Self::ProofGadget,
|
|
||||
condition: &Boolean,
|
|
||||
) -> Result<(), SynthesisError>
|
|
||||
where
|
|
||||
CS: ConstraintSystem<ConstraintF>,
|
|
||||
I: Iterator<Item = &'a T>,
|
|
||||
T: 'a + ToBitsGadget<ConstraintF> + ?Sized;
|
|
||||
|
/// Optionally allocates `N::VerificationParameters` in `cs`
|
||||
|
/// without performing subgroup checks.
|
||||
|
///
|
||||
|
/// The default implementation doesn't omit these checks.
|
||||
|
fn new_verification_key_unchecked<T: Borrow<N::VerificationParameters>>(
|
||||
|
cs: impl Into<Namespace<ConstraintF>>,
|
||||
|
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
|
mode: AllocationMode,
|
||||
|
) -> Result<Self::VerificationKeyVar, SynthesisError> {
|
||||
|
Self::VerificationKeyVar::new_variable(cs, f, mode)
|
||||
|
}
|
||||
|
|
||||
fn conditional_check_verify_prepared<'a, CS, I, T>(
|
|
||||
cs: CS,
|
|
||||
prepared_verification_key: &Self::PreparedVerificationKeyGadget,
|
|
||||
input: I,
|
|
||||
proof: &Self::ProofGadget,
|
|
||||
condition: &Boolean,
|
|
||||
) -> Result<(), SynthesisError>
|
|
||||
where
|
|
||||
CS: ConstraintSystem<ConstraintF>,
|
|
||||
I: Iterator<Item = &'a T>,
|
|
||||
T: 'a + ToBitsGadget<ConstraintF> + ?Sized;
|
|
||||
|
fn verify<'a, T: 'a + ToBitsGadget<ConstraintF> + ?Sized>(
|
||||
|
verification_key: &Self::VerificationKeyVar,
|
||||
|
input: impl Iterator<Item = &'a T>,
|
||||
|
proof: &Self::ProofVar,
|
||||
|
) -> Result<(), SynthesisError> {
|
||||
|
Self::conditional_verify(verification_key, input, proof, &Boolean::constant(true))
|
||||
|
}
|
||||
|
|
||||
|
fn conditional_verify<'a, T: 'a + ToBitsGadget<ConstraintF> + ?Sized>(
|
||||
|
verification_key: &Self::VerificationKeyVar,
|
||||
|
input: impl Iterator<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>,
|
||||
|
proof: &Self::ProofVar,
|
||||
|
condition: &Boolean<ConstraintF>,
|
||||
|
) -> Result<(), SynthesisError>;
|
||||
}
|
}
|
@ -1,21 +1,20 @@ |
|||||
use algebra_core::Field;
|
use algebra_core::Field;
|
||||
use r1cs_core::{ConstraintSystem, SynthesisError};
|
|
||||
|
use r1cs_core::SynthesisError;
|
||||
use r1cs_std::prelude::*;
|
use r1cs_std::prelude::*;
|
||||
|
|
||||
use crate::signature::SignatureScheme;
|
use crate::signature::SignatureScheme;
|
||||
|
|
||||
pub trait SigRandomizePkGadget<S: SignatureScheme, ConstraintF: Field> {
|
pub trait SigRandomizePkGadget<S: SignatureScheme, ConstraintF: Field> {
|
||||
type ParametersGadget: AllocGadget<S::Parameters, ConstraintF> + Clone;
|
|
||||
|
type ParametersVar: AllocVar<S::Parameters, ConstraintF> + Clone;
|
||||
|
|
||||
type PublicKeyGadget: ToBytesGadget<ConstraintF>
|
|
||||
|
type PublicKeyVar: ToBytesGadget<ConstraintF>
|
||||
+ EqGadget<ConstraintF>
|
+ EqGadget<ConstraintF>
|
||||
+ AllocGadget<S::PublicKey, ConstraintF>
|
|
||||
|
+ AllocVar<S::PublicKey, ConstraintF>
|
||||
+ Clone;
|
+ Clone;
|
||||
|
|
||||
fn check_randomization_gadget<CS: ConstraintSystem<ConstraintF>>(
|
|
||||
cs: CS,
|
|
||||
parameters: &Self::ParametersGadget,
|
|
||||
public_key: &Self::PublicKeyGadget,
|
|
||||
randomness: &[UInt8],
|
|
||||
) -> Result<Self::PublicKeyGadget, SynthesisError>;
|
|
||||
|
fn randomize(
|
||||
|
parameters: &Self::ParametersVar,
|
||||
|
public_key: &Self::PublicKeyVar,
|
||||
|
randomness: &[UInt8<ConstraintF>],
|
||||
|
) -> Result<Self::PublicKeyVar, SynthesisError>;
|
||||
}
|
}
|
@ -1,242 +1,157 @@ |
|||||
use crate::Vec;
|
use crate::Vec;
|
||||
use algebra_core::{groups::Group, Field};
|
|
||||
use r1cs_core::{ConstraintSystem, SynthesisError};
|
|
||||
|
use algebra_core::{Field, ProjectiveCurve};
|
||||
|
use r1cs_core::{Namespace, SynthesisError};
|
||||
use r1cs_std::prelude::*;
|
use r1cs_std::prelude::*;
|
||||
|
|
||||
use crate::signature::SigRandomizePkGadget;
|
use crate::signature::SigRandomizePkGadget;
|
||||
|
|
||||
use core::{borrow::Borrow, marker::PhantomData};
|
use core::{borrow::Borrow, marker::PhantomData};
|
||||
|
|
||||
use crate::signature::schnorr::{SchnorrPublicKey, SchnorrSigParameters, SchnorrSignature};
|
|
||||
|
use crate::signature::schnorr::{Parameters, PublicKey, Schnorr};
|
||||
use digest::Digest;
|
use digest::Digest;
|
||||
|
|
||||
pub struct SchnorrSigGadgetParameters<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>>
|
|
||||
{
|
|
||||
generator: GG,
|
|
||||
_group: PhantomData<*const G>,
|
|
||||
_engine: PhantomData<*const ConstraintF>,
|
|
||||
}
|
|
||||
|
type ConstraintF<C> = <<C as ProjectiveCurve>::BaseField as Field>::BasePrimeField;
|
||||
|
|
||||
impl<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> Clone
|
|
||||
for SchnorrSigGadgetParameters<G, ConstraintF, GG>
|
|
||||
|
#[derive(Clone)]
|
||||
|
pub struct ParametersVar<C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>>
|
||||
|
where
|
||||
|
for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
|
||||
{
|
{
|
||||
fn clone(&self) -> Self {
|
|
||||
Self {
|
|
||||
generator: self.generator.clone(),
|
|
||||
_group: PhantomData,
|
|
||||
_engine: PhantomData,
|
|
||||
}
|
|
||||
}
|
|
||||
|
generator: GC,
|
||||
|
_curve: PhantomData<C>,
|
||||
}
|
}
|
||||
|
|
||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||
#[derivative(
|
#[derivative(
|
||||
Debug(bound = "G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>"),
|
|
||||
Clone(bound = "G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>"),
|
|
||||
PartialEq(bound = "G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>"),
|
|
||||
Eq(bound = "G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>")
|
|
||||
|
Debug(bound = "C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>"),
|
||||
|
Clone(bound = "C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>")
|
||||
)]
|
)]
|
||||
pub struct SchnorrSigGadgetPk<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> {
|
|
||||
pub_key: GG,
|
|
||||
#[doc(hidden)]
|
|
||||
_group: PhantomData<*const G>,
|
|
||||
|
pub struct PublicKeyVar<C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>>
|
||||
|
where
|
||||
|
for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
|
||||
|
{
|
||||
|
pub_key: GC,
|
||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||
_engine: PhantomData<*const ConstraintF>,
|
|
||||
|
_group: PhantomData<*const C>,
|
||||
}
|
}
|
||||
|
|
||||
pub struct SchnorrRandomizePkGadget<G: Group, ConstraintF: Field, GG: GroupGadget<G, ConstraintF>> {
|
|
||||
#[doc(hidden)]
|
|
||||
_group: PhantomData<*const G>,
|
|
||||
|
pub struct SchnorrRandomizePkGadget<C: ProjectiveCurve, GC: CurveVar<C, ConstraintF<C>>>
|
||||
|
where
|
||||
|
for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
|
||||
|
{
|
||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||
_group_gadget: PhantomData<*const GG>,
|
|
||||
|
_group: PhantomData<*const C>,
|
||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||
_engine: PhantomData<*const ConstraintF>,
|
|
||||
|
_group_gadget: PhantomData<*const GC>,
|
||||
}
|
}
|
||||
|
|
||||
impl<G, GG, D, ConstraintF> SigRandomizePkGadget<SchnorrSignature<G, D>, ConstraintF>
|
|
||||
for SchnorrRandomizePkGadget<G, ConstraintF, GG>
|
|
||||
|
impl<C, GC, D> SigRandomizePkGadget<Schnorr<C, D>, ConstraintF<C>>
|
||||
|
for SchnorrRandomizePkGadget<C, GC>
|
||||
where
|
where
|
||||
G: Group,
|
|
||||
GG: GroupGadget<G, ConstraintF>,
|
|
||||
|
C: ProjectiveCurve,
|
||||
|
GC: CurveVar<C, ConstraintF<C>>,
|
||||
D: Digest + Send + Sync,
|
D: Digest + Send + Sync,
|
||||
ConstraintF: Field,
|
|
||||
|
for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
|
||||
{
|
{
|
||||
type ParametersGadget = SchnorrSigGadgetParameters<G, ConstraintF, GG>;
|
|
||||
type PublicKeyGadget = SchnorrSigGadgetPk<G, ConstraintF, GG>;
|
|
||||
|
|
||||
fn check_randomization_gadget<CS: ConstraintSystem<ConstraintF>>(
|
|
||||
mut cs: CS,
|
|
||||
parameters: &Self::ParametersGadget,
|
|
||||
public_key: &Self::PublicKeyGadget,
|
|
||||
randomness: &[UInt8],
|
|
||||
) -> Result<Self::PublicKeyGadget, SynthesisError> {
|
|
||||
|
type ParametersVar = ParametersVar<C, GC>;
|
||||
|
type PublicKeyVar = PublicKeyVar<C, GC>;
|
||||
|
|
||||
|
fn randomize(
|
||||
|
parameters: &Self::ParametersVar,
|
||||
|
public_key: &Self::PublicKeyVar,
|
||||
|
randomness: &[UInt8<ConstraintF<C>>],
|
||||
|
) -> Result<Self::PublicKeyVar, SynthesisError> {
|
||||
let base = parameters.generator.clone();
|
let base = parameters.generator.clone();
|
||||
let randomness = randomness
|
let randomness = randomness
|
||||
.iter()
|
.iter()
|
||||
.flat_map(|b| b.into_bits_le())
|
.flat_map(|b| b.into_bits_le())
|
||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||
let rand_pk = base.mul_bits(
|
|
||||
&mut cs.ns(|| "Compute Randomizer"),
|
|
||||
&public_key.pub_key,
|
|
||||
randomness.iter(),
|
|
||||
)?;
|
|
||||
Ok(SchnorrSigGadgetPk {
|
|
||||
|
let rand_pk = &public_key.pub_key + &base.mul_bits(randomness.iter())?;
|
||||
|
Ok(PublicKeyVar {
|
||||
pub_key: rand_pk,
|
pub_key: rand_pk,
|
||||
_group: PhantomData,
|
_group: PhantomData,
|
||||
_engine: PhantomData,
|
|
||||
})
|
})
|
||||
}
|
}
|
||||
}
|
}
|
||||
|
|
||||
impl<G, ConstraintF, GG, D> AllocGadget<SchnorrSigParameters<G, D>, ConstraintF>
|
|
||||
for SchnorrSigGadgetParameters<G, ConstraintF, GG>
|
|
||||
|
impl<C, GC, D> AllocVar<Parameters<C, D>, ConstraintF<C>> for ParametersVar<C, GC>
|
||||
where
|
where
|
||||
G: Group,
|
|
||||
ConstraintF: Field,
|
|
||||
GG: GroupGadget<G, ConstraintF>,
|
|
||||
|
C: ProjectiveCurve,
|
||||
|
GC: CurveVar<C, ConstraintF<C>>,
|
||||
D: Digest,
|
D: Digest,
|
||||
|
for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
|
||||
{
|
{
|
||||
fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>(
|
|
||||
cs: CS,
|
|
||||
val: T,
|
|
||||
) -> Result<Self, SynthesisError>
|
|
||||
where
|
|
||||
T: Borrow<SchnorrSigParameters<G, D>>,
|
|
||||
{
|
|
||||
let generator = GG::alloc_constant(cs, val.borrow().generator)?;
|
|
||||
|
fn new_variable<T: Borrow<Parameters<C, D>>>(
|
||||
|
cs: impl Into<Namespace<ConstraintF<C>>>,
|
||||
|
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
|
mode: AllocationMode,
|
||||
|
) -> Result<Self, SynthesisError> {
|
||||
|
let generator = GC::new_variable(cs, || f().map(|g| g.borrow().generator), mode)?;
|
||||
Ok(Self {
|
Ok(Self {
|
||||
generator,
|
generator,
|
||||
_engine: PhantomData,
|
|
||||
_group: PhantomData,
|
|
||||
})
|
|
||||
}
|
|
||||
|
|
||||
fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(cs: CS, f: F) -> Result<Self, SynthesisError>
|
|
||||
where
|
|
||||
F: FnOnce() -> Result<T, SynthesisError>,
|
|
||||
T: Borrow<SchnorrSigParameters<G, D>>,
|
|
||||
{
|
|
||||
let generator = GG::alloc_checked(cs, || f().map(|pp| pp.borrow().generator))?;
|
|
||||
Ok(Self {
|
|
||||
generator,
|
|
||||
_engine: PhantomData,
|
|
||||
_group: PhantomData,
|
|
||||
})
|
|
||||
}
|
|
||||
|
|
||||
fn alloc_input<F, T, CS: ConstraintSystem<ConstraintF>>(
|
|
||||
cs: CS,
|
|
||||
f: F,
|
|
||||
) -> Result<Self, SynthesisError>
|
|
||||
where
|
|
||||
F: FnOnce() -> Result<T, SynthesisError>,
|
|
||||
T: Borrow<SchnorrSigParameters<G, D>>,
|
|
||||
{
|
|
||||
let generator = GG::alloc_input(cs, || f().map(|pp| pp.borrow().generator))?;
|
|
||||
Ok(Self {
|
|
||||
generator,
|
|
||||
_engine: PhantomData,
|
|
||||
_group: PhantomData,
|
|
||||
|
_curve: PhantomData,
|
||||
})
|
})
|
||||
}
|
}
|
||||
}
|
}
|
||||
|
|
||||
impl<G, ConstraintF, GG> AllocGadget<SchnorrPublicKey<G>, ConstraintF>
|
|
||||
for SchnorrSigGadgetPk<G, ConstraintF, GG>
|
|
||||
|
impl<C, GC> AllocVar<PublicKey<C>, ConstraintF<C>> for PublicKeyVar<C, GC>
|
||||
where
|
where
|
||||
G: Group,
|
|
||||
ConstraintF: Field,
|
|
||||
GG: GroupGadget<G, ConstraintF>,
|
|
||||
|
C: ProjectiveCurve,
|
||||
|
GC: CurveVar<C, ConstraintF<C>>,
|
||||
|
for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
|
||||
{
|
{
|
||||
fn alloc_constant<T, CS: ConstraintSystem<ConstraintF>>(
|
|
||||
cs: CS,
|
|
||||
val: T,
|
|
||||
) -> Result<Self, SynthesisError>
|
|
||||
where
|
|
||||
T: Borrow<SchnorrPublicKey<G>>,
|
|
||||
{
|
|
||||
let pub_key = GG::alloc_constant(cs, val.borrow())?;
|
|
||||
|
fn new_variable<T: Borrow<PublicKey<C>>>(
|
||||
|
cs: impl Into<Namespace<ConstraintF<C>>>,
|
||||
|
f: impl FnOnce() -> Result<T, SynthesisError>,
|
||||
|
mode: AllocationMode,
|
||||
|
) -> Result<Self, SynthesisError> {
|
||||
|
let pub_key = GC::new_variable(cs, f, mode)?;
|
||||
Ok(Self {
|
Ok(Self {
|
||||
pub_key,
|
pub_key,
|
||||
_engine: PhantomData,
|
|
||||
_group: PhantomData,
|
|
||||
})
|
|
||||
}
|
|
||||
|
|
||||
fn alloc<F, T, CS: ConstraintSystem<ConstraintF>>(cs: CS, f: F) -> Result<Self, SynthesisError>
|
|
||||
where
|
|
||||
F: FnOnce() -> Result<T, SynthesisError>,
|
|
||||
T: Borrow<SchnorrPublicKey<G>>,
|
|
||||
{
|
|
||||
let pub_key = GG::alloc_input(cs, || f().map(|pk| *pk.borrow()))?;
|
|
||||
Ok(Self {
|
|
||||
pub_key,
|
|
||||
_engine: PhantomData,
|
|
||||
_group: PhantomData,
|
|
||||
})
|
|
||||
}
|
|
||||
|
|
||||
fn alloc_input<F, T, CS: ConstraintSystem<ConstraintF>>(
|
|
||||
cs: CS,
|
|
||||
f: F,
|
|
||||
) -> Result<Self, SynthesisError>
|
|
||||
where
|
|
||||
F: FnOnce() -> Result<T, SynthesisError>,
|
|
||||
T: Borrow<SchnorrPublicKey<G>>,
|
|
||||
{
|
|
||||
let pub_key = GG::alloc_input(cs, || f().map(|pk| *pk.borrow()))?;
|
|
||||
Ok(Self {
|
|
||||
pub_key,
|
|
||||
_engine: PhantomData,
|
|
||||
_group: PhantomData,
|
_group: PhantomData,
|
||||
})
|
})
|
||||
}
|
}
|
||||
}
|
}
|
||||
|
|
||||
impl<G, ConstraintF, GG> ConditionalEqGadget<ConstraintF> for SchnorrSigGadgetPk<G, ConstraintF, GG>
|
|
||||
|
impl<C, GC> EqGadget<ConstraintF<C>> for PublicKeyVar<C, GC>
|
||||
where
|
where
|
||||
G: Group,
|
|
||||
ConstraintF: Field,
|
|
||||
GG: GroupGadget<G, ConstraintF>,
|
|
||||
|
C: ProjectiveCurve,
|
||||
|
GC: CurveVar<C, ConstraintF<C>>,
|
||||
|
for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
|
||||
{
|
{
|
||||
#[inline]
|
#[inline]
|
||||
fn conditional_enforce_equal<CS: ConstraintSystem<ConstraintF>>(
|
|
||||
|
fn is_eq(&self, other: &Self) -> Result<Boolean<ConstraintF<C>>, SynthesisError> {
|
||||
|
self.pub_key.is_eq(&other.pub_key)
|
||||
|
}
|
||||
|
|
||||
|
#[inline]
|
||||
|
fn conditional_enforce_equal(
|
||||
&self,
|
&self,
|
||||
mut cs: CS,
|
|
||||
other: &Self,
|
other: &Self,
|
||||
condition: &Boolean,
|
|
||||
|
condition: &Boolean<ConstraintF<C>>,
|
||||
) -> Result<(), SynthesisError> {
|
) -> Result<(), SynthesisError> {
|
||||
self.pub_key.conditional_enforce_equal(
|
|
||||
&mut cs.ns(|| "PubKey equality"),
|
|
||||
&other.pub_key,
|
|
||||
condition,
|
|
||||
)?;
|
|
||||
Ok(())
|
|
||||
|
self.pub_key
|
||||
|
.conditional_enforce_equal(&other.pub_key, condition)
|
||||
}
|
}
|
||||
|
|
||||
fn cost() -> usize {
|
|
||||
<GG as ConditionalEqGadget<ConstraintF>>::cost()
|
|
||||
|
#[inline]
|
||||
|
fn conditional_enforce_not_equal(
|
||||
|
&self,
|
||||
|
other: &Self,
|
||||
|
condition: &Boolean<ConstraintF<C>>,
|
||||
|
) -> Result<(), SynthesisError> {
|
||||
|
self.pub_key
|
||||
|
.conditional_enforce_not_equal(&other.pub_key, condition)
|
||||
}
|
}
|
||||
}
|
}
|
||||
|
|
||||
impl<G, ConstraintF, GG> EqGadget<ConstraintF> for SchnorrSigGadgetPk<G, ConstraintF, GG>
|
|
||||
where
|
|
||||
G: Group,
|
|
||||
ConstraintF: Field,
|
|
||||
GG: GroupGadget<G, ConstraintF>,
|
|
||||
{
|
|
||||
}
|
|
||||
|
|
||||
impl<G, ConstraintF, GG> ToBytesGadget<ConstraintF> for SchnorrSigGadgetPk<G, ConstraintF, GG>
|
|
||||
|
impl<C, GC> ToBytesGadget<ConstraintF<C>> for PublicKeyVar<C, GC>
|
||||
where
|
where
|
||||
G: Group,
|
|
||||
ConstraintF: Field,
|
|
||||
GG: GroupGadget<G, ConstraintF>,
|
|
||||
|
C: ProjectiveCurve,
|
||||
|
GC: CurveVar<C, ConstraintF<C>>,
|
||||
|
for<'a> &'a GC: GroupOpsBounds<'a, C, GC>,
|
||||
{
|
{
|
||||
fn to_bytes<CS: ConstraintSystem<ConstraintF>>(
|
|
||||
&self,
|
|
||||
mut cs: CS,
|
|
||||
) -> Result<Vec<UInt8>, SynthesisError> {
|
|
||||
self.pub_key.to_bytes(&mut cs.ns(|| "PubKey To Bytes"))
|
|
||||
|
fn to_bytes(&self) -> Result<Vec<UInt8<ConstraintF<C>>>, SynthesisError> {
|
||||
|
self.pub_key.to_bytes()
|
||||
}
|
}
|
||||
}
|
}
|