Skip to content

Commit a8bcae2

Browse files
authored
feat: remove byte decomposition in compute_decomposition (#6159)
# Description ## Problem\* Resolves <!-- Link to GitHub Issue --> ## Summary\* This PR replaces `compute_decomposition` with a separate implementation which should be cheaper for the AVM to handle. Idea taken from Guillaume in #6084 . ## 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.
1 parent e4325aa commit a8bcae2

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

noir_stdlib/src/field/bn254.nr

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,18 @@ global PLO: Field = 53438638232309528389504892708671455233;
55
global PHI: Field = 64323764613183177041862057485226039389;
66

77
pub(crate) global TWO_POW_128: Field = 0x100000000000000000000000000000000;
8+
global TWO_POW_64: Field = 0x10000000000000000;
89

910
// Decomposes a single field into two 16 byte fields.
10-
fn compute_decomposition(x: Field) -> (Field, Field) {
11-
let x_bytes: [u8; 32] = x.to_le_bytes();
12-
13-
let mut low: Field = 0;
14-
let mut high: Field = 0;
15-
16-
let mut offset = 1;
17-
for i in 0..16 {
18-
low += (x_bytes[i] as Field) * offset;
19-
high += (x_bytes[i + 16] as Field) * offset;
20-
offset *= 256;
21-
}
11+
fn compute_decomposition(mut x: Field) -> (Field, Field) {
12+
// Here's we're taking advantage of truncating 64 bit limbs from the input field
13+
// and then subtracting them from the input such the field division is equivalent to integer division.
14+
let low_lower_64 = (x as u64) as Field;
15+
x = (x - low_lower_64) / TWO_POW_64;
16+
let low_upper_64 = (x as u64) as Field;
17+
18+
let high = (x - low_upper_64) / TWO_POW_64;
19+
let low = low_upper_64 * TWO_POW_64 + low_lower_64;
2220

2321
(low, high)
2422
}

0 commit comments

Comments
 (0)