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::{
|
||||
constants::{
|
||||
load::{OrchardFixedBasesFull, ValueCommitV},
|
||||
load::{NullifierK, OrchardFixedBasesFull, ValueCommitV},
|
||||
MERKLE_DEPTH_ORCHARD,
|
||||
},
|
||||
keys::{
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
|||
ExtractedNoteCommitment,
|
||||
},
|
||||
primitives::{
|
||||
poseidon,
|
||||
poseidon::{self, ConstantLength},
|
||||
redpallas::{SpendAuth, VerificationKey},
|
||||
},
|
||||
spec::NonIdentityPallasPoint,
|
||||
|
@ -35,9 +35,12 @@ use crate::{
|
|||
use gadget::{
|
||||
ecc::{
|
||||
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::{
|
||||
chip::{SinsemillaChip, SinsemillaConfig, SinsemillaHashDomains},
|
||||
merkle::{
|
||||
|
@ -440,6 +443,92 @@ impl plonk::Circuit<pallas::Base> for Circuit {
|
|||
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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use pasta_curves::pallas;
|
||||
|
||||
use ecc::chip::EccChip;
|
||||
use poseidon::Pow5T3Chip as PoseidonChip;
|
||||
use sinsemilla::merkle::chip::MerkleChip;
|
||||
use utilities::plonk::PLONKChip;
|
||||
|
||||
|
@ -25,4 +26,8 @@ impl super::Config {
|
|||
pub(super) fn merkle_chip_2(&self) -> MerkleChip {
|
||||
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`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Pow5T3Config<F: FieldExt> {
|
||||
state: [Column<Advice>; WIDTH],
|
||||
pub(in crate::circuit) state: [Column<Advice>; WIDTH],
|
||||
partial_sbox: Column<Advice>,
|
||||
rc_a: [Column<Fixed>; WIDTH],
|
||||
rc_b: [Column<Fixed>; WIDTH],
|
||||
|
|
Loading…
Reference in New Issue