From 906065ed2eacf5f78784130e3015096a48be00bb Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 5 Feb 2024 15:59:40 +0000 Subject: [PATCH 1/2] add struct for each bigint modulus --- noir/noir_stdlib/src/bigint.nr | 329 ++++++++++++++++-- .../execution_success/3_add/src/main.nr | 30 +- .../execution_success/bigint/src/main.nr | 14 +- 3 files changed, 333 insertions(+), 40 deletions(-) diff --git a/noir/noir_stdlib/src/bigint.nr b/noir/noir_stdlib/src/bigint.nr index 110266512079..61051da71164 100644 --- a/noir/noir_stdlib/src/bigint.nr +++ b/noir/noir_stdlib/src/bigint.nr @@ -1,5 +1,5 @@ -use crate::ops::{Add, Sub, Mul, Div, Rem,}; - +use crate::ops::{Add, Sub, Mul, Div}; +use crate::cmp::Eq; global bn254_fq = [0x47, 0xFD, 0x7C, 0xD8, 0x16, 0x8C, 0x20, 0x3C, 0x8d, 0xca, 0x71, 0x68, 0x91, 0x6a, 0x81, 0x97, 0x5d, 0x58, 0x81, 0x81, 0xb6, 0x45, 0x50, 0xb8, 0x29, 0xa0, 0x31, 0xe1, 0x72, 0x4e, 0x64, 0x30]; @@ -36,46 +36,321 @@ impl BigInt { #[builtin(bigint_from_le_bytes)] fn from_le_bytes(bytes: [u8], modulus: [u8]) -> BigInt {} #[builtin(bigint_to_le_bytes)] - pub fn to_le_bytes(self) -> [u8] {} + fn to_le_bytes(self) -> [u8] {} - pub fn bn254_fr_from_le_bytes(bytes: [u8]) -> BigInt { - BigInt::from_le_bytes(bytes, bn254_fr) + fn check_32_bytes(self: Self, other: BigInt) -> bool { + let bytes = self.to_le_bytes(); + let o_bytes = other.to_le_bytes(); + let mut result = true; + for i in 0..32{ + result = result & (bytes[i] == o_bytes[i]); + } + result } - pub fn bn254_fq_from_le_bytes(bytes: [u8]) -> BigInt { - BigInt::from_le_bytes(bytes, bn254_fq) +} + + +trait BigField { + fn from_le_bytes(bytes: [u8]) -> Self; + fn to_le_bytes(self) -> [u8]; +} + +struct Secpk1Fq { + inner: BigInt, +} + +impl BigField for Secpk1Fq { + fn from_le_bytes(bytes: [u8]) -> Secpk1Fq { + Secpk1Fq { + inner: BigInt::from_le_bytes(bytes, secpk1_fq) + } + } + fn to_le_bytes(self) -> [u8] { + self.inner.to_le_bytes() } - pub fn secpk1_fq_from_le_bytes(bytes: [u8]) -> BigInt { - BigInt::from_le_bytes(bytes, secpk1_fq) +} + +impl Add for Secpk1Fq { + fn add(self: Self, other: Secpk1Fq) -> Secpk1Fq { + Secpk1Fq { + inner: self.inner.bigint_add(other.inner) + } } - pub fn secpk1_fr_from_le_bytes(bytes: [u8]) -> BigInt { - BigInt::from_le_bytes(bytes, secpk1_fr) +} +impl Sub for Secpk1Fq { + fn sub(self: Self, other: Secpk1Fq) -> Secpk1Fq { + Secpk1Fq { + inner: self.inner.bigint_sub(other.inner) + } } } +impl Mul for Secpk1Fq { + fn mul(self: Self, other: Secpk1Fq) -> Secpk1Fq { + Secpk1Fq { + inner: self.inner.bigint_mul(other.inner) + } -impl Add for BigInt { - fn add(self: Self, other: BigInt) -> BigInt { - self.bigint_add(other) } } -impl Sub for BigInt { - fn sub(self: Self, other: BigInt) -> BigInt { - self.bigint_sub(other) +impl Div for Secpk1Fq { + fn div(self: Self, other: Secpk1Fq) -> Secpk1Fq { + Secpk1Fq { + inner: self.inner.bigint_div(other.inner) + } } } -impl Mul for BigInt { - fn mul(self: Self, other: BigInt) -> BigInt { - self.bigint_mul(other) +impl Eq for Secpk1Fq { + fn eq(self: Self, other: Secpk1Fq) -> bool { + self.inner.check_32_bytes(other.inner) } } -impl Div for BigInt { - fn div(self: Self, other: BigInt) -> BigInt { - self.bigint_div(other) + +struct Secpk1Fr { + inner: BigInt, +} + +impl BigField for Secpk1Fr { + fn from_le_bytes(bytes: [u8]) -> Secpk1Fr { + Secpk1Fr { + inner: BigInt::from_le_bytes(bytes, secpk1_fr) + } + } + fn to_le_bytes(self) -> [u8] { + self.inner.to_le_bytes() + } +} + +impl Add for Secpk1Fr { + fn add(self: Self, other: Secpk1Fr) -> Secpk1Fr { + Secpk1Fr { + inner: self.inner.bigint_add(other.inner) + } } } -impl Rem for BigInt { - fn rem(self: Self, other: BigInt) -> BigInt { - let quotient = self.bigint_div(other); - self.bigint_sub(quotient.bigint_mul(other)) +impl Sub for Secpk1Fr { + fn sub(self: Self, other: Secpk1Fr) -> Secpk1Fr { + Secpk1Fr { + inner: self.inner.bigint_sub(other.inner) + } } } +impl Mul for Secpk1Fr { + fn mul(self: Self, other: Secpk1Fr) -> Secpk1Fr { + Secpk1Fr { + inner: self.inner.bigint_mul(other.inner) + } + } +} +impl Div for Secpk1Fr { + fn div(self: Self, other: Secpk1Fr) -> Secpk1Fr { + Secpk1Fr { + inner: self.inner.bigint_div(other.inner) + } + } +} +impl Eq for Secpk1Fr { + fn eq(self: Self, other: Secpk1Fr) -> bool { + self.inner.check_32_bytes(other.inner) + } +} + +struct Bn254Fr { + inner: BigInt, +} + +impl BigField for Bn254Fr { + fn from_le_bytes(bytes: [u8]) -> Bn254Fr { + Bn254Fr { + inner: BigInt::from_le_bytes(bytes, bn254_fr) + } + } + fn to_le_bytes(self) -> [u8] { + self.inner.to_le_bytes() + } +} + +impl Add for Bn254Fr { + fn add(self: Self, other: Bn254Fr) -> Bn254Fr { + Bn254Fr { + inner: self.inner.bigint_add(other.inner) + } + } +} +impl Sub for Bn254Fr { + fn sub(self: Self, other: Bn254Fr) -> Bn254Fr { + Bn254Fr { + inner: self.inner.bigint_sub(other.inner) + } + } +} +impl Mul for Bn254Fr { + fn mul(self: Self, other: Bn254Fr) -> Bn254Fr { + Bn254Fr { + inner: self.inner.bigint_mul(other.inner) + } + + } +} +impl Div for Bn254Fr { + fn div(self: Self, other: Bn254Fr) -> Bn254Fr { + Bn254Fr { + inner: self.inner.bigint_div(other.inner) + } + } +} +impl Eq for Bn254Fr { + fn eq(self: Self, other: Bn254Fr) -> bool { + self.inner.check_32_bytes(other.inner) + } +} + +struct Bn254Fq { + inner: BigInt, +} + +impl BigField for Bn254Fq { + fn from_le_bytes(bytes: [u8]) -> Bn254Fq { + Bn254Fq { + inner: BigInt::from_le_bytes(bytes, bn254_fq) + } + } + fn to_le_bytes(self) -> [u8] { + self.inner.to_le_bytes() + } +} + +impl Add for Bn254Fq { + fn add(self: Self, other: Bn254Fq) -> Bn254Fq { + Bn254Fq { + inner: self.inner.bigint_add(other.inner) + } + } +} +impl Sub for Bn254Fq { + fn sub(self: Self, other: Bn254Fq) -> Bn254Fq { + Bn254Fq { + inner: self.inner.bigint_sub(other.inner) + } + } +} +impl Mul for Bn254Fq { + fn mul(self: Self, other: Bn254Fq) -> Bn254Fq { + Bn254Fq { + inner: self.inner.bigint_mul(other.inner) + } + + } +} +impl Div for Bn254Fq { + fn div(self: Self, other: Bn254Fq) -> Bn254Fq { + Bn254Fq { + inner: self.inner.bigint_div(other.inner) + } + } +} +impl Eq for Bn254Fq { + fn eq(self: Self, other: Bn254Fq) -> bool { + self.inner.check_32_bytes(other.inner) + } +} + +struct Secpr1Fq { + inner: BigInt, +} + +impl BigField for Secpr1Fq { + fn from_le_bytes(bytes: [u8]) -> Secpr1Fq { + Secpr1Fq { + inner: BigInt::from_le_bytes(bytes, secpr1_fq) + } + } + fn to_le_bytes(self) -> [u8] { + self.inner.to_le_bytes() + } +} + +impl Add for Secpr1Fq { + fn add(self: Self, other: Secpr1Fq) -> Secpr1Fq { + Secpr1Fq { + inner: self.inner.bigint_add(other.inner) + } + } +} +impl Sub for Secpr1Fq { + fn sub(self: Self, other: Secpr1Fq) -> Secpr1Fq { + Secpr1Fq { + inner: self.inner.bigint_sub(other.inner) + } + } +} +impl Mul for Secpr1Fq { + fn mul(self: Self, other: Secpr1Fq) -> Secpr1Fq { + Secpr1Fq { + inner: self.inner.bigint_mul(other.inner) + } + + } +} +impl Div for Secpr1Fq { + fn div(self: Self, other: Secpr1Fq) -> Secpr1Fq { + Secpr1Fq { + inner: self.inner.bigint_div(other.inner) + } + } +} +impl Eq for Secpr1Fq { + fn eq(self: Self, other: Secpr1Fq) -> bool { + self.inner.check_32_bytes(other.inner) + } +} + +struct Secpr1Fr { + inner: BigInt, +} + +impl BigField for Secpr1Fr { + fn from_le_bytes(bytes: [u8]) -> Secpr1Fr { + Secpr1Fr { + inner: BigInt::from_le_bytes(bytes, secpr1_fr) + } + } + fn to_le_bytes(self) -> [u8] { + self.inner.to_le_bytes() + } +} + +impl Add for Secpr1Fr { + fn add(self: Self, other: Secpr1Fr) -> Secpr1Fr { + Secpr1Fr { + inner: self.inner.bigint_add(other.inner) + } + } +} +impl Sub for Secpr1Fr { + fn sub(self: Self, other: Secpr1Fr) -> Secpr1Fr { + Secpr1Fr { + inner: self.inner.bigint_sub(other.inner) + } + } +} +impl Mul for Secpr1Fr { + fn mul(self: Self, other: Secpr1Fr) -> Secpr1Fr { + Secpr1Fr { + inner: self.inner.bigint_mul(other.inner) + } + + } +} +impl Div for Secpr1Fr { + fn div(self: Self, other: Secpr1Fr) -> Secpr1Fr { + Secpr1Fr { + inner: self.inner.bigint_div(other.inner) + } + } +} +impl Eq for Secpr1Fr { + fn eq(self: Self, other: Secpr1Fr) -> bool { + self.inner.check_32_bytes(other.inner) + } +} diff --git a/noir/test_programs/execution_success/3_add/src/main.nr b/noir/test_programs/execution_success/3_add/src/main.nr index 480348dc1cf0..a42ccf2da30e 100644 --- a/noir/test_programs/execution_success/3_add/src/main.nr +++ b/noir/test_programs/execution_success/3_add/src/main.nr @@ -1,8 +1,30 @@ +use dep::std::bigint; +use dep::std; + // Test integer addition: 3 + 4 = 7 fn main(mut x: u32, y: u32, z: u32) { - x += y; - assert(x == z); + // x += y; + // assert(x == z); + + // x *= 8; + // assert(x > 9); +std::println("HELLO"); + let a = std::bigint::BigInt::secpk1_fq_from_le_bytes([3]); + let b = bigint::BigInt::secpk1_fq_from_le_bytes([5]); + std::println(a); + let c= a+b; + let bytes = (c*a-b-b).to_le_bytes(); + std::println(bytes[0]); + +// //sha +// let a = [0; 16]; +// let b= [0;8]; +// let c = std::hash::sha256_compression(a, b); +// std::println(c); - x *= 8; - assert(x > 9); +// let mut c=a + b; +// c= c.neg(b); +// c= c.mul(b); +// c=c.div(b); +// std::println(c); } diff --git a/noir/test_programs/execution_success/bigint/src/main.nr b/noir/test_programs/execution_success/bigint/src/main.nr index 74949a5f785d..4b8735062878 100644 --- a/noir/test_programs/execution_success/bigint/src/main.nr +++ b/noir/test_programs/execution_success/bigint/src/main.nr @@ -1,9 +1,8 @@ use dep::std::bigint; fn main(mut x: [u8;5], y: [u8;5]) { - let a = bigint::BigInt::secpk1_fq_from_le_bytes([x[0],x[1],x[2],x[3],x[4]]); - let b = bigint::BigInt::secpk1_fq_from_le_bytes([y[0],y[1],y[2],y[3],y[4]]); - + let a = bigint::Secpk1Fq::from_le_bytes([x[0],x[1],x[2],x[3],x[4]]); + let b = bigint::Secpk1Fq::from_le_bytes([y[0],y[1],y[2],y[3],y[4]]); let a_bytes = a.to_le_bytes(); let b_bytes = b.to_le_bytes(); for i in 0..5 { @@ -12,10 +11,7 @@ fn main(mut x: [u8;5], y: [u8;5]) { } let d = a*b - b; - let d_bytes = d.to_le_bytes(); - let d1 = bigint::BigInt::secpk1_fq_from_le_bytes(597243850900842442924.to_le_bytes(10)); - let d1_bytes = d1.to_le_bytes(); - for i in 0..32 { - assert(d_bytes[i] == d1_bytes[i]); - } + let d1 = bigint::Secpk1Fq::from_le_bytes(597243850900842442924.to_le_bytes(10)); + assert(d1 == d); + } From c8e1e1e3902007d5c49b2e271498da1e8ba775d1 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 5 Feb 2024 17:08:35 +0000 Subject: [PATCH 2/2] code review --- .../execution_success/3_add/src/main.nr | 32 +++---------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/noir/test_programs/execution_success/3_add/src/main.nr b/noir/test_programs/execution_success/3_add/src/main.nr index a42ccf2da30e..9c77af868b69 100644 --- a/noir/test_programs/execution_success/3_add/src/main.nr +++ b/noir/test_programs/execution_success/3_add/src/main.nr @@ -1,30 +1,8 @@ -use dep::std::bigint; -use dep::std; - // Test integer addition: 3 + 4 = 7 fn main(mut x: u32, y: u32, z: u32) { - // x += y; - // assert(x == z); - - // x *= 8; - // assert(x > 9); -std::println("HELLO"); - let a = std::bigint::BigInt::secpk1_fq_from_le_bytes([3]); - let b = bigint::BigInt::secpk1_fq_from_le_bytes([5]); - std::println(a); - let c= a+b; - let bytes = (c*a-b-b).to_le_bytes(); - std::println(bytes[0]); - -// //sha -// let a = [0; 16]; -// let b= [0;8]; -// let c = std::hash::sha256_compression(a, b); -// std::println(c); + x += y; + assert(x == z); -// let mut c=a + b; -// c= c.neg(b); -// c= c.mul(b); -// c=c.div(b); -// std::println(c); -} + x *= 8; + assert(x > 9); +} \ No newline at end of file