From feedffa2b2f9c44d75f011f66ec414e87aa623e5 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Wed, 6 Jan 2021 13:23:16 +0800 Subject: [PATCH] Add MessageSchedule --- src/gadget/sha256/table16.rs | 16 ++- src/gadget/sha256/table16/message_schedule.rs | 120 ++++++++++++++++++ src/gadget/sha256/table16/spread_table.rs | 41 +++++- 3 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 src/gadget/sha256/table16/message_schedule.rs diff --git a/src/gadget/sha256/table16.rs b/src/gadget/sha256/table16.rs index 0bf0d19..f5952a3 100644 --- a/src/gadget/sha256/table16.rs +++ b/src/gadget/sha256/table16.rs @@ -7,9 +7,11 @@ use crate::{ plonk::{Advice, Column, ConstraintSystem, Error, Permutation}, }; +mod message_schedule; mod spread_table; mod util; +use message_schedule::*; use spread_table::*; const ROUNDS: usize = 64; @@ -153,6 +155,7 @@ struct HPrime {} #[derive(Clone, Debug)] pub struct Table16Config { lookup_table: SpreadTable, + message_schedule: MessageSchedule, } /// A chip that implements SHA-256 with a maximum lookup table size of $2^16$. @@ -183,7 +186,7 @@ impl Table16Chip { let (lookup_inputs, lookup_table) = SpreadTable::configure(meta, tag, dense, spread); // Rename these here for ease of matching the gates to the specification. - let a_0 = lookup_inputs.tag; + let _a_0 = lookup_inputs.tag; let a_1 = lookup_inputs.dense; let a_2 = lookup_inputs.spread; let a_3 = extras[0]; @@ -192,7 +195,7 @@ impl Table16Chip { let a_6 = extras[2]; let a_7 = extras[3]; let a_8 = extras[4]; - let a_9 = extras[5]; + let _a_9 = extras[5]; let perm = Permutation::new( meta, @@ -208,7 +211,13 @@ impl Table16Chip { ], ); - Table16Config { lookup_table } + let message_schedule = + MessageSchedule::configure(meta, lookup_inputs, message_schedule, extras, perm.clone()); + + Table16Config { + lookup_table, + message_schedule, + } } } @@ -248,6 +257,7 @@ impl Sha256Instructions for Table16Chip { input: [Self::BlockWord; super::BLOCK_SIZE], ) -> Result { let config = layouter.config().clone(); + let (_, w_halves) = config.message_schedule.process(layouter, input)?; todo!() } diff --git a/src/gadget/sha256/table16/message_schedule.rs b/src/gadget/sha256/table16/message_schedule.rs new file mode 100644 index 0000000..d67641e --- /dev/null +++ b/src/gadget/sha256/table16/message_schedule.rs @@ -0,0 +1,120 @@ +use std::convert::TryInto; + +use super::{ + super::BLOCK_SIZE, BlockWord, CellValue16, SpreadInputs, Table16Assignment, Table16Chip, ROUNDS, +}; +use crate::{ + arithmetic::FieldExt, + circuit::{Cell, Layouter}, + plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation}, +}; + +// mod schedule_gates; +// mod subregion1; +// mod subregion2; +// mod subregion3; + +// use schedule_gates::ScheduleGate; + +#[derive(Clone, Debug)] +pub(super) struct MessageWord { + var: Cell, + value: Option, +} + +#[derive(Clone, Debug)] +pub(super) struct MessageSchedule { + lookup: SpreadInputs, + message_schedule: Column, + extras: [Column; 6], + + /// Construct a word using reduce_4. + s_word: Column, + /// Decomposition gate for W_0, W_62, W_63. + s_decompose_0: Column, + /// Decomposition gate for W_[1..14] + s_decompose_1: Column, + /// Decomposition gate for W_[14..49] + s_decompose_2: Column, + /// Decomposition gate for W_[49..62] + s_decompose_3: Column, + /// sigma_0 gate for W_[1..14] + s_lower_sigma_0: Column, + /// sigma_1 gate for W_[49..62] + s_lower_sigma_1: Column, + /// sigma_0_v2 gate for W_[14..49] + s_lower_sigma_0_v2: Column, + /// sigma_1_v2 gate for W_[14..49] + s_lower_sigma_1_v2: Column, + perm: Permutation, +} + +impl MessageSchedule { + /// Configures the message schedule. + /// + /// `message_schedule` is the column into which the message schedule will be placed. + /// The caller must create appropriate permutations in order to load schedule words + /// into the compression rounds. + /// + /// `extras` contains columns that the message schedule will only use for internal + /// gates, and will not place any constraints on (such as lookup constraints) outside + /// itself. + pub(super) fn configure( + meta: &mut ConstraintSystem, + lookup: SpreadInputs, + message_schedule: Column, + extras: [Column; 6], + perm: Permutation, + ) -> Self { + // Create fixed columns for the selectors we will require. + let s_word = meta.fixed_column(); + let s_decompose_0 = meta.fixed_column(); + let s_decompose_1 = meta.fixed_column(); + let s_decompose_2 = meta.fixed_column(); + let s_decompose_3 = meta.fixed_column(); + let s_lower_sigma_0 = meta.fixed_column(); + let s_lower_sigma_1 = meta.fixed_column(); + let s_lower_sigma_0_v2 = meta.fixed_column(); + let s_lower_sigma_1_v2 = meta.fixed_column(); + + // TODO: Create gates + + MessageSchedule { + lookup, + message_schedule, + extras, + s_word, + s_decompose_0, + s_decompose_1, + s_decompose_2, + s_decompose_3, + s_lower_sigma_0, + s_lower_sigma_1, + s_lower_sigma_0_v2, + s_lower_sigma_1_v2, + perm, + } + } + + pub(super) fn process( + &self, + layouter: &mut impl Layouter>, + input: [BlockWord; BLOCK_SIZE], + ) -> Result<([MessageWord; ROUNDS], [(CellValue16, CellValue16); ROUNDS]), Error> { + let mut w = Vec::::with_capacity(ROUNDS); + let mut w_halves = Vec::<(CellValue16, CellValue16)>::with_capacity(ROUNDS); + + layouter.assign_region( + || "process message block", + |region| { + let region = std::cell::RefCell::new(region); + + // TODO: Assign cells + + Ok(()) + }, + )?; + + Ok((w.try_into().unwrap(), w_halves.try_into().unwrap())) + } +} diff --git a/src/gadget/sha256/table16/spread_table.rs b/src/gadget/sha256/table16/spread_table.rs index fe5b66c..8e0c866 100644 --- a/src/gadget/sha256/table16/spread_table.rs +++ b/src/gadget/sha256/table16/spread_table.rs @@ -245,7 +245,7 @@ mod tests { use std::marker::PhantomData; use super::{ - super::{util::*, Table16Chip, Table16Config}, + super::{util::*, MessageSchedule, Table16Chip, Table16Config}, SpreadInputs, SpreadTable, }; use crate::{ @@ -488,9 +488,46 @@ mod tests { meta.advice_column(), ]; + // Rename these here for ease of matching the gates to the specification. + let _a_0 = lookup_inputs.tag; + let a_1 = lookup_inputs.dense; + let a_2 = lookup_inputs.spread; + let a_3 = extras[0]; + let a_4 = extras[1]; + let a_5 = message_schedule; + let a_6 = extras[2]; + let a_7 = extras[3]; + let a_8 = extras[4]; + let _a_9 = extras[5]; + + let perm = Permutation::new( + meta, + &[ + a_1.into(), + a_2.into(), + a_3.into(), + a_4.into(), + a_5.into(), + a_6.into(), + a_7.into(), + a_8.into(), + ], + ); + + let message_schedule = MessageSchedule::configure( + meta, + lookup_inputs.clone(), + message_schedule, + extras, + perm.clone(), + ); + MyConfig { lookup_inputs, - sha256: Table16Config { lookup_table }, + sha256: Table16Config { + lookup_table, + message_schedule, + }, } }