diff --git a/src/gadget/sha256/table16/compression.rs b/src/gadget/sha256/table16/compression.rs index 3b1c4d3a..7bb8bde2 100644 --- a/src/gadget/sha256/table16/compression.rs +++ b/src/gadget/sha256/table16/compression.rs @@ -12,7 +12,7 @@ use crate::{ mod compression_gates; mod compression_util; // mod subregion_digest; -// mod subregion_initial; +mod subregion_initial; // mod subregion_main; use compression_gates::CompressionGate; @@ -681,7 +681,14 @@ impl Compression { init_state: [u32; STATE], ) -> Result { let mut new_state = State::empty_state(); - todo!() + layouter.assign_region( + || "initialize_with_iv", + |mut region| { + new_state = self.initialize_iv(&mut region, init_state)?; + Ok(()) + }, + )?; + Ok(new_state) } /// Initialize compression with some initialized state. This could be a state @@ -692,7 +699,14 @@ impl Compression { init_state: State, ) -> Result { let mut new_state = State::empty_state(); - todo!() + layouter.assign_region( + || "initialize_with_state", + |mut region| { + new_state = self.initialize_state(&mut region, init_state.clone())?; + Ok(()) + }, + )?; + Ok(new_state) } /// Given an initialized state and a message schedule, perform 64 compression rounds. diff --git a/src/gadget/sha256/table16/compression/subregion_initial.rs b/src/gadget/sha256/table16/compression/subregion_initial.rs new file mode 100644 index 00000000..ca5a78bd --- /dev/null +++ b/src/gadget/sha256/table16/compression/subregion_initial.rs @@ -0,0 +1,156 @@ +use super::super::{RoundWordDense, RoundWordSpread, StateWord, Table16Chip, STATE}; +use super::{compression_util::*, Compression, State}; +use crate::{arithmetic::FieldExt, circuit::Region, plonk::Error}; + +impl Compression { + pub fn initialize_iv( + &self, + region: &mut Region<'_, Table16Chip>, + iv: [u32; STATE], + ) -> Result { + let a_7 = self.extras[3]; + + let idx = -1; + + // Decompose E into (6, 5, 14, 7)-bit chunks + let e = self.decompose_e(region, idx, iv[4])?; + + // Decompose F, G + let f = self.decompose_f(region, idx, iv[5])?; + let g = self.decompose_g(region, idx, iv[6])?; + + // Assign H + let h_row = get_h_row(idx); + let h_dense = self.assign_word_halves_dense(region, h_row, a_7, h_row + 1, a_7, iv[7])?; + let h = RoundWordDense::new(h_dense); + + // Decompose A into (2, 11, 9, 10)-bit chunks + let a = self.decompose_a(region, idx, iv[0])?; + + // Decompose B, C + let b = self.decompose_b(region, idx, iv[1])?; + let c = self.decompose_c(region, idx, iv[2])?; + + // Assign D + let d_row = get_d_row(idx); + let d_dense = self.assign_word_halves_dense(region, d_row, a_7, d_row + 1, a_7, iv[3])?; + let d = RoundWordDense::new(d_dense); + + Ok(State::new( + StateWord::A(a), + StateWord::B(b), + StateWord::C(c), + StateWord::D(d), + StateWord::E(e), + StateWord::F(f), + StateWord::G(g), + StateWord::H(h), + )) + } + + pub fn initialize_state( + &self, + region: &mut Region<'_, Table16Chip>, + state: State, + ) -> Result { + let a_7 = self.extras[3]; + let (a, b, c, d, e, f, g, h) = match_state(state); + + let idx = -1; + + // Decompose E into (6, 5, 14, 7)-bit chunks + let e = val_from_dense_halves(e.dense_halves); + let e = self.decompose_e(region, idx, e)?; + + // Decompose F, G + let f = val_from_dense_halves(f.dense_halves); + let f = self.decompose_f(region, idx, f)?; + let g = val_from_dense_halves(g.dense_halves); + let g = self.decompose_g(region, idx, g)?; + + // Assign H + let h = val_from_dense_halves(h.dense_halves); + let h_row = get_h_row(idx); + let h_dense = self.assign_word_halves_dense(region, h_row, a_7, h_row + 1, a_7, h)?; + let h = RoundWordDense::new(h_dense); + + // Decompose A into (2, 11, 9, 10)-bit chunks + let a = val_from_dense_halves(a.dense_halves); + let a = self.decompose_a(region, idx, a)?; + + // Decompose B, C + let b = val_from_dense_halves(b.dense_halves); + let b = self.decompose_b(region, idx, b)?; + let c = val_from_dense_halves(c.dense_halves); + let c = self.decompose_c(region, idx, c)?; + + // Assign D + let d = val_from_dense_halves(d.dense_halves); + let d_row = get_d_row(idx); + let d_dense = self.assign_word_halves_dense(region, d_row, a_7, d_row + 1, a_7, d)?; + let d = RoundWordDense::new(d_dense); + + Ok(State::new( + StateWord::A(a), + StateWord::B(b), + StateWord::C(c), + StateWord::D(d), + StateWord::E(e), + StateWord::F(f), + StateWord::G(g), + StateWord::H(h), + )) + } + + fn decompose_b( + &self, + region: &mut Region<'_, Table16Chip>, + idx: i32, + b_val: u32, + ) -> Result { + let row = get_decompose_b_row(idx); + + let (dense_halves, spread_halves) = self.assign_word_halves(region, row, b_val)?; + self.decompose_abcd(region, row, b_val)?; + Ok(RoundWordSpread::new(dense_halves, spread_halves)) + } + + fn decompose_c( + &self, + region: &mut Region<'_, Table16Chip>, + idx: i32, + c_val: u32, + ) -> Result { + let row = get_decompose_c_row(idx); + + let (dense_halves, spread_halves) = self.assign_word_halves(region, row, c_val)?; + self.decompose_abcd(region, row, c_val)?; + Ok(RoundWordSpread::new(dense_halves, spread_halves)) + } + + fn decompose_f( + &self, + region: &mut Region<'_, Table16Chip>, + idx: i32, + f_val: u32, + ) -> Result { + let row = get_decompose_f_row(idx); + + let (dense_halves, spread_halves) = self.assign_word_halves(region, row, f_val)?; + self.decompose_efgh(region, row, f_val)?; + Ok(RoundWordSpread::new(dense_halves, spread_halves)) + } + + fn decompose_g( + &self, + region: &mut Region<'_, Table16Chip>, + idx: i32, + g_val: u32, + ) -> Result { + let row = get_decompose_g_row(idx); + + let (dense_halves, spread_halves) = self.assign_word_halves(region, row, g_val)?; + self.decompose_efgh(region, row, g_val)?; + Ok(RoundWordSpread::new(dense_halves, spread_halves)) + } +}