From e2859df4eb69a9b0de21cf9adf474b184e751e7b Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 19 Jun 2021 10:44:54 +0800 Subject: [PATCH] sinsemilla::message.rs: Add message module. This defines a Sinsemilla message in terms of pieces and subpieces. This is useful when decomposing field elements and packing them into K-bit messages. --- src/circuit/gadget/sinsemilla.rs | 2 +- src/circuit/gadget/sinsemilla/message.rs | 71 ++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/circuit/gadget/sinsemilla/message.rs diff --git a/src/circuit/gadget/sinsemilla.rs b/src/circuit/gadget/sinsemilla.rs index d4360b0b..d24ddb79 100644 --- a/src/circuit/gadget/sinsemilla.rs +++ b/src/circuit/gadget/sinsemilla.rs @@ -7,7 +7,7 @@ use halo2::{arithmetic::CurveAffine, circuit::Layouter, plonk::Error}; use std::fmt::Debug; // pub mod chip; -// mod message; +mod message; // pub use chip::{SinsemillaChip, SinsemillaConfig}; diff --git a/src/circuit/gadget/sinsemilla/message.rs b/src/circuit/gadget/sinsemilla/message.rs new file mode 100644 index 00000000..63917bf3 --- /dev/null +++ b/src/circuit/gadget/sinsemilla/message.rs @@ -0,0 +1,71 @@ +//! Gadget and chips for the Sinsemilla hash function. +use crate::circuit::gadget::utilities::{CellValue, Var}; +use ff::PrimeFieldBits; +use halo2::{arithmetic::FieldExt, circuit::Cell}; +use std::fmt::Debug; + +/// A [`Message`] composed of several [`MessagePiece`]s. +#[derive(Clone, Debug)] +pub struct Message(Vec>); + +impl + From>> for Message +{ + fn from(pieces: Vec>) -> Self { + // A message cannot contain more than `MAX_WORDS` words. + assert!(pieces.iter().map(|piece| piece.num_words()).sum::() < MAX_WORDS); + Message(pieces) + } +} + +impl std::ops::Deref + for Message +{ + type Target = [MessagePiece]; + + fn deref(&self) -> &[MessagePiece] { + &self.0 + } +} + +/// A [`MessagePiece`] of some bitlength. +/// +/// The piece must fit within a base field element, which means its length +/// cannot exceed the base field's `NUM_BITS`. +#[derive(Copy, Clone, Debug)] +pub struct MessagePiece { + cell: Cell, + field_elem: Option, + // The number of K-bit words in this message piece. + num_words: usize, +} + +#[allow(clippy::from_over_into)] +impl Into> for MessagePiece { + fn into(self) -> CellValue { + CellValue::new(self.cell(), self.field_elem()) + } +} + +impl MessagePiece { + pub fn new(cell: Cell, field_elem: Option, num_words: usize) -> Self { + assert!(num_words * K < F::NUM_BITS as usize); + Self { + cell, + field_elem, + num_words, + } + } + + pub fn num_words(&self) -> usize { + self.num_words + } + + pub fn cell(&self) -> Cell { + self.cell + } + + pub fn field_elem(&self) -> Option { + self.field_elem + } +}