Add MessageSchedule

This commit is contained in:
therealyingtong 2021-01-06 13:23:16 +08:00 committed by Jack Grigg
parent 570f90e4ee
commit feedffa2b2
3 changed files with 172 additions and 5 deletions

View file

@ -7,9 +7,11 @@ use crate::{
plonk::{Advice, Column, ConstraintSystem, Error, Permutation}, plonk::{Advice, Column, ConstraintSystem, Error, Permutation},
}; };
mod message_schedule;
mod spread_table; mod spread_table;
mod util; mod util;
use message_schedule::*;
use spread_table::*; use spread_table::*;
const ROUNDS: usize = 64; const ROUNDS: usize = 64;
@ -153,6 +155,7 @@ struct HPrime {}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Table16Config { pub struct Table16Config {
lookup_table: SpreadTable, lookup_table: SpreadTable,
message_schedule: MessageSchedule,
} }
/// A chip that implements SHA-256 with a maximum lookup table size of $2^16$. /// A chip that implements SHA-256 with a maximum lookup table size of $2^16$.
@ -183,7 +186,7 @@ impl<F: FieldExt> Table16Chip<F> {
let (lookup_inputs, lookup_table) = SpreadTable::configure(meta, tag, dense, spread); let (lookup_inputs, lookup_table) = SpreadTable::configure(meta, tag, dense, spread);
// Rename these here for ease of matching the gates to the specification. // 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_1 = lookup_inputs.dense;
let a_2 = lookup_inputs.spread; let a_2 = lookup_inputs.spread;
let a_3 = extras[0]; let a_3 = extras[0];
@ -192,7 +195,7 @@ impl<F: FieldExt> Table16Chip<F> {
let a_6 = extras[2]; let a_6 = extras[2];
let a_7 = extras[3]; let a_7 = extras[3];
let a_8 = extras[4]; let a_8 = extras[4];
let a_9 = extras[5]; let _a_9 = extras[5];
let perm = Permutation::new( let perm = Permutation::new(
meta, meta,
@ -208,7 +211,13 @@ impl<F: FieldExt> Table16Chip<F> {
], ],
); );
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<F: FieldExt> Sha256Instructions for Table16Chip<F> {
input: [Self::BlockWord; super::BLOCK_SIZE], input: [Self::BlockWord; super::BLOCK_SIZE],
) -> Result<Self::State, Error> { ) -> Result<Self::State, Error> {
let config = layouter.config().clone(); let config = layouter.config().clone();
let (_, w_halves) = config.message_schedule.process(layouter, input)?;
todo!() todo!()
} }

View file

@ -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<u32>,
}
#[derive(Clone, Debug)]
pub(super) struct MessageSchedule {
lookup: SpreadInputs,
message_schedule: Column<Advice>,
extras: [Column<Advice>; 6],
/// Construct a word using reduce_4.
s_word: Column<Fixed>,
/// Decomposition gate for W_0, W_62, W_63.
s_decompose_0: Column<Fixed>,
/// Decomposition gate for W_[1..14]
s_decompose_1: Column<Fixed>,
/// Decomposition gate for W_[14..49]
s_decompose_2: Column<Fixed>,
/// Decomposition gate for W_[49..62]
s_decompose_3: Column<Fixed>,
/// sigma_0 gate for W_[1..14]
s_lower_sigma_0: Column<Fixed>,
/// sigma_1 gate for W_[49..62]
s_lower_sigma_1: Column<Fixed>,
/// sigma_0_v2 gate for W_[14..49]
s_lower_sigma_0_v2: Column<Fixed>,
/// sigma_1_v2 gate for W_[14..49]
s_lower_sigma_1_v2: Column<Fixed>,
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<F: FieldExt>(
meta: &mut ConstraintSystem<F>,
lookup: SpreadInputs,
message_schedule: Column<Advice>,
extras: [Column<Advice>; 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<F: FieldExt>(
&self,
layouter: &mut impl Layouter<Table16Chip<F>>,
input: [BlockWord; BLOCK_SIZE],
) -> Result<([MessageWord; ROUNDS], [(CellValue16, CellValue16); ROUNDS]), Error> {
let mut w = Vec::<MessageWord>::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()))
}
}

View file

@ -245,7 +245,7 @@ mod tests {
use std::marker::PhantomData; use std::marker::PhantomData;
use super::{ use super::{
super::{util::*, Table16Chip, Table16Config}, super::{util::*, MessageSchedule, Table16Chip, Table16Config},
SpreadInputs, SpreadTable, SpreadInputs, SpreadTable,
}; };
use crate::{ use crate::{
@ -488,9 +488,46 @@ mod tests {
meta.advice_column(), 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 { MyConfig {
lookup_inputs, lookup_inputs,
sha256: Table16Config { lookup_table }, sha256: Table16Config {
lookup_table,
message_schedule,
},
} }
} }