mirror of https://github.com/zcash/halo2.git
Circuit::synthesize(): Nullifier integrity.
This commit is contained in:
parent
626ee482bf
commit
48b862f13f
|
@ -13,7 +13,7 @@ use pasta_curves::{arithmetic::FieldExt, pallas, vesta};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::{
|
constants::{
|
||||||
load::{OrchardFixedBasesFull, ValueCommitV},
|
load::{NullifierK, OrchardFixedBasesFull, ValueCommitV},
|
||||||
MERKLE_DEPTH_ORCHARD,
|
MERKLE_DEPTH_ORCHARD,
|
||||||
},
|
},
|
||||||
keys::{
|
keys::{
|
||||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||||
ExtractedNoteCommitment,
|
ExtractedNoteCommitment,
|
||||||
},
|
},
|
||||||
primitives::{
|
primitives::{
|
||||||
poseidon,
|
poseidon::{self, ConstantLength},
|
||||||
redpallas::{SpendAuth, VerificationKey},
|
redpallas::{SpendAuth, VerificationKey},
|
||||||
},
|
},
|
||||||
spec::NonIdentityPallasPoint,
|
spec::NonIdentityPallasPoint,
|
||||||
|
@ -35,9 +35,12 @@ use crate::{
|
||||||
use gadget::{
|
use gadget::{
|
||||||
ecc::{
|
ecc::{
|
||||||
chip::{EccChip, EccConfig},
|
chip::{EccChip, EccConfig},
|
||||||
FixedPoint, FixedPointShort, Point,
|
FixedPoint, FixedPointBaseField, FixedPointShort, Point,
|
||||||
|
},
|
||||||
|
poseidon::{
|
||||||
|
Hash as PoseidonHash, Pow5T3Chip as PoseidonChip, Pow5T3Config as PoseidonConfig,
|
||||||
|
StateWord, Word,
|
||||||
},
|
},
|
||||||
poseidon::{Pow5T3Chip as PoseidonChip, Pow5T3Config as PoseidonConfig},
|
|
||||||
sinsemilla::{
|
sinsemilla::{
|
||||||
chip::{SinsemillaChip, SinsemillaConfig, SinsemillaHashDomains},
|
chip::{SinsemillaChip, SinsemillaConfig, SinsemillaHashDomains},
|
||||||
merkle::{
|
merkle::{
|
||||||
|
@ -440,6 +443,92 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
||||||
commitment.add(layouter.namespace(|| "cv_net"), &blind)?
|
commitment.add(layouter.namespace(|| "cv_net"), &blind)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Nullifier integrity
|
||||||
|
// TODO: constrain to equal public input nf_old
|
||||||
|
let _nf_old = {
|
||||||
|
// nk_rho_old = poseidon_hash(nk, rho_old)
|
||||||
|
let nk_rho_old = {
|
||||||
|
let message = [nk, rho_old];
|
||||||
|
|
||||||
|
let poseidon_message = layouter.assign_region(
|
||||||
|
|| "load message",
|
||||||
|
|mut region| {
|
||||||
|
let mut message_word = |i: usize| {
|
||||||
|
let value = message[i].value();
|
||||||
|
let var = region.assign_advice(
|
||||||
|
|| format!("load message_{}", i),
|
||||||
|
config.poseidon_config.state[i],
|
||||||
|
0,
|
||||||
|
|| value.ok_or(plonk::Error::SynthesisError),
|
||||||
|
)?;
|
||||||
|
region.constrain_equal(var, message[i].cell())?;
|
||||||
|
Ok(Word::<_, _, poseidon::OrchardNullifier, 3, 2> {
|
||||||
|
inner: StateWord::new(var, value),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok([message_word(0)?, message_word(1)?])
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let poseidon_hasher = PoseidonHash::init(
|
||||||
|
config.poseidon_chip(),
|
||||||
|
layouter.namespace(|| "Poseidon init"),
|
||||||
|
ConstantLength::<2>,
|
||||||
|
)?;
|
||||||
|
let poseidon_output = poseidon_hasher.hash(
|
||||||
|
layouter.namespace(|| "Poseidon hash (nk, rho_old)"),
|
||||||
|
poseidon_message,
|
||||||
|
)?;
|
||||||
|
let poseidon_output: CellValue<pallas::Base> = poseidon_output.inner.into();
|
||||||
|
poseidon_output
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add hash output to psi using standard PLONK
|
||||||
|
// `scalar` = poseidon_hash(nk, rho_old) + psi_old.
|
||||||
|
//
|
||||||
|
let scalar = {
|
||||||
|
let scalar_val = nk_rho_old
|
||||||
|
.value()
|
||||||
|
.zip(psi_old.value())
|
||||||
|
.map(|(nk_rho_old, psi_old)| nk_rho_old + psi_old);
|
||||||
|
let scalar = self.load_private(
|
||||||
|
layouter.namespace(|| "poseidon_hash(nk, rho_old) + psi_old"),
|
||||||
|
config.advices[0],
|
||||||
|
scalar_val,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
config.plonk_chip().add(
|
||||||
|
layouter.namespace(|| "poseidon_hash(nk, rho_old) + psi_old"),
|
||||||
|
nk_rho_old,
|
||||||
|
psi_old,
|
||||||
|
scalar,
|
||||||
|
Some(pallas::Base::one()),
|
||||||
|
Some(pallas::Base::one()),
|
||||||
|
Some(pallas::Base::one()),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
scalar
|
||||||
|
};
|
||||||
|
|
||||||
|
// Multiply scalar by NullifierK
|
||||||
|
// `product` = [poseidon_hash(nk, rho_old) + psi_old] NullifierK.
|
||||||
|
//
|
||||||
|
let product = {
|
||||||
|
let nullifier_k = FixedPointBaseField::from_inner(ecc_chip.clone(), NullifierK);
|
||||||
|
nullifier_k.mul(
|
||||||
|
layouter.namespace(|| "[poseidon_output + psi_old] NullifierK"),
|
||||||
|
scalar,
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add cm_old to multiplied fixed base to get nf_old
|
||||||
|
// cm_old + [poseidon_output + psi_old] NullifierK
|
||||||
|
cm_old
|
||||||
|
.add(layouter.namespace(|| "nf_old"), &product)?
|
||||||
|
.extract_p()
|
||||||
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use pasta_curves::pallas;
|
use pasta_curves::pallas;
|
||||||
|
|
||||||
use ecc::chip::EccChip;
|
use ecc::chip::EccChip;
|
||||||
|
use poseidon::Pow5T3Chip as PoseidonChip;
|
||||||
use sinsemilla::merkle::chip::MerkleChip;
|
use sinsemilla::merkle::chip::MerkleChip;
|
||||||
use utilities::plonk::PLONKChip;
|
use utilities::plonk::PLONKChip;
|
||||||
|
|
||||||
|
@ -25,4 +26,8 @@ impl super::Config {
|
||||||
pub(super) fn merkle_chip_2(&self) -> MerkleChip {
|
pub(super) fn merkle_chip_2(&self) -> MerkleChip {
|
||||||
MerkleChip::construct(self.merkle_config_2.clone())
|
MerkleChip::construct(self.merkle_config_2.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn poseidon_chip(&self) -> PoseidonChip<pallas::Base> {
|
||||||
|
PoseidonChip::construct(self.poseidon_config.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ const WIDTH: usize = 3;
|
||||||
/// Configuration for an [`Pow5T3Chip`].
|
/// Configuration for an [`Pow5T3Chip`].
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Pow5T3Config<F: FieldExt> {
|
pub struct Pow5T3Config<F: FieldExt> {
|
||||||
state: [Column<Advice>; WIDTH],
|
pub(in crate::circuit) state: [Column<Advice>; WIDTH],
|
||||||
partial_sbox: Column<Advice>,
|
partial_sbox: Column<Advice>,
|
||||||
rc_a: [Column<Fixed>; WIDTH],
|
rc_a: [Column<Fixed>; WIDTH],
|
||||||
rc_b: [Column<Fixed>; WIDTH],
|
rc_b: [Column<Fixed>; WIDTH],
|
||||||
|
|
Loading…
Reference in New Issue