2021-01-05 17:16:30 -08:00
|
|
|
use std::marker::PhantomData;
|
|
|
|
|
|
|
|
use super::Sha256Instructions;
|
2021-02-25 11:50:50 -08:00
|
|
|
use halo2::{
|
2021-01-05 17:16:30 -08:00
|
|
|
arithmetic::FieldExt,
|
2021-10-27 06:58:28 -07:00
|
|
|
circuit::{AssignedCell, Chip, Layouter, Region},
|
|
|
|
pasta::pallas,
|
|
|
|
plonk::{Advice, Any, Column, ConstraintSystem, Error},
|
2021-01-05 17:16:30 -08:00
|
|
|
};
|
|
|
|
|
2021-01-08 00:10:55 -08:00
|
|
|
mod compression;
|
2021-01-05 21:32:07 -08:00
|
|
|
mod gates;
|
2021-01-05 21:23:16 -08:00
|
|
|
mod message_schedule;
|
2021-01-05 17:16:30 -08:00
|
|
|
mod spread_table;
|
|
|
|
mod util;
|
|
|
|
|
2021-01-08 00:10:55 -08:00
|
|
|
use compression::*;
|
2021-01-05 21:32:07 -08:00
|
|
|
use gates::*;
|
2021-01-05 21:23:16 -08:00
|
|
|
use message_schedule::*;
|
2021-01-05 17:16:30 -08:00
|
|
|
use spread_table::*;
|
|
|
|
|
|
|
|
const ROUNDS: usize = 64;
|
|
|
|
const STATE: usize = 8;
|
|
|
|
|
|
|
|
#[allow(clippy::unreadable_literal)]
|
2021-01-14 21:07:45 -08:00
|
|
|
pub(crate) const ROUND_CONSTANTS: [u32; ROUNDS] = [
|
2021-01-05 17:16:30 -08:00
|
|
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
|
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
|
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
|
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
|
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
|
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
|
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
|
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
|
|
];
|
|
|
|
|
|
|
|
const IV: [u32; STATE] = [
|
|
|
|
0x6a09_e667,
|
|
|
|
0xbb67_ae85,
|
|
|
|
0x3c6e_f372,
|
|
|
|
0xa54f_f53a,
|
|
|
|
0x510e_527f,
|
|
|
|
0x9b05_688c,
|
|
|
|
0x1f83_d9ab,
|
|
|
|
0x5be0_cd19,
|
|
|
|
];
|
|
|
|
|
2021-07-19 07:23:20 -07:00
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
2021-01-15 13:35:49 -08:00
|
|
|
/// A word in a `Table16` message block.
|
2021-07-19 07:23:20 -07:00
|
|
|
pub struct BlockWord(pub(crate) Option<u32>);
|
2021-01-05 17:16:30 -08:00
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
/// Newtype around u16
|
|
|
|
pub struct U16(u16);
|
|
|
|
|
|
|
|
impl From<U16> for pallas::Base {
|
|
|
|
fn from(int: U16) -> pallas::Base {
|
|
|
|
pallas::Base::from_u64(int.0 as u64)
|
|
|
|
}
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
impl From<U16> for u16 {
|
|
|
|
fn from(int: U16) -> u16 {
|
|
|
|
int.0
|
|
|
|
}
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct CellValue16(AssignedCell<pallas::Base, U16>);
|
|
|
|
|
|
|
|
impl CellValue16 {
|
|
|
|
pub fn assign_unchecked<A, AR>(
|
|
|
|
region: &mut Region<'_, pallas::Base>,
|
|
|
|
annotation: A,
|
|
|
|
column: impl Into<Column<Any>>,
|
|
|
|
offset: usize,
|
|
|
|
value: Option<u16>,
|
|
|
|
) -> Result<Self, Error>
|
|
|
|
where
|
|
|
|
A: Fn() -> AR,
|
|
|
|
AR: Into<String>,
|
|
|
|
{
|
|
|
|
AssignedCell::<pallas::Base, U16>::assign_unchecked(
|
|
|
|
region,
|
|
|
|
annotation,
|
|
|
|
column,
|
|
|
|
offset,
|
|
|
|
value.map(U16),
|
|
|
|
)
|
|
|
|
.map(CellValue16)
|
2021-07-19 07:23:20 -07:00
|
|
|
}
|
2021-10-27 06:58:28 -07:00
|
|
|
|
|
|
|
pub fn value_u16(&self) -> Option<u16> {
|
|
|
|
self.value().map(|value| value.0)
|
2021-07-19 07:23:20 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
impl From<AssignedCell<pallas::Base, U16>> for CellValue16 {
|
|
|
|
fn from(assigned_cell: AssignedCell<pallas::Base, U16>) -> CellValue16 {
|
|
|
|
CellValue16(assigned_cell)
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
impl std::ops::Deref for CellValue16 {
|
|
|
|
type Target = AssignedCell<pallas::Base, U16>;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.0
|
|
|
|
}
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
/// Newtype around u32
|
|
|
|
pub struct U32(u32);
|
|
|
|
|
|
|
|
impl From<U32> for pallas::Base {
|
|
|
|
fn from(int: U32) -> pallas::Base {
|
|
|
|
pallas::Base::from_u64(int.0 as u64)
|
2021-07-19 07:23:20 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct CellValue32(AssignedCell<pallas::Base, U32>);
|
|
|
|
|
|
|
|
impl CellValue32 {
|
|
|
|
pub fn assign_unchecked<A, AR>(
|
|
|
|
region: &mut Region<'_, pallas::Base>,
|
|
|
|
annotation: A,
|
|
|
|
column: impl Into<Column<Any>>,
|
|
|
|
offset: usize,
|
|
|
|
value: Option<u32>,
|
|
|
|
) -> Result<Self, Error>
|
|
|
|
where
|
|
|
|
A: Fn() -> AR,
|
|
|
|
AR: Into<String>,
|
|
|
|
{
|
|
|
|
AssignedCell::<pallas::Base, U32>::assign_unchecked(
|
|
|
|
region,
|
|
|
|
annotation,
|
|
|
|
column,
|
|
|
|
offset,
|
|
|
|
value.map(U32),
|
|
|
|
)
|
|
|
|
.map(CellValue32)
|
2021-07-19 07:23:20 -07:00
|
|
|
}
|
2021-10-27 06:58:28 -07:00
|
|
|
|
|
|
|
pub fn value_u32(&self) -> Option<u32> {
|
|
|
|
self.value().map(|value| value.0)
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
impl From<AssignedCell<pallas::Base, U32>> for CellValue32 {
|
|
|
|
fn from(assigned_cell: AssignedCell<pallas::Base, U32>) -> CellValue32 {
|
|
|
|
CellValue32(assigned_cell)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::ops::Deref for CellValue32 {
|
|
|
|
type Target = AssignedCell<pallas::Base, U32>;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.0
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Configuration for a [`Table16Chip`].
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct Table16Config {
|
2021-04-20 04:26:32 -07:00
|
|
|
lookup: SpreadTableConfig,
|
|
|
|
message_schedule: MessageScheduleConfig,
|
|
|
|
compression: CompressionConfig,
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A chip that implements SHA-256 with a maximum lookup table size of $2^16$.
|
|
|
|
#[derive(Clone, Debug)]
|
2021-10-27 06:58:28 -07:00
|
|
|
pub struct Table16Chip {
|
2021-04-20 04:26:32 -07:00
|
|
|
config: Table16Config,
|
2021-10-27 06:58:28 -07:00
|
|
|
_marker: PhantomData<pallas::Base>,
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
impl Chip<pallas::Base> for Table16Chip {
|
2021-04-20 04:26:32 -07:00
|
|
|
type Config = Table16Config;
|
|
|
|
type Loaded = ();
|
|
|
|
|
|
|
|
fn config(&self) -> &Self::Config {
|
|
|
|
&self.config
|
|
|
|
}
|
|
|
|
|
|
|
|
fn loaded(&self) -> &Self::Loaded {
|
|
|
|
&()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
impl Table16Chip {
|
|
|
|
pub fn construct(config: <Self as Chip<pallas::Base>>::Config) -> Self {
|
2021-04-20 04:26:32 -07:00
|
|
|
Self {
|
|
|
|
config,
|
|
|
|
_marker: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
2021-01-05 17:16:30 -08:00
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
pub fn configure(
|
|
|
|
meta: &mut ConstraintSystem<pallas::Base>,
|
|
|
|
) -> <Self as Chip<pallas::Base>>::Config {
|
2021-04-20 04:26:32 -07:00
|
|
|
// Columns required by this chip:
|
2021-01-05 17:16:30 -08:00
|
|
|
let message_schedule = meta.advice_column();
|
|
|
|
let extras = [
|
|
|
|
meta.advice_column(),
|
|
|
|
meta.advice_column(),
|
|
|
|
meta.advice_column(),
|
|
|
|
meta.advice_column(),
|
|
|
|
meta.advice_column(),
|
|
|
|
meta.advice_column(),
|
|
|
|
];
|
|
|
|
|
2021-04-20 04:26:32 -07:00
|
|
|
// - Three advice columns to interact with the lookup table.
|
|
|
|
let input_tag = meta.advice_column();
|
|
|
|
let input_dense = meta.advice_column();
|
|
|
|
let input_spread = meta.advice_column();
|
|
|
|
|
|
|
|
let lookup = SpreadTableChip::configure(meta, input_tag, input_dense, input_spread);
|
|
|
|
let lookup_inputs = lookup.input.clone();
|
2021-01-05 17:16:30 -08:00
|
|
|
|
|
|
|
// Rename these here for ease of matching the gates to the specification.
|
2021-01-05 21:23:16 -08:00
|
|
|
let _a_0 = lookup_inputs.tag;
|
2021-01-05 17:16:30 -08:00
|
|
|
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];
|
2021-01-05 21:23:16 -08:00
|
|
|
let _a_9 = extras[5];
|
2021-01-05 17:16:30 -08:00
|
|
|
|
2021-07-16 08:33:22 -07:00
|
|
|
// Add all advice columns to permutation
|
|
|
|
for column in [a_1, a_2, a_3, a_4, a_5, a_6, a_7, a_8].iter() {
|
|
|
|
meta.enable_equality((*column).into());
|
|
|
|
}
|
|
|
|
|
|
|
|
let compression =
|
|
|
|
CompressionConfig::configure(meta, lookup_inputs.clone(), message_schedule, extras);
|
2021-01-08 00:10:55 -08:00
|
|
|
|
2021-05-26 14:52:03 -07:00
|
|
|
let message_schedule =
|
2021-07-16 08:33:22 -07:00
|
|
|
MessageScheduleConfig::configure(meta, lookup_inputs, message_schedule, extras);
|
2021-01-05 21:23:16 -08:00
|
|
|
|
|
|
|
Table16Config {
|
2021-04-20 04:26:32 -07:00
|
|
|
lookup,
|
2021-01-05 21:23:16 -08:00
|
|
|
message_schedule,
|
2021-01-08 00:10:55 -08:00
|
|
|
compression,
|
2021-01-05 21:23:16 -08:00
|
|
|
}
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
pub fn load(
|
|
|
|
config: Table16Config,
|
|
|
|
layouter: &mut impl Layouter<pallas::Base>,
|
|
|
|
) -> Result<(), Error> {
|
2021-04-20 04:26:32 -07:00
|
|
|
SpreadTableChip::load(config.lookup, layouter)
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
impl Sha256Instructions<pallas::Base> for Table16Chip {
|
2021-01-05 17:16:30 -08:00
|
|
|
type State = State;
|
|
|
|
type BlockWord = BlockWord;
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
fn initialization_vector(
|
|
|
|
&self,
|
|
|
|
layouter: &mut impl Layouter<pallas::Base>,
|
|
|
|
) -> Result<State, Error> {
|
2021-04-20 04:26:32 -07:00
|
|
|
self.config().compression.initialize_with_iv(layouter, IV)
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn initialization(
|
2021-04-20 04:26:32 -07:00
|
|
|
&self,
|
2021-10-27 06:58:28 -07:00
|
|
|
layouter: &mut impl Layouter<pallas::Base>,
|
2021-01-05 17:16:30 -08:00
|
|
|
init_state: &Self::State,
|
|
|
|
) -> Result<Self::State, Error> {
|
2021-04-20 04:26:32 -07:00
|
|
|
self.config()
|
2021-01-08 00:10:55 -08:00
|
|
|
.compression
|
|
|
|
.initialize_with_state(layouter, init_state.clone())
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
2021-01-08 00:10:55 -08:00
|
|
|
// Given an initialized state and an input message block, compress the
|
|
|
|
// message block and return the final state.
|
2021-01-05 17:16:30 -08:00
|
|
|
fn compress(
|
2021-04-20 04:26:32 -07:00
|
|
|
&self,
|
2021-10-27 06:58:28 -07:00
|
|
|
layouter: &mut impl Layouter<pallas::Base>,
|
2021-01-05 17:16:30 -08:00
|
|
|
initialized_state: &Self::State,
|
|
|
|
input: [Self::BlockWord; super::BLOCK_SIZE],
|
|
|
|
) -> Result<Self::State, Error> {
|
2021-05-26 14:49:18 -07:00
|
|
|
let config = self.config();
|
2021-01-05 21:23:16 -08:00
|
|
|
let (_, w_halves) = config.message_schedule.process(layouter, input)?;
|
2021-01-08 00:10:55 -08:00
|
|
|
config
|
|
|
|
.compression
|
|
|
|
.compress(layouter, initialized_state.clone(), w_halves)
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn digest(
|
2021-04-20 04:26:32 -07:00
|
|
|
&self,
|
2021-10-27 06:58:28 -07:00
|
|
|
layouter: &mut impl Layouter<pallas::Base>,
|
2021-01-05 17:16:30 -08:00
|
|
|
state: &Self::State,
|
|
|
|
) -> Result<[Self::BlockWord; super::DIGEST_SIZE], Error> {
|
|
|
|
// Copy the dense forms of the state variable chunks down to this gate.
|
|
|
|
// Reconstruct the 32-bit dense words.
|
2021-04-20 04:26:32 -07:00
|
|
|
self.config().compression.digest(layouter, state.clone())
|
2021-01-05 17:16:30 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Common assignment patterns used by Table16 regions.
|
2021-10-27 06:58:28 -07:00
|
|
|
trait Table16Assignment {
|
2021-01-05 17:16:30 -08:00
|
|
|
// Assign cells for general spread computation used in sigma, ch, ch_neg, maj gates
|
2021-02-25 12:34:07 -08:00
|
|
|
#[allow(clippy::too_many_arguments)]
|
|
|
|
#[allow(clippy::type_complexity)]
|
2021-01-05 17:16:30 -08:00
|
|
|
fn assign_spread_outputs(
|
|
|
|
&self,
|
2021-10-27 06:58:28 -07:00
|
|
|
region: &mut Region<'_, pallas::Base>,
|
2021-01-05 17:16:30 -08:00
|
|
|
lookup: &SpreadInputs,
|
|
|
|
a_3: Column<Advice>,
|
|
|
|
row: usize,
|
2021-07-19 07:23:20 -07:00
|
|
|
r_0_even: Option<u16>,
|
|
|
|
r_0_odd: Option<u16>,
|
|
|
|
r_1_even: Option<u16>,
|
|
|
|
r_1_odd: Option<u16>,
|
2021-01-05 17:16:30 -08:00
|
|
|
) -> Result<((CellValue16, CellValue16), (CellValue16, CellValue16)), Error> {
|
|
|
|
// Lookup R_0^{even}, R_0^{odd}, R_1^{even}, R_1^{odd}
|
2021-07-19 07:23:20 -07:00
|
|
|
let r_0_even =
|
|
|
|
SpreadVar::with_lookup(region, lookup, row - 1, SpreadWord::opt_new(r_0_even))?;
|
|
|
|
let r_0_odd = SpreadVar::with_lookup(region, lookup, row, SpreadWord::opt_new(r_0_odd))?;
|
|
|
|
let r_1_even =
|
|
|
|
SpreadVar::with_lookup(region, lookup, row + 1, SpreadWord::opt_new(r_1_even))?;
|
|
|
|
let r_1_odd =
|
|
|
|
SpreadVar::with_lookup(region, lookup, row + 2, SpreadWord::opt_new(r_1_odd))?;
|
2021-01-05 17:16:30 -08:00
|
|
|
|
|
|
|
// Assign and copy R_1^{odd}
|
2021-10-27 06:58:28 -07:00
|
|
|
r_1_odd
|
|
|
|
.spread
|
|
|
|
.copy_advice(|| "Assign and copy R_1^{odd}", region, a_3, row)?;
|
2021-01-05 17:16:30 -08:00
|
|
|
|
|
|
|
Ok((
|
2021-10-27 06:58:28 -07:00
|
|
|
(r_0_even.dense, r_1_even.dense),
|
|
|
|
(r_0_odd.dense, r_1_odd.dense),
|
2021-01-05 17:16:30 -08:00
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assign outputs of sigma gates
|
2021-02-25 12:34:07 -08:00
|
|
|
#[allow(clippy::too_many_arguments)]
|
2021-01-05 17:16:30 -08:00
|
|
|
fn assign_sigma_outputs(
|
|
|
|
&self,
|
2021-10-27 06:58:28 -07:00
|
|
|
region: &mut Region<'_, pallas::Base>,
|
2021-01-05 17:16:30 -08:00
|
|
|
lookup: &SpreadInputs,
|
|
|
|
a_3: Column<Advice>,
|
|
|
|
row: usize,
|
2021-07-19 07:23:20 -07:00
|
|
|
r_0_even: Option<u16>,
|
|
|
|
r_0_odd: Option<u16>,
|
|
|
|
r_1_even: Option<u16>,
|
|
|
|
r_1_odd: Option<u16>,
|
2021-01-05 17:16:30 -08:00
|
|
|
) -> Result<(CellValue16, CellValue16), Error> {
|
|
|
|
let (even, _odd) = self.assign_spread_outputs(
|
2021-07-16 08:33:22 -07:00
|
|
|
region, lookup, a_3, row, r_0_even, r_0_odd, r_1_even, r_1_odd,
|
2021-01-05 17:16:30 -08:00
|
|
|
)?;
|
|
|
|
|
|
|
|
Ok(even)
|
|
|
|
}
|
|
|
|
}
|
2021-01-22 14:59:14 -08:00
|
|
|
|
|
|
|
#[cfg(test)]
|
2021-10-27 01:48:56 -07:00
|
|
|
#[cfg(feature = "dev-graph")]
|
2021-01-22 14:59:14 -08:00
|
|
|
mod tests {
|
2021-10-27 01:48:56 -07:00
|
|
|
use super::super::{Sha256, BLOCK_SIZE};
|
2021-07-19 07:23:20 -07:00
|
|
|
use super::{message_schedule::msg_schedule_test_input, Table16Chip, Table16Config};
|
2021-02-25 11:50:50 -08:00
|
|
|
use halo2::{
|
2021-07-16 08:33:22 -07:00
|
|
|
circuit::{Layouter, SimpleFloorPlanner},
|
2021-10-27 06:58:28 -07:00
|
|
|
pasta::pallas,
|
2021-07-16 08:33:22 -07:00
|
|
|
plonk::{Circuit, ConstraintSystem, Error},
|
2021-01-22 14:59:14 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn print_sha256_circuit() {
|
2021-10-27 01:48:56 -07:00
|
|
|
use plotters::prelude::*;
|
2021-01-22 14:59:14 -08:00
|
|
|
struct MyCircuit {}
|
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
impl Circuit<pallas::Base> for MyCircuit {
|
2021-01-22 14:59:14 -08:00
|
|
|
type Config = Table16Config;
|
2021-07-16 08:33:22 -07:00
|
|
|
type FloorPlanner = SimpleFloorPlanner;
|
|
|
|
|
|
|
|
fn without_witnesses(&self) -> Self {
|
|
|
|
MyCircuit {}
|
|
|
|
}
|
2021-01-22 14:59:14 -08:00
|
|
|
|
2021-10-27 06:58:28 -07:00
|
|
|
fn configure(meta: &mut ConstraintSystem<pallas::Base>) -> Self::Config {
|
2021-01-22 14:59:14 -08:00
|
|
|
Table16Chip::configure(meta)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn synthesize(
|
|
|
|
&self,
|
2021-04-20 04:26:32 -07:00
|
|
|
config: Self::Config,
|
2021-10-27 06:58:28 -07:00
|
|
|
mut layouter: impl Layouter<pallas::Base>,
|
2021-01-22 14:59:14 -08:00
|
|
|
) -> Result<(), Error> {
|
2021-10-27 06:58:28 -07:00
|
|
|
let table16_chip = Table16Chip::construct(config.clone());
|
|
|
|
Table16Chip::load(config, &mut layouter)?;
|
2021-01-22 14:59:14 -08:00
|
|
|
|
|
|
|
// Test vector: "abc"
|
2021-07-19 07:23:20 -07:00
|
|
|
let test_input = msg_schedule_test_input();
|
2021-01-22 14:59:14 -08:00
|
|
|
|
|
|
|
// Create a message of length 31 blocks
|
|
|
|
let mut input = Vec::with_capacity(31 * BLOCK_SIZE);
|
|
|
|
for _ in 0..31 {
|
|
|
|
input.extend_from_slice(&test_input);
|
|
|
|
}
|
|
|
|
|
2021-04-20 04:26:32 -07:00
|
|
|
Sha256::digest(table16_chip, layouter.namespace(|| "'abc' * 31"), &input)?;
|
2021-01-22 14:59:14 -08:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-29 07:49:34 -08:00
|
|
|
let root =
|
2021-10-27 01:48:56 -07:00
|
|
|
BitMapBackend::new("sha-256-table16-chip-layout.png", (1024, 3480)).into_drawing_area();
|
2021-01-29 07:49:34 -08:00
|
|
|
root.fill(&WHITE).unwrap();
|
|
|
|
let root = root
|
|
|
|
.titled("16-bit Table SHA-256 Chip", ("sans-serif", 60))
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let circuit = MyCircuit {};
|
2021-07-16 08:33:22 -07:00
|
|
|
halo2::dev::CircuitLayout::default()
|
2021-10-27 06:58:28 -07:00
|
|
|
.render::<pallas::Base, _, _>(17, &circuit, &root)
|
2021-07-16 08:33:22 -07:00
|
|
|
.unwrap();
|
2021-01-29 07:49:34 -08:00
|
|
|
}
|
2021-01-22 14:59:14 -08:00
|
|
|
}
|