From ebb7dae0635ad90834bd52d169dd8cc1a572e38f Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 19 Jun 2021 10:59:39 +0800 Subject: [PATCH] sinsemilla::chip.rs: Add Sinsemilla chip. The chip that will implement SinsemillaInstructions. --- src/circuit/gadget/sinsemilla.rs | 2 +- src/circuit/gadget/sinsemilla/chip.rs | 192 ++++++++++++++++++++++++++ 2 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 src/circuit/gadget/sinsemilla/chip.rs diff --git a/src/circuit/gadget/sinsemilla.rs b/src/circuit/gadget/sinsemilla.rs index d24ddb79..e9e6384c 100644 --- a/src/circuit/gadget/sinsemilla.rs +++ b/src/circuit/gadget/sinsemilla.rs @@ -6,7 +6,7 @@ use crate::circuit::gadget::{ use halo2::{arithmetic::CurveAffine, circuit::Layouter, plonk::Error}; use std::fmt::Debug; -// pub mod chip; +pub mod chip; mod message; // pub use chip::{SinsemillaChip, SinsemillaConfig}; diff --git a/src/circuit/gadget/sinsemilla/chip.rs b/src/circuit/gadget/sinsemilla/chip.rs new file mode 100644 index 00000000..95c26af3 --- /dev/null +++ b/src/circuit/gadget/sinsemilla/chip.rs @@ -0,0 +1,192 @@ +use super::{ + message::{Message, MessagePiece}, + HashDomains, SinsemillaInstructions, +}; +use crate::{ + circuit::gadget::{ + ecc::chip::EccPoint, + utilities::{CellValue, Var}, + }, + primitives::sinsemilla::{ + self, Q_COMMIT_IVK_M_GENERATOR, Q_MERKLE_CRH, Q_NOTE_COMMITMENT_M_GENERATOR, + }, +}; + +use ff::PrimeField; +use halo2::{ + arithmetic::{CurveAffine, FieldExt}, + circuit::{Chip, Layouter}, + plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation, Selector}, + poly::Rotation, +}; +use pasta_curves::pallas; + +use std::convert::TryInto; + +// mod generator_table; +// pub use generator_table::get_s_by_idx; +// use generator_table::GeneratorTableConfig; + +// mod hash_to_point; + +/// Configuration for the Sinsemilla hash chip +#[derive(Eq, PartialEq, Clone, Debug)] +pub struct SinsemillaConfig { + // Selector used in the lookup argument as well as Sinsemilla custom gates. + q_sinsemilla1: Selector, + // Fixed column used in Sinsemilla custom gates. + q_sinsemilla2: Column, + // Fixed column used to constrain hash initialization to be consistent with + // the y-coordinate of the domain Q. + fixed_y_q: Column, + // Advice column used to store the x-coordinate of the accumulator at each + // iteration of the hash. + x_a: Column, + // Advice column used to store the x-coordinate of the generator corresponding + // to the message word at each iteration of the hash. This is looked up in the + // generator table. + x_p: Column, + // Advice column used to load the message. + bits: Column, + // Advice column used to store the lambda_1 intermediate value at each + // iteration. + lambda_1: Column, + // Advice column used to store the lambda_2 intermediate value at each + // iteration. + lambda_2: Column, + // Fixed column shared by the whole circuit. This is used to load the + // x-coordinate of the domain Q, which is then constrained to equal the + // initial x_a. + constants: Column, + // Permutation over all advice columns and the `constants` fixed column. + perm: Permutation, +} + +#[derive(Eq, PartialEq, Clone, Debug)] +pub struct SinsemillaChip { + config: SinsemillaConfig, +} + +impl Chip for SinsemillaChip { + type Config = SinsemillaConfig; + type Loaded = (); + + fn config(&self) -> &Self::Config { + &self.config + } + + fn loaded(&self) -> &Self::Loaded { + &() + } +} + +impl SinsemillaChip { + pub fn construct(config: >::Config) -> Self { + Self { config } + } + + pub fn load( + config: SinsemillaConfig, + layouter: &mut impl Layouter, + ) -> Result<>::Loaded, Error> { + todo!() + } + + #[allow(clippy::too_many_arguments)] + pub fn configure( + meta: &mut ConstraintSystem, + advices: [Column; 5], + lookup: (Column, Column, Column), + constants: Column, + perm: Permutation, + ) -> >::Config { + todo!() + } +} + +// Implement `SinsemillaInstructions` for `SinsemillaChip` +impl SinsemillaInstructions + for SinsemillaChip +{ + type CellValue = CellValue; + + type Message = Message; + type MessagePiece = MessagePiece; + + type X = CellValue; + type Point = EccPoint; + + type HashDomains = SinsemillaHashDomains; + + #[allow(non_snake_case)] + fn witness_message( + &self, + mut layouter: impl Layouter, + message: Vec>, + ) -> Result { + todo!() + } + + #[allow(non_snake_case)] + fn witness_message_piece_bitstring( + &self, + layouter: impl Layouter, + message_piece: &[Option], + ) -> Result { + todo!() + } + + fn witness_message_piece_field( + &self, + mut layouter: impl Layouter, + field_elem: Option, + num_words: usize, + ) -> Result { + todo!() + } + + #[allow(non_snake_case)] + #[allow(clippy::type_complexity)] + fn hash_to_point( + &self, + mut layouter: impl Layouter, + Q: pallas::Affine, + message: Self::Message, + ) -> Result<(Self::Point, Vec>), Error> { + todo!() + } + + fn extract(point: &Self::Point) -> Self::X { + point.x() + } +} + +#[derive(Clone, Debug)] +pub enum SinsemillaHashDomains { + NoteCommit, + CommitIvk, + MerkleCrh, +} + +#[allow(non_snake_case)] +impl HashDomains for SinsemillaHashDomains { + fn Q(&self) -> pallas::Affine { + match self { + SinsemillaHashDomains::CommitIvk => pallas::Affine::from_xy( + pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.0).unwrap(), + pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.1).unwrap(), + ) + .unwrap(), + SinsemillaHashDomains::NoteCommit => pallas::Affine::from_xy( + pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.0).unwrap(), + pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.1).unwrap(), + ) + .unwrap(), + SinsemillaHashDomains::MerkleCrh => pallas::Affine::from_xy( + pallas::Base::from_bytes(&Q_MERKLE_CRH.0).unwrap(), + pallas::Base::from_bytes(&Q_MERKLE_CRH.1).unwrap(), + ) + .unwrap(), + } + } +}