Skip to content

Commit

Permalink
fix: enforce correctness of decompositions performed at compile time (#…
Browse files Browse the repository at this point in the history
…6278)

# Description

## Problem\*

Resolves #6244

## Summary\*

We were not checking that a radix decomposition simplification performed
at compile time was valid, resulting in a truncation to fit the result
array. This PR prevents the simplification in this case so we can
instead error at runtime.

## Additional Context



## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
TomAFrench authored Oct 21, 2024
1 parent 67ac0d6 commit 53252fd
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 15 deletions.
32 changes: 17 additions & 15 deletions compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ pub(super) fn simplify_call(
} else {
unreachable!("ICE: Intrinsic::ToRadix return type must be array")
};
let result_array = constant_to_radix(endian, field, 2, limb_count, dfg);

SimplifyResult::SimplifiedTo(result_array)
constant_to_radix(endian, field, 2, limb_count, dfg)
} else {
SimplifyResult::None
}
Expand All @@ -79,10 +77,7 @@ pub(super) fn simplify_call(
} else {
unreachable!("ICE: Intrinsic::ToRadix return type must be array")
};

let result_array = constant_to_radix(endian, field, radix, limb_count, dfg);

SimplifyResult::SimplifiedTo(result_array)
constant_to_radix(endian, field, radix, limb_count, dfg)
} else {
SimplifyResult::None
}
Expand Down Expand Up @@ -611,22 +606,29 @@ fn constant_to_radix(
radix: u32,
limb_count: u32,
dfg: &mut DataFlowGraph,
) -> ValueId {
) -> SimplifyResult {
let bit_size = u32::BITS - (radix - 1).leading_zeros();
let radix_big = BigUint::from(radix);
assert_eq!(BigUint::from(2u128).pow(bit_size), radix_big, "ICE: Radix must be a power of 2");
let big_integer = BigUint::from_bytes_be(&field.to_be_bytes());

// Decompose the integer into its radix digits in little endian form.
let decomposed_integer = big_integer.to_radix_le(radix);
let mut limbs = vecmap(0..limb_count, |i| match decomposed_integer.get(i as usize) {
Some(digit) => FieldElement::from_be_bytes_reduce(&[*digit]),
None => FieldElement::zero(),
});
if endian == Endian::Big {
limbs.reverse();
if limb_count < decomposed_integer.len() as u32 {
// `field` cannot be represented as `limb_count` bits.
// defer error to acir_gen.
SimplifyResult::None
} else {
let mut limbs = vecmap(0..limb_count, |i| match decomposed_integer.get(i as usize) {
Some(digit) => FieldElement::from_be_bytes_reduce(&[*digit]),
None => FieldElement::zero(),
});
if endian == Endian::Big {
limbs.reverse();
}
let result_array = make_constant_array(dfg, limbs, Type::unsigned(bit_size));
SimplifyResult::SimplifiedTo(result_array)
}
make_constant_array(dfg, limbs, Type::unsigned(bit_size))
}

fn to_u8_vec(dfg: &DataFlowGraph, values: im::Vector<Id<Value>>) -> Vec<u8> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "invalid_comptime_bits_decomposition"
type = "bin"
authors = [""]
compiler_version = ">=0.30.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn main() -> pub [u1; 1] {
let large_number: Field = 2;

large_number.to_be_bits()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "invalid_comptime_bytes_decomposition"
type = "bin"
authors = [""]
compiler_version = ">=0.30.0"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() -> pub [u8; 1] {
let large_number: Field = 256;
large_number.to_be_bytes()
}

0 comments on commit 53252fd

Please sign in to comment.