mirror of https://github.com/zcash/halo2.git
chore: instance columns for poseidon bench (#712)
This commit is contained in:
parent
caf9e71b30
commit
9eb8eadbd7
|
@ -4,7 +4,7 @@ use halo2_proofs::{
|
||||||
pasta::Fp,
|
pasta::Fp,
|
||||||
plonk::{
|
plonk::{
|
||||||
create_proof, keygen_pk, keygen_vk, verify_proof, Advice, Circuit, Column,
|
create_proof, keygen_pk, keygen_vk, verify_proof, Advice, Circuit, Column,
|
||||||
ConstraintSystem, Error, SingleVerifier,
|
ConstraintSystem, Error, Instance, SingleVerifier,
|
||||||
},
|
},
|
||||||
poly::commitment::Params,
|
poly::commitment::Params,
|
||||||
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
|
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
|
||||||
|
@ -27,15 +27,13 @@ where
|
||||||
S: Spec<Fp, WIDTH, RATE> + Clone + Copy,
|
S: Spec<Fp, WIDTH, RATE> + Clone + Copy,
|
||||||
{
|
{
|
||||||
message: Value<[Fp; L]>,
|
message: Value<[Fp; L]>,
|
||||||
// For the purpose of this test, witness the result.
|
|
||||||
// TODO: Move this into an instance column.
|
|
||||||
output: Value<Fp>,
|
|
||||||
_spec: PhantomData<S>,
|
_spec: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct MyConfig<const WIDTH: usize, const RATE: usize, const L: usize> {
|
struct MyConfig<const WIDTH: usize, const RATE: usize, const L: usize> {
|
||||||
input: [Column<Advice>; L],
|
input: [Column<Advice>; L],
|
||||||
|
expected: Column<Instance>,
|
||||||
poseidon_config: Pow5Config<Fp, WIDTH, RATE>,
|
poseidon_config: Pow5Config<Fp, WIDTH, RATE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,13 +48,14 @@ where
|
||||||
fn without_witnesses(&self) -> Self {
|
fn without_witnesses(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
message: Value::unknown(),
|
message: Value::unknown(),
|
||||||
output: Value::unknown(),
|
|
||||||
_spec: PhantomData,
|
_spec: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
|
fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
|
||||||
let state = (0..WIDTH).map(|_| meta.advice_column()).collect::<Vec<_>>();
|
let state = (0..WIDTH).map(|_| meta.advice_column()).collect::<Vec<_>>();
|
||||||
|
let expected = meta.instance_column();
|
||||||
|
meta.enable_equality(expected);
|
||||||
let partial_sbox = meta.advice_column();
|
let partial_sbox = meta.advice_column();
|
||||||
|
|
||||||
let rc_a = (0..WIDTH).map(|_| meta.fixed_column()).collect::<Vec<_>>();
|
let rc_a = (0..WIDTH).map(|_| meta.fixed_column()).collect::<Vec<_>>();
|
||||||
|
@ -66,6 +65,7 @@ where
|
||||||
|
|
||||||
Self::Config {
|
Self::Config {
|
||||||
input: state[..RATE].try_into().unwrap(),
|
input: state[..RATE].try_into().unwrap(),
|
||||||
|
expected,
|
||||||
poseidon_config: Pow5Chip::configure::<S>(
|
poseidon_config: Pow5Chip::configure::<S>(
|
||||||
meta,
|
meta,
|
||||||
state.try_into().unwrap(),
|
state.try_into().unwrap(),
|
||||||
|
@ -107,21 +107,14 @@ where
|
||||||
)?;
|
)?;
|
||||||
let output = hasher.hash(layouter.namespace(|| "hash"), message)?;
|
let output = hasher.hash(layouter.namespace(|| "hash"), message)?;
|
||||||
|
|
||||||
layouter.assign_region(
|
layouter.constrain_instance(output.cell(), config.expected, 0)
|
||||||
|| "constrain output",
|
|
||||||
|mut region| {
|
|
||||||
let expected_var =
|
|
||||||
region.assign_advice(|| "load output", config.input[0], 0, || self.output)?;
|
|
||||||
region.constrain_equal(output.cell(), expected_var.cell())
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
struct MySpec<const WIDTH: usize, const RATE: usize>;
|
struct MySpec<const WIDTH: usize, const RATE: usize>;
|
||||||
|
|
||||||
impl Spec<Fp, 3, 2> for MySpec<3, 2> {
|
impl<const WIDTH: usize, const RATE: usize> Spec<Fp, WIDTH, RATE> for MySpec<WIDTH, RATE> {
|
||||||
fn full_rounds() -> usize {
|
fn full_rounds() -> usize {
|
||||||
8
|
8
|
||||||
}
|
}
|
||||||
|
@ -131,63 +124,19 @@ impl Spec<Fp, 3, 2> for MySpec<3, 2> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sbox(val: Fp) -> Fp {
|
fn sbox(val: Fp) -> Fp {
|
||||||
val.pow_vartime([5])
|
val.pow_vartime(&[5])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn secure_mds() -> usize {
|
fn secure_mds() -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn constants() -> (Vec<[Fp; 3]>, Mds<Fp, 3>, Mds<Fp, 3>) {
|
fn constants() -> (Vec<[Fp; WIDTH]>, Mds<Fp, WIDTH>, Mds<Fp, WIDTH>) {
|
||||||
generate_constants::<_, Self, 3, 2>()
|
generate_constants::<_, Self, WIDTH, RATE>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Spec<Fp, 9, 8> for MySpec<9, 8> {
|
const K: u32 = 7;
|
||||||
fn full_rounds() -> usize {
|
|
||||||
8
|
|
||||||
}
|
|
||||||
|
|
||||||
fn partial_rounds() -> usize {
|
|
||||||
56
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sbox(val: Fp) -> Fp {
|
|
||||||
val.pow_vartime([5])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn secure_mds() -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn constants() -> (Vec<[Fp; 9]>, Mds<Fp, 9>, Mds<Fp, 9>) {
|
|
||||||
generate_constants::<_, Self, 9, 8>()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Spec<Fp, 12, 11> for MySpec<12, 11> {
|
|
||||||
fn full_rounds() -> usize {
|
|
||||||
8
|
|
||||||
}
|
|
||||||
|
|
||||||
fn partial_rounds() -> usize {
|
|
||||||
56
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sbox(val: Fp) -> Fp {
|
|
||||||
val.pow_vartime([5])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn secure_mds() -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn constants() -> (Vec<[Fp; 12]>, Mds<Fp, 12>, Mds<Fp, 12>) {
|
|
||||||
generate_constants::<_, Self, 12, 11>()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const K: u32 = 6;
|
|
||||||
|
|
||||||
fn bench_poseidon<S, const WIDTH: usize, const RATE: usize, const L: usize>(
|
fn bench_poseidon<S, const WIDTH: usize, const RATE: usize, const L: usize>(
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -200,7 +149,6 @@ fn bench_poseidon<S, const WIDTH: usize, const RATE: usize, const L: usize>(
|
||||||
|
|
||||||
let empty_circuit = HashCircuit::<S, WIDTH, RATE, L> {
|
let empty_circuit = HashCircuit::<S, WIDTH, RATE, L> {
|
||||||
message: Value::unknown(),
|
message: Value::unknown(),
|
||||||
output: Value::unknown(),
|
|
||||||
_spec: PhantomData,
|
_spec: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,30 +169,49 @@ fn bench_poseidon<S, const WIDTH: usize, const RATE: usize, const L: usize>(
|
||||||
|
|
||||||
let circuit = HashCircuit::<S, WIDTH, RATE, L> {
|
let circuit = HashCircuit::<S, WIDTH, RATE, L> {
|
||||||
message: Value::known(message),
|
message: Value::known(message),
|
||||||
output: Value::known(output),
|
|
||||||
_spec: PhantomData,
|
_spec: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
c.bench_function(&prover_name, |b| {
|
c.bench_function(&prover_name, |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
// Create a proof
|
|
||||||
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
|
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
|
||||||
create_proof(¶ms, &pk, &[circuit], &[&[]], &mut rng, &mut transcript)
|
create_proof(
|
||||||
.expect("proof generation should not fail")
|
¶ms,
|
||||||
|
&pk,
|
||||||
|
&[circuit],
|
||||||
|
&[&[&[output]]],
|
||||||
|
&mut rng,
|
||||||
|
&mut transcript,
|
||||||
|
)
|
||||||
|
.expect("proof generation should not fail")
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a proof
|
// Create a proof
|
||||||
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
|
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
|
||||||
create_proof(¶ms, &pk, &[circuit], &[&[]], &mut rng, &mut transcript)
|
create_proof(
|
||||||
.expect("proof generation should not fail");
|
¶ms,
|
||||||
|
&pk,
|
||||||
|
&[circuit],
|
||||||
|
&[&[&[output]]],
|
||||||
|
&mut rng,
|
||||||
|
&mut transcript,
|
||||||
|
)
|
||||||
|
.expect("proof generation should not fail");
|
||||||
let proof = transcript.finalize();
|
let proof = transcript.finalize();
|
||||||
|
|
||||||
c.bench_function(&verifier_name, |b| {
|
c.bench_function(&verifier_name, |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let strategy = SingleVerifier::new(¶ms);
|
let strategy = SingleVerifier::new(¶ms);
|
||||||
let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
|
let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
|
||||||
assert!(verify_proof(¶ms, pk.get_vk(), strategy, &[&[]], &mut transcript).is_ok());
|
assert!(verify_proof(
|
||||||
|
¶ms,
|
||||||
|
pk.get_vk(),
|
||||||
|
strategy,
|
||||||
|
&[&[&[output]]],
|
||||||
|
&mut transcript
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue