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( &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), ), )) } }