halo2/examples/sha256/table16/message_schedule/schedule_util.rs

197 lines
7.1 KiB
Rust

use super::super::CellValue16;
use super::MessageScheduleConfig;
use halo2::{
arithmetic::FieldExt,
circuit::{Cell, Region},
plonk::Error,
};
#[cfg(test)]
use super::super::{super::BLOCK_SIZE, BlockWord, ROUNDS};
// Rows needed for each gate
pub const DECOMPOSE_0_ROWS: usize = 2;
pub const DECOMPOSE_1_ROWS: usize = 2;
pub const DECOMPOSE_2_ROWS: usize = 3;
pub const DECOMPOSE_3_ROWS: usize = 2;
pub const SIGMA_0_V1_ROWS: usize = 4;
pub const SIGMA_0_V2_ROWS: usize = 4;
pub const SIGMA_1_V1_ROWS: usize = 4;
pub const SIGMA_1_V2_ROWS: usize = 4;
// Rows needed for each subregion
pub const SUBREGION_0_LEN: usize = 1; // W_0
pub const SUBREGION_0_ROWS: usize = SUBREGION_0_LEN * DECOMPOSE_0_ROWS;
pub const SUBREGION_1_WORD: usize = DECOMPOSE_1_ROWS + SIGMA_0_V1_ROWS;
pub const SUBREGION_1_LEN: usize = 13; // W_[1..14]
pub const SUBREGION_1_ROWS: usize = SUBREGION_1_LEN * SUBREGION_1_WORD;
pub const SUBREGION_2_WORD: usize = DECOMPOSE_2_ROWS + SIGMA_0_V2_ROWS + SIGMA_1_V2_ROWS;
pub const SUBREGION_2_LEN: usize = 35; // W_[14..49]
pub const SUBREGION_2_ROWS: usize = SUBREGION_2_LEN * SUBREGION_2_WORD;
pub const SUBREGION_3_WORD: usize = DECOMPOSE_3_ROWS + SIGMA_1_V1_ROWS;
pub const SUBREGION_3_LEN: usize = 13; // W[49..62]
pub const SUBREGION_3_ROWS: usize = SUBREGION_3_LEN * SUBREGION_3_WORD;
// pub const SUBREGION_4_LEN: usize = 2; // W_[62..64]
// pub const SUBREGION_4_ROWS: usize = SUBREGION_4_LEN * DECOMPOSE_0_ROWS;
/// Returns row number of a word
pub fn get_word_row(word_idx: usize) -> usize {
assert!(word_idx <= 63);
if word_idx == 0 {
0
} else if (1..=13).contains(&word_idx) {
SUBREGION_0_ROWS + SUBREGION_1_WORD * (word_idx - 1) as usize
} else if (14..=48).contains(&word_idx) {
SUBREGION_0_ROWS + SUBREGION_1_ROWS + SUBREGION_2_WORD * (word_idx - 14) + 1
} else if (49..=61).contains(&word_idx) {
SUBREGION_0_ROWS
+ SUBREGION_1_ROWS
+ SUBREGION_2_ROWS
+ SUBREGION_3_WORD * (word_idx - 49) as usize
} else {
SUBREGION_0_ROWS
+ SUBREGION_1_ROWS
+ SUBREGION_2_ROWS
+ SUBREGION_3_ROWS
+ DECOMPOSE_0_ROWS * (word_idx - 62) as usize
}
}
/// Test vector: "abc"
#[cfg(test)]
pub fn get_msg_schedule_test_input() -> [BlockWord; BLOCK_SIZE] {
[
BlockWord::new(0b01100001011000100110001110000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000000000),
BlockWord::new(0b00000000000000000000000000011000),
]
}
#[cfg(test)]
pub const MSG_SCHEDULE_TEST_OUTPUT: [u32; ROUNDS] = [
0b01100001011000100110001110000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000000000,
0b00000000000000000000000000011000,
0b01100001011000100110001110000000,
0b00000000000011110000000000000000,
0b01111101101010000110010000000101,
0b01100000000000000000001111000110,
0b00111110100111010111101101111000,
0b00000001100000111111110000000000,
0b00010010110111001011111111011011,
0b11100010111000101100001110001110,
0b11001000001000010101110000011010,
0b10110111001101100111100110100010,
0b11100101101111000011100100001001,
0b00110010011001100011110001011011,
0b10011101001000001001110101100111,
0b11101100100001110010011011001011,
0b01110000001000010011100010100100,
0b11010011101101111001011100111011,
0b10010011111101011001100101111111,
0b00111011011010001011101001110011,
0b10101111111101001111111111000001,
0b11110001000010100101110001100010,
0b00001010100010110011100110010110,
0b01110010101011111000001100001010,
0b10010100000010011110001100111110,
0b00100100011001000001010100100010,
0b10011111010001111011111110010100,
0b11110000101001100100111101011010,
0b00111110001001000110101001111001,
0b00100111001100110011101110100011,
0b00001100010001110110001111110010,
0b10000100000010101011111100100111,
0b01111010001010010000110101011101,
0b00000110010111000100001111011010,
0b11111011001111101000100111001011,
0b11001100011101100001011111011011,
0b10111001111001100110110000110100,
0b10101001100110010011011001100111,
0b10000100101110101101111011011101,
0b11000010000101000110001010111100,
0b00010100100001110100011100101100,
0b10110010000011110111101010011001,
0b11101111010101111011100111001101,
0b11101011111001101011001000111000,
0b10011111111000110000100101011110,
0b01111000101111001000110101001011,
0b10100100001111111100111100010101,
0b01100110100010110010111111111000,
0b11101110101010111010001011001100,
0b00010010101100011110110111101011,
];
impl MessageScheduleConfig {
// Assign a word and its hi and lo halves
pub fn assign_word_and_halves<F: FieldExt>(
&self,
region: &mut Region<'_, F>,
word: u32,
word_idx: usize,
) -> Result<(Cell, (CellValue16, CellValue16)), Error> {
// Rename these here for ease of matching the gates to the specification.
let a_3 = self.extras[0];
let a_4 = self.extras[1];
let row = get_word_row(word_idx);
let var = region.assign_advice(
|| format!("W_{}", word_idx),
self.message_schedule,
row,
|| Ok(F::from_u64(word as u64)),
)?;
let w_lo = word as u16;
let w_hi = (word >> 16) as u16;
let w_lo_cell = region.assign_advice(
|| format!("W_{}_lo", word_idx),
a_3,
row,
|| Ok(F::from_u64(w_lo as u64)),
)?;
let w_hi_cell = region.assign_advice(
|| format!("W_{}_hi", word_idx),
a_4,
row,
|| Ok(F::from_u64(w_hi as u64)),
)?;
Ok((
var,
(
CellValue16::new(w_lo_cell, w_lo),
CellValue16::new(w_hi_cell, w_hi),
),
))
}
}