Skip to content

Commit

Permalink
Add Sinsemilla chip
Browse files Browse the repository at this point in the history
  • Loading branch information
therealyingtong committed Apr 23, 2021
1 parent 5ce75e4 commit 2eee389
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 17 deletions.
49 changes: 32 additions & 17 deletions src/circuit/gadget/sinsemilla.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
//! Gadget and chips for the Sinsemilla hash function.
use crate::circuit::gadget::ecc::{self, EccInstructions};
use halo2::{arithmetic::CurveAffine, circuit::Layouter, plonk::Error};
use std::fmt;

use halo2::{arithmetic::CurveAffine, circuit::Layouter, plonk::Error};
mod chip;
// pub use chip::{SinsemillaChip, SinsemillaColumns, SinsemillaConfig};

use crate::circuit::gadget::ecc::{self, EccInstructions};
/// Trait allowing circuit's Sinsemilla HashDomains to be enumerated.
pub trait HashDomains<C: CurveAffine>: Clone + fmt::Debug {}

// mod chip;
// pub use chip::{SinsemillaChip, SinsemillaColumns, SinsemillaConfig};
/// Trait allowing circuit's Sinsemilla CommitDomains to be enumerated.
pub trait CommitDomains<C: CurveAffine, F: ecc::FixedPoints<C>, H: HashDomains<C>>:
Clone + fmt::Debug
{
/// Returns the fixed point corresponding to the R constant for this CommitDomain.
fn r(&self) -> F;

/// Trait allowing circuit's Sinsemilla domains to be enumerated.
pub trait Domains<C: CurveAffine, F: ecc::FixedPoints<C>>: Clone + fmt::Debug {
/// Returns the fixed point corresponding to the R constant for this domain.
fn get_r(&self) -> F;
/// Returns the HashDomain contained in this CommitDomain
fn hash_domain(&self) -> H;
}

/// The set of circuit instructions required to use the [`Sinsemilla`](https://zcash.github.io/halo2/design/gadgets/sinsemilla.html) gadget.
pub trait SinsemillaInstructions<C: CurveAffine>: EccInstructions<C> {
/// Witnessed message.
type Message: Clone + fmt::Debug;
/// Variable representing the set of fixed bases in the circuit.
type Domains: Domains<C, <Self as EccInstructions<C>>::FixedPoints>;
/// Variable representing a Q fixed point for a domain.
/// Variable representing the set of CommitDomains in the circuit.
type CommitDomains: CommitDomains<
C,
<Self as EccInstructions<C>>::FixedPoints,
Self::HashDomains,
>;
/// Variable representing the set of HashDomains in the circuit.
type HashDomains: HashDomains<C>;
/// Variable representing a Q fixed point for a HashDomain.
type Q: Clone + fmt::Debug;

/// Gets the Q constant for the given domain.
#[allow(non_snake_case)]
fn get_Q(layouter: &mut impl Layouter<Self>, domain: &Self::Domains) -> Result<Self::Q, Error>;
fn get_Q(
layouter: &mut impl Layouter<Self>,
domain: &Self::HashDomains,
) -> Result<Self::Q, Error>;

/// Witnesses a message in the form of a bitstring.
fn witness_message(
Expand Down Expand Up @@ -53,10 +68,10 @@ pub struct HashDomain<C: CurveAffine, SinsemillaChip: SinsemillaInstructions<C>>

impl<C: CurveAffine, SinsemillaChip: SinsemillaInstructions<C>> HashDomain<C, SinsemillaChip> {
#[allow(non_snake_case)]
/// Constructs a new `CommitDomain` for the given domain.
/// Constructs a new `HashDomain` for the given domain.
pub fn new(
mut layouter: impl Layouter<SinsemillaChip>,
domain: &SinsemillaChip::Domains,
domain: &SinsemillaChip::HashDomains,
) -> Result<Self, Error> {
SinsemillaChip::get_Q(&mut layouter, domain).map(|Q| HashDomain { Q })
}
Expand Down Expand Up @@ -95,11 +110,11 @@ impl<C: CurveAffine, SinsemillaChip: SinsemillaInstructions<C>> CommitDomain<C,
/// Constructs a new `CommitDomain` for the given domain.
pub fn new(
mut layouter: impl Layouter<SinsemillaChip>,
domain: &SinsemillaChip::Domains,
domain: &SinsemillaChip::CommitDomains,
) -> Result<Self, Error> {
Ok(CommitDomain {
M: HashDomain::new(layouter.namespace(|| "M"), domain)?,
R: ecc::FixedPoint::get(layouter.namespace(|| "R"), domain.get_r())?,
M: HashDomain::new(layouter.namespace(|| "M"), &domain.hash_domain())?,
R: ecc::FixedPoint::get(layouter.namespace(|| "R"), domain.r())?,
})
}

Expand Down
125 changes: 125 additions & 0 deletions src/circuit/gadget/sinsemilla/chip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
use super::super::ecc::chip::EccChip;
use super::{CommitDomains, HashDomains, SinsemillaInstructions};

use crate::constants::OrchardFixedBases;
use halo2::{
arithmetic::{CurveAffine, FieldExt},
circuit::{Cell, Layouter},
plonk::Error,
};

/// A structure containing a cell and its assigned value.
#[derive(Clone, Debug)]
pub struct CellValue<F: FieldExt> {
cell: Cell,
value: Option<F>,
}

/// A message to be hashed.
#[derive(Clone, Debug)]
pub struct Message<F: FieldExt>(Vec<CellValue<F>>);

/// A domain in which $\mathsf{SinsemillaHashToPoint}$ and $\mathsf{SinsemillaHash}$ can
/// be used.
#[derive(Clone, Debug)]
#[allow(non_snake_case)]
pub struct HashDomain<C: CurveAffine> {
Q: C,
}

#[derive(Clone, Debug)]
pub enum OrchardHashDomains<C: CurveAffine> {
NoteCommit(HashDomain<C>),
CommitIvk(HashDomain<C>),
MerkleCrh(HashDomain<C>),
}

impl<C: CurveAffine> HashDomains<C> for OrchardHashDomains<C> {}

/// A domain in which $\mathsf{SinsemillaCommit}$ and $\mathsf{SinsemillaShortCommit}$ can
/// be used.
#[derive(Clone, Debug)]
#[allow(non_snake_case)]
pub struct OrchardCommitDomain<C: CurveAffine> {
M: HashDomain<C>,
R: OrchardFixedBases<C>,
}

impl<C: CurveAffine> OrchardCommitDomain<C> {
fn M(&self) -> &HashDomain<C> {
&self.M
}

fn R(&self) -> OrchardFixedBases<C> {
self.R
}
}

#[derive(Clone, Debug)]
pub enum OrchardCommitDomains<C: CurveAffine> {
NoteCommit(OrchardCommitDomain<C>),
CommitIvk(OrchardCommitDomain<C>),
}

impl<C: CurveAffine> From<OrchardCommitDomains<C>> for OrchardHashDomains<C> {
fn from(commit_domain: OrchardCommitDomains<C>) -> Self {
match commit_domain {
OrchardCommitDomains::NoteCommit(domain) => Self::NoteCommit(domain.M().clone()),
OrchardCommitDomains::CommitIvk(domain) => Self::CommitIvk(domain.M().clone()),
}
}
}

impl<C: CurveAffine> CommitDomains<C, OrchardFixedBases<C>, OrchardHashDomains<C>>
for OrchardCommitDomains<C>
{
fn r(&self) -> OrchardFixedBases<C> {
match self {
Self::NoteCommit(domain) => domain.R(),
Self::CommitIvk(domain) => domain.R(),
_ => unreachable!(),
}
}

fn hash_domain(&self) -> OrchardHashDomains<C> {
match self {
Self::NoteCommit(_) => self.clone().into(),
Self::CommitIvk(_) => self.clone().into(),
}
}
}

impl<C: CurveAffine> SinsemillaInstructions<C> for EccChip<C> {
type Message = Message<C::Base>;
type CommitDomains = OrchardCommitDomains<C>;
type HashDomains = OrchardHashDomains<C>;
type Q = Self::Point;

#[allow(non_snake_case)]
fn get_Q(
layouter: &mut impl Layouter<Self>,
domain: &Self::HashDomains,
) -> Result<Self::Q, Error> {
todo!()
}

fn witness_message(
layouter: &mut impl Layouter<Self>,
message: Vec<bool>,
) -> Result<Self::Message, Error> {
todo!()
}

fn extract(point: &Self::Point) -> Self::X {
todo!()
}

#[allow(non_snake_case)]
fn hash_to_point(
layouter: &mut impl Layouter<Self>,
Q: &Self::Q,
message: Self::Message,
) -> Result<Self::Point, Error> {
todo!()
}
}

0 comments on commit 2eee389

Please sign in to comment.