From 5f3c41c369fc324cf11972b0acb37f39b37f798e Mon Sep 17 00:00:00 2001 From: Tom French Date: Thu, 26 Sep 2024 17:59:48 +0100 Subject: [PATCH 1/2] feat: remove byte decomposition in `compute_decomposition` --- noir_stdlib/src/field/bn254.nr | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/noir_stdlib/src/field/bn254.nr b/noir_stdlib/src/field/bn254.nr index 0aa5ca0717b..9292187528e 100644 --- a/noir_stdlib/src/field/bn254.nr +++ b/noir_stdlib/src/field/bn254.nr @@ -5,20 +5,18 @@ global PLO: Field = 53438638232309528389504892708671455233; global PHI: Field = 64323764613183177041862057485226039389; global TWO_POW_128: Field = 0x100000000000000000000000000000000; +global TWO_POW_64: Field = 10000000000000000; // Decomposes a single field into two 16 byte fields. -fn compute_decomposition(x: Field) -> (Field, Field) { - let x_bytes: [u8; 32] = x.to_le_bytes(); - - let mut low: Field = 0; - let mut high: Field = 0; - - let mut offset = 1; - for i in 0..16 { - low += (x_bytes[i] as Field) * offset; - high += (x_bytes[i + 16] as Field) * offset; - offset *= 256; - } +fn compute_decomposition(mut x: Field) -> (Field, Field) { + // Here's we're taking advantage of truncating 64 bit limbs from the input field + // and then subtracting them from the input such the field division is equivalent to integer division. + let low_lower_64 = (x as u64) as Field; + x = (x - low_lower_64) / TWO_POW_64; + let low_upper_64 = (x as u64) as Field; + + let high = (x - low_upper_64) / TWO_POW_64; + let low = low_upper_64 * TWO_POW_64 + low_lower_64; (low, high) } From 741b1d9b4ca0523afb1a2f4eeb1b8645873b409a Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 27 Sep 2024 12:19:16 +0100 Subject: [PATCH 2/2] Update noir_stdlib/src/field/bn254.nr --- noir_stdlib/src/field/bn254.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir_stdlib/src/field/bn254.nr b/noir_stdlib/src/field/bn254.nr index 9292187528e..b92ba1dc983 100644 --- a/noir_stdlib/src/field/bn254.nr +++ b/noir_stdlib/src/field/bn254.nr @@ -5,7 +5,7 @@ global PLO: Field = 53438638232309528389504892708671455233; global PHI: Field = 64323764613183177041862057485226039389; global TWO_POW_128: Field = 0x100000000000000000000000000000000; -global TWO_POW_64: Field = 10000000000000000; +global TWO_POW_64: Field = 0x10000000000000000; // Decomposes a single field into two 16 byte fields. fn compute_decomposition(mut x: Field) -> (Field, Field) {