Skip to content

Commit 92ef102

Browse files
committed
feat: perform constant sha256 compressions at compile-time
1 parent 8516bbc commit 92ef102

2 files changed

Lines changed: 82 additions & 2 deletions

File tree

compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,9 @@ fn simplify_black_box_func(
610610
"ICE: `BlackBoxFunc::RANGE` calls should be transformed into a `Instruction::Cast`"
611611
)
612612
}
613-
BlackBoxFunc::Sha256Compression => SimplifyResult::None, //TODO(Guillaume)
613+
BlackBoxFunc::Sha256Compression => {
614+
blackbox::simplify_sha256_compression(dfg, arguments, block, call_stack)
615+
}
614616
BlackBoxFunc::AES128Encrypt => SimplifyResult::None,
615617
}
616618
}

compiler/noirc_evaluator/src/ssa/ir/instruction/call/blackbox.rs

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::sync::Arc;
22

3+
use acvm::blackbox_solver::sha256_compression;
34
use acvm::{BlackBoxFunctionSolver, BlackBoxResolutionError, FieldElement, acir::AcirField};
45

56
use crate::ssa::ir::call_stack::CallStackId;
@@ -233,6 +234,54 @@ pub(super) fn simplify_poseidon2_permutation(
233234
}
234235
}
235236

237+
pub(super) fn simplify_sha256_compression(
238+
dfg: &mut DataFlowGraph,
239+
arguments: &[ValueId],
240+
block: BasicBlockId,
241+
call_stack: CallStackId,
242+
) -> SimplifyResult {
243+
match (dfg.get_array_constant(arguments[0]), dfg.get_array_constant(arguments[1])) {
244+
(Some((state, _)), Some((msg_blocks, _)))
245+
if array_is_constant(dfg, &state) && array_is_constant(dfg, &msg_blocks) =>
246+
{
247+
let Some(mut state) = state
248+
.iter()
249+
.map(|id| {
250+
dfg.get_numeric_constant(*id)
251+
.expect("value id from array should point at constant")
252+
.try_to_u32()
253+
})
254+
.collect::<Option<Vec<u32>>>()
255+
.map(|vec| <[u32; 8]>::try_from(vec).unwrap())
256+
else {
257+
return SimplifyResult::None;
258+
};
259+
260+
let Some(msg_blocks) = msg_blocks
261+
.iter()
262+
.map(|id| {
263+
dfg.get_numeric_constant(*id)
264+
.expect("value id from array should point at constant")
265+
.try_to_u32()
266+
})
267+
.collect::<Option<Vec<u32>>>()
268+
.map(|vec| <[u32; 16]>::try_from(vec).unwrap())
269+
else {
270+
return SimplifyResult::None;
271+
};
272+
273+
sha256_compression(&mut state, &msg_blocks);
274+
275+
let new_state = state.into_iter().map(FieldElement::from);
276+
let typ = NumericType::Unsigned { bit_size: 32 };
277+
let result_array = make_constant_array(dfg, new_state, typ, block, call_stack);
278+
279+
SimplifyResult::SimplifiedTo(result_array)
280+
}
281+
_ => SimplifyResult::None,
282+
}
283+
}
284+
236285
pub(super) fn simplify_hash(
237286
dfg: &mut DataFlowGraph,
238287
arguments: &[ValueId],
@@ -308,7 +357,7 @@ pub(super) fn simplify_signature(
308357

309358
#[cfg(feature = "bn254")]
310359
#[cfg(test)]
311-
mod test {
360+
mod multi_scalar_mul {
312361
use crate::ssa::Ssa;
313362
use crate::ssa::opt::assert_normalized_ssa_equals;
314363

@@ -395,3 +444,32 @@ mod test {
395444
assert_normalized_ssa_equals(ssa, expected_src);
396445
}
397446
}
447+
448+
#[cfg(test)]
449+
mod sha256_compression {
450+
use crate::ssa::Ssa;
451+
use crate::ssa::opt::assert_normalized_ssa_equals;
452+
453+
#[test]
454+
fn is_optimized_out_with_constant_arguments() {
455+
let src = r#"
456+
acir(inline) fn main f0 {
457+
b0():
458+
v0 = make_array [u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0] : [u32; 8]
459+
v1 = make_array [u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0] : [u32; 16]
460+
v2 = call sha256_compression(v0, v1) -> [u32; 8]
461+
return v2
462+
}"#;
463+
let ssa = Ssa::from_str_simplifying(src).unwrap();
464+
let expected_src = r#"
465+
acir(inline) fn main f0 {
466+
b0():
467+
v1 = make_array [u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0] : [u32; 8]
468+
v2 = make_array [u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0, u32 0] : [u32; 16]
469+
v11 = make_array [u32 2091193876, u32 1113340840, u32 3461668143, u32 3254913767, u32 3068490961, u32 2551409935, u32 2927503052, u32 3205228454] : [u32; 8]
470+
return v11
471+
}
472+
"#;
473+
assert_normalized_ssa_equals(ssa, expected_src);
474+
}
475+
}

0 commit comments

Comments
 (0)