Skip to content

Commit eee18cd

Browse files
fix rebase issues
1 parent 13390a8 commit eee18cd

File tree

8 files changed

+853
-404
lines changed

8 files changed

+853
-404
lines changed

Cargo.lock

Lines changed: 748 additions & 343 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/circuits/sha-air/src/air.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -209,34 +209,44 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
209209
// Assert that the previous hash + work vars == final hash.
210210
// That is, `next.prev_hash[i] + local.work_vars[i] == next.final_hash[i]`
211211
// where addition is done modulo 2^32
212-
for i in 0..SHA256_HASH_WORDS {
212+
for i in 0..C::HASH_WORDS {
213213
let mut carry = AB::Expr::ZERO;
214-
for j in 0..SHA256_WORD_U16S {
215-
let work_var_limb = if i < SHA256_ROUNDS_PER_ROW {
214+
for j in 0..C::WORD_U16S {
215+
let work_var_limb = if i < C::ROUNDS_PER_ROW {
216216
compose::<AB::Expr>(
217-
&local.work_vars.a[SHA256_ROUNDS_PER_ROW - 1 - i][j * 16..(j + 1) * 16],
217+
&local
218+
.work_vars
219+
.a
220+
.slice(s![C::ROUNDS_PER_ROW - 1 - i, j * 16..(j + 1) * 16])
221+
.as_slice().unwrap(),
218222
1,
219223
)
220224
} else {
221225
compose::<AB::Expr>(
222-
&local.work_vars.e[SHA256_ROUNDS_PER_ROW + 3 - i][j * 16..(j + 1) * 16],
226+
&local
227+
.work_vars
228+
.e
229+
.slice(s![C::ROUNDS_PER_ROW + 3 - i, j * 16..(j + 1) * 16])
230+
.as_slice().unwrap(),
223231
1,
224232
)
225233
};
226-
let final_hash_limb =
227-
compose::<AB::Expr>(&next.final_hash[i][j * 2..(j + 1) * 2], 8);
234+
let final_hash_limb = compose::<AB::Expr>(
235+
&next.final_hash.slice(s![i, j * 2..(j + 1) * 2]).as_slice().unwrap(),
236+
8,
237+
);
228238

229239
carry = AB::Expr::from(AB::F::from_canonical_u32(1 << 16).inverse())
230-
* (next.prev_hash[i][j] + work_var_limb + carry - final_hash_limb);
240+
* (next.prev_hash[[i,j]] + work_var_limb + carry - final_hash_limb);
231241
builder
232-
.when(next.flags.is_digest_row)
242+
.when(*next.flags.is_digest_row)
233243
.assert_bool(carry.clone());
234244
}
235245
// constrain the final hash limbs two at a time since we can do two checks per interaction
236-
for chunk in next.final_hash[i].chunks(2) {
246+
for chunk in next.final_hash.row(i).as_slice().unwrap().chunks(2) {
237247
self.bitwise_lookup_bus
238248
.send_range(chunk[0], chunk[1])
239-
.eval(builder, next.flags.is_digest_row);
249+
.eval(builder, *next.flags.is_digest_row);
240250
}
241251
}
242252
}
@@ -364,7 +374,7 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
364374
.assert_zero(*next_cols.flags.local_block_idx);
365375

366376
self.eval_message_schedule(builder, local_cols.clone(), next_cols.clone());
367-
self.eval_work_vars(builder, local_cols, next_cols);
377+
self.eval_work_vars(builder, local_cols.clone(), next_cols);
368378
let next_cols: ShaDigestColsRef<AB::Var> =
369379
ShaDigestColsRef::from::<C>(&next[start_col..start_col + C::DIGEST_WIDTH]);
370380
self.eval_digest_row(builder, local_cols, next_cols);

crates/circuits/sha-air/src/columns.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub struct ShaMessageScheduleCols<
6969
const ROUNDS_PER_ROW: usize,
7070
const WORD_U8S: usize,
7171
> {
72-
/// The message schedule words as 32-bit intergers
72+
/// The message schedule words as 32-bit integers
7373
pub w: [[T; WORD_BITS]; ROUNDS_PER_ROW],
7474
/// Will be message schedule carries for rows 4..C::ROUND_ROWS and a buffer for rows 0..4 to be used freely by wrapper chips
7575
/// Note: carries are represented as 2 bit numbers

crates/circuits/sha-air/src/config.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ pub trait ShaConfig: Send + Sync + Clone {
4040
const ROUNDS_PER_ROW_MINUS_ONE: usize = Self::ROUNDS_PER_ROW - 1;
4141
/// Number of rounds per block. Must be a multiple of Self::ROUNDS_PER_ROW
4242
const ROUNDS_PER_BLOCK: usize;
43-
/// Number of rows used to constrain rounds
44-
const ROUND_ROWS: usize = Self::ROUNDS_PER_BLOCK / Self::ROUNDS_PER_ROW;
4543
/// Number of words in a SHA hash
4644
const HASH_WORDS: usize;
4745
/// Number of vars needed to encode the row index with [Encoder]
@@ -85,7 +83,7 @@ pub trait ShaConfig: Send + Sync + Clone {
8583
/// To optimize the trace generation of invalid rows, we precompute those values.
8684
/// This trait also stores the constants K and H for the given SHA config.
8785
pub trait ShaPrecomputedValues<T> {
88-
// these should be appropirately sized for the config
86+
// these should be appropriately sized for the config
8987
fn get_invalid_carry_a(round_num: usize) -> &'static [u32];
9088
fn get_invalid_carry_e(round_num: usize) -> &'static [u32];
9189
fn get_k() -> &'static [T];

crates/circuits/sha-air/src/tests.rs

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use std::{array, borrow::BorrowMut, cmp::max, sync::Arc};
1+
use std::{borrow::BorrowMut, cmp::max, sync::Arc};
2+
use crate::{ShaDigestColsRefMut, ShaRoundColsRefMut, ShaRoundColsRef};
23

34
use openvm_circuit::arch::{
45
instructions::riscv::RV32_CELL_BITS,
@@ -22,8 +23,7 @@ use openvm_stark_sdk::utils::create_seeded_rng;
2223
use rand::Rng;
2324

2425
use crate::{
25-
compose, small_sig0_field, Sha256Config, Sha512Config, ShaAir, ShaConfig, ShaFlagsColsRef,
26-
ShaFlagsColsRefMut, ShaPrecomputedValues,
26+
compose, small_sig0_field, Sha256Config, Sha512Config, ShaAir, ShaConfig, ShaPrecomputedValues,
2727
};
2828

2929
// A wrapper AIR purely for testing purposes
@@ -101,7 +101,7 @@ fn rand_sha_test<C: ShaConfig + ShaPrecomputedValues<C::Word> + 'static>() {
101101
let bitwise_chip = SharedBitwiseOperationLookupChip::<RV32_CELL_BITS>::new(bitwise_bus);
102102
let len = rng.gen_range(1..100);
103103
let random_records: Vec<_> = (0..len)
104-
.map(|_| {
104+
.map(|i| {
105105
(
106106
(0..C::BLOCK_U8S)
107107
.map(|_| rng.gen::<u8>())
@@ -137,7 +137,7 @@ fn rand_sha512_test() {
137137
pub struct ShaTestBadFinalHashChip<C: ShaConfig + ShaPrecomputedValues<C::Word>> {
138138
pub air: ShaTestAir<C>,
139139
pub bitwise_lookup_chip: SharedBitwiseOperationLookupChip<8>,
140-
pub records: Vec<(Vec<u8>, bool)>, // length of inner vec is C::BLOCK_U8S
140+
pub records: Vec<(Vec<u8>, bool)>, // length of inner vec should be C::BLOCK_U8S
141141
}
142142

143143
impl<SC: StarkGenericConfig, C: ShaConfig + ShaPrecomputedValues<C::Word> + 'static> Chip<SC>
@@ -150,7 +150,7 @@ where
150150
}
151151

152152
fn generate_air_proof_input(self) -> AirProofInput<SC> {
153-
let mut trace = crate::generate_trace::<Val<SC>>(
153+
let mut trace = crate::generate_trace::<Val<SC>, C>(
154154
&self.air.sub_air,
155155
self.bitwise_lookup_chip.clone(),
156156
self.records.clone(),
@@ -161,7 +161,7 @@ where
161161
for (i, row) in self.records.iter().enumerate() {
162162
if row.1 {
163163
let last_digest_row_idx = (i + 1) * C::ROWS_PER_BLOCK - 1;
164-
let last_digest_row: crate::ShaDigestColsRefMut<Val<SC>> =
164+
let mut last_digest_row: crate::ShaDigestColsRefMut<Val<SC>> =
165165
ShaDigestColsRefMut::from::<C>(
166166
trace.row_mut(last_digest_row_idx)[..C::DIGEST_WIDTH].borrow_mut(),
167167
);
@@ -176,10 +176,10 @@ where
176176
trace.row_pair_mut(last_digest_row_idx - 1, last_digest_row_idx);
177177
let last_round_row: crate::ShaRoundColsRefMut<Val<SC>> =
178178
ShaRoundColsRefMut::from::<C>(last_round_row.borrow_mut());
179-
let last_digest_row: crate::ShaRoundColsRefMut<Val<SC>> =
179+
let mut last_digest_row: crate::ShaRoundColsRefMut<Val<SC>> =
180180
ShaRoundColsRefMut::from::<C>(last_digest_row.borrow_mut());
181181
// fix the intermed_4 for the digest row
182-
generate_intermed_4(last_round_row, last_digest_row);
182+
generate_intermed_4::<Val<SC>, C>(&ShaRoundColsRef::from_mut::<C>(&last_round_row), &mut last_digest_row);
183183
}
184184
}
185185

@@ -199,52 +199,72 @@ where
199199

200200
// Copy of private method in Sha256Air used for testing
201201
/// Puts the correct intermed_4 in the `next_row`
202-
fn generate_intermed_4<F: PrimeField32>(
203-
local_cols: &Sha256RoundCols<F>,
204-
next_cols: &mut Sha256RoundCols<F>,
202+
fn generate_intermed_4<F: PrimeField32, C: ShaConfig + ShaPrecomputedValues<C::Word>>(
203+
local_cols: &ShaRoundColsRef<F>,
204+
next_cols: &mut ShaRoundColsRefMut<F>,
205205
) {
206-
let w = [local_cols.message_schedule.w, next_cols.message_schedule.w].concat();
207-
let w_limbs: Vec<[F; SHA256_WORD_U16S]> = w
206+
let w = [
207+
local_cols
208+
.message_schedule
209+
.w
210+
.rows()
211+
.into_iter()
212+
.collect::<Vec<_>>(),
213+
next_cols
214+
.message_schedule
215+
.w
216+
.rows()
217+
.into_iter()
218+
.collect::<Vec<_>>(),
219+
]
220+
.concat();
221+
222+
223+
// length of inner vec is C::WORD_U16S
224+
let w_limbs: Vec<Vec<F>> = w
208225
.iter()
209-
.map(|x| array::from_fn(|i| compose::<F>(&x[i * 16..(i + 1) * 16], 1)))
226+
.map(|x| {
227+
(0..C::WORD_U16S)
228+
.map(|i| compose::<F>(&x.as_slice().unwrap()[i * 16..(i + 1) * 16], 1))
229+
.collect::<Vec<F>>()
230+
})
210231
.collect();
211-
for i in 0..SHA256_ROUNDS_PER_ROW {
212-
let sig_w = small_sig0_field::<F>(&w[i + 1]);
213-
let sig_w_limbs: [F; SHA256_WORD_U16S] =
214-
array::from_fn(|j| compose::<F>(&sig_w[j * 16..(j + 1) * 16], 1));
232+
for i in 0..C::ROUNDS_PER_ROW {
233+
let sig_w = small_sig0_field::<F, C>(w[i + 1].as_slice().unwrap());
234+
let sig_w_limbs: Vec<F> = (0..C::WORD_U16S)
235+
.map(|j| compose::<F>(&sig_w[j * 16..(j + 1) * 16], 1))
236+
.collect();
215237
for (j, sig_w_limb) in sig_w_limbs.iter().enumerate() {
216-
next_cols.schedule_helper.intermed_4[i][j] = w_limbs[i][j] + *sig_w_limb;
238+
next_cols.schedule_helper.intermed_4[[i, j]] = w_limbs[i][j] + *sig_w_limb;
217239
}
218240
}
219241
}
220242

221-
impl ChipUsageGetter for Sha256TestBadFinalHashChip {
243+
impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ChipUsageGetter for ShaTestBadFinalHashChip<C> {
222244
fn air_name(&self) -> String {
223245
get_air_name(&self.air)
224246
}
225247
fn current_trace_height(&self) -> usize {
226-
self.records.len() * SHA256_ROWS_PER_BLOCK
248+
self.records.len() * C::ROWS_PER_BLOCK
227249
}
228250

229251
fn trace_width(&self) -> usize {
230-
max(SHA256_ROUND_WIDTH, SHA256_DIGEST_WIDTH)
252+
max(C::ROUND_WIDTH, C::DIGEST_WIDTH)
231253
}
232254
}
233255

234-
#[test]
235-
#[should_panic]
236-
fn test_sha256_final_hash_constraints() {
256+
fn test_sha_final_hash_constraints<C: ShaConfig + ShaPrecomputedValues<C::Word> + 'static>() {
237257
let mut rng = create_seeded_rng();
238258
let tester = VmChipTestBuilder::default();
239259
let bitwise_bus = BitwiseOperationLookupBus::new(BITWISE_OP_LOOKUP_BUS);
240260
let bitwise_chip = SharedBitwiseOperationLookupChip::<RV32_CELL_BITS>::new(bitwise_bus);
241261
let len = rng.gen_range(1..100);
242262
let random_records: Vec<_> = (0..len)
243-
.map(|_| (array::from_fn(|_| rng.gen::<u8>()), true))
263+
.map(|_| ((0..C::BLOCK_U8S).map(|_| rng.gen::<u8>()).collect::<Vec<_>>(), true))
244264
.collect();
245-
let chip = Sha256TestBadFinalHashChip {
246-
air: Sha256TestAir {
247-
sub_air: Sha256Air::new(bitwise_bus, SELF_BUS_IDX),
265+
let chip = ShaTestBadFinalHashChip {
266+
air: ShaTestAir {
267+
sub_air: ShaAir::<C>::new(bitwise_bus, SELF_BUS_IDX),
248268
},
249269
bitwise_lookup_chip: bitwise_chip.clone(),
250270
records: random_records,
@@ -253,3 +273,15 @@ fn test_sha256_final_hash_constraints() {
253273
let tester = tester.build().load(chip).load(bitwise_chip).finalize();
254274
tester.simple_test().expect("Verification failed");
255275
}
276+
277+
#[test]
278+
#[should_panic]
279+
fn test_sha256_final_hash_constraints() {
280+
test_sha_final_hash_constraints::<Sha256Config>();
281+
}
282+
283+
#[test]
284+
#[should_panic]
285+
fn test_sha512_final_hash_constraints() {
286+
test_sha_final_hash_constraints::<Sha512Config>();
287+
}

crates/circuits/sha-air/src/trace.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,10 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
339339
let final_hash: Vec<C::Word> = (0..C::HASH_WORDS)
340340
.map(|i| work_vars[i].wrapping_add(prev_hash[i]))
341341
.collect();
342-
let final_hash_limbs: Vec<Vec<C::Word>> = final_hash.iter().map(|i|
343-
word_into_u8_limbs::<C>(final_hash[i])
344-
)
342+
let final_hash_limbs: Vec<Vec<u32>> = final_hash
343+
.iter()
344+
.map(|word| word_into_u8_limbs::<C>(*word))
345+
.collect();
345346
// need to ensure final hash limbs are bytes, in order for
346347
// prev_hash[i] + work_vars[i] == final_hash[i]
347348
// to be constrained correctly
@@ -368,7 +369,7 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
368369
.collect::<Vec<_>>()
369370
}))
370371
.for_each(|(x, y)| *x = y);
371-
372+
372373
let hash = if is_last_block {
373374
C::get_h()
374375
.iter()
@@ -476,11 +477,20 @@ impl<C: ShaConfig + ShaPrecomputedValues<C::Word>> ShaAir<C> {
476477
&mut next_block_first_row[trace_start_col..trace_start_col + C::ROUND_WIDTH],
477478
);
478479
// Fill in the last round row's `intermed_12` with dummy values so the message schedule constraints holds on row 16
479-
Self::generate_intermed_12(&mut cols_last_round_row, ShaRoundColsRef::from_mut::<C>(&cols_digest_row));
480+
Self::generate_intermed_12(
481+
&mut cols_last_round_row,
482+
ShaRoundColsRef::from_mut::<C>(&cols_digest_row),
483+
);
480484
// Fill in the digest row's `intermed_12` with dummy values so the message schedule constraints holds on the next block's row 0
481-
Self::generate_intermed_12(&mut cols_digest_row, ShaRoundColsRef::from_mut::<C>(&cols_next_block_first_row));
485+
Self::generate_intermed_12(
486+
&mut cols_digest_row,
487+
ShaRoundColsRef::from_mut::<C>(&cols_next_block_first_row),
488+
);
482489
// Fill in the next block's first row's `intermed_4` with dummy values so the message schedule constraints holds on that row
483-
Self::generate_intermed_4(ShaRoundColsRef::from_mut::<C>(&cols_digest_row), &mut cols_next_block_first_row);
490+
Self::generate_intermed_4(
491+
ShaRoundColsRef::from_mut::<C>(&cols_digest_row),
492+
&mut cols_next_block_first_row,
493+
);
484494
}
485495

486496
/// Fills the `cols` as a padding row
@@ -796,9 +806,8 @@ pub fn generate_trace<F: PrimeField32, C: ShaConfig + ShaPrecomputedValues<C::Wo
796806
let input_words = (0..C::BLOCK_WORDS)
797807
.map(|i| {
798808
limbs_into_word::<C>(
799-
&(0..C::WORD_U8S).map(|j|
800-
input[((i + 1) * C::WORD_U8S - j - 1]
801-
)
809+
&(0..C::WORD_U8S)
810+
.map(|j| input[(i + 1) * C::WORD_U8S - j - 1] as u32)
802811
.collect::<Vec<_>>(),
803812
)
804813
})

crates/circuits/sha-air/src/utils.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::array;
2-
31
pub use openvm_circuit_primitives::utils::compose;
42
use openvm_circuit_primitives::{
53
encoder::Encoder,

crates/circuits/sha-macros/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
#![feature(proc_macro_diagnostic)]
2-
31
extern crate proc_macro;
42

53
use itertools::Itertools;
6-
//use openvm_macros_common::MacroArgs;
74
use proc_macro::TokenStream;
85
use quote::{format_ident, quote};
96
use syn::{parse_macro_input, parse_quote, DeriveInput, Expr};

0 commit comments

Comments
 (0)