Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ad0b500
feat : ec_ops added with proper constraints for field element
ocdbytes Feb 26, 2026
e64cf9e
feat : added wide field ops for ec operations and added trait generics
ocdbytes Feb 28, 2026
ac142d6
feat : added dynamic multi limb approach with cost model for msm blac…
ocdbytes Mar 2, 2026
0f769a7
feat : added gnark optimisations for msm
ocdbytes Mar 4, 2026
92ab236
opt: added unchecked select for already constrained values in scalar …
ocdbytes Mar 4, 2026
4052765
feat : added scalar 0 and inf handling
ocdbytes Mar 5, 2026
6e7197b
feat : updated G offset for curve and refactor
ocdbytes Mar 5, 2026
64111f9
fix : private document items ci
ocdbytes Mar 6, 2026
76ec439
fix : document-private-items ci
ocdbytes Mar 6, 2026
b308656
fix : bug in curve params handling for bigger field curves
ocdbytes Mar 6, 2026
e0a3d1d
feat : updated native and non native curve implementations
ocdbytes Mar 11, 2026
5c5f1f1
fix : lint
ocdbytes Mar 11, 2026
ad1f690
feat : added wNAF implementation in native msm noir circuit
ocdbytes Mar 11, 2026
43efc92
merge: main
ocdbytes Mar 11, 2026
089e400
lint : document-private-items
ocdbytes Mar 11, 2026
665c17f
feat : added tests for proper coverage of logic
ocdbytes Mar 11, 2026
3e0ddab
feat : added merged doubles and signed digit window with skew correct…
ocdbytes Mar 12, 2026
1ac6a8e
feat : added prover hint for step by step multi limb ops and fused ta…
ocdbytes Mar 13, 2026
8f57e57
refactor : modules and comments
ocdbytes Mar 13, 2026
cf115a0
feat : bug fix and witness solving test for non native msm
ocdbytes Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ chrono = "0.4.41"
divan = "0.1.21"
hex = "0.4.3"
itertools = "0.14.0"
num-bigint = "0.4"
paste = "1.0.15"
postcard = { version = "1.1.1", features = ["use-std"] }
primitive-types = "0.13.1"
Expand Down
7 changes: 7 additions & 0 deletions noir-examples/embedded_curve_msm/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "embedded_curve_msm"
type = "bin"
authors = [""]
compiler_version = ">=0.22.0"

[dependencies]
9 changes: 9 additions & 0 deletions noir-examples/embedded_curve_msm/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ============================================================
# MSM test vectors: result = s1 * G + s2 * G
# Grumpkin curve order n = 21888242871839275222246405745257275088696311157297823662689037894645226208583
# ============================================================
# n - 2, n - 3 (previously failing with [2]G offset)
scalar1_lo = "201385395114098847380338600778089168197"
scalar1_hi = "64323764613183177041862057485226039389"
scalar2_lo = "201385395114098847380338600778089168196"
scalar2_hi = "64323764613183177041862057485226039389"
6 changes: 6 additions & 0 deletions noir-examples/embedded_curve_msm/Prover_near_identity.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# MSM edge case: n-2 and n-3 (previously failing with [2]G offset)
# Grumpkin curve order n = 21888242871839275222246405745257275088696311157297823662689037894645226208583
scalar1_lo = "201385395114098847380338600778089168197"
scalar1_hi = "64323764613183177041862057485226039389"
scalar2_lo = "201385395114098847380338600778089168196"
scalar2_hi = "64323764613183177041862057485226039389"
6 changes: 6 additions & 0 deletions noir-examples/embedded_curve_msm/Prover_near_order.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# MSM edge case: near-max scalars (n-10 and n-20)
# Grumpkin curve order n = 21888242871839275222246405745257275088696311157297823662689037894645226208583
scalar1_lo = "201385395114098847380338600778089168189"
scalar1_hi = "64323764613183177041862057485226039389"
scalar2_lo = "201385395114098847380338600778089168179"
scalar2_hi = "64323764613183177041862057485226039389"
5 changes: 5 additions & 0 deletions noir-examples/embedded_curve_msm/Prover_single_nonzero.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# MSM edge case: one zero scalar, one non-zero (0*G + 5*G = 5*G)
scalar1_lo = "0"
scalar1_hi = "0"
scalar2_lo = "5"
scalar2_hi = "0"
5 changes: 5 additions & 0 deletions noir-examples/embedded_curve_msm/Prover_zero_scalars.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# MSM edge case: all-zero scalars (0*G + 0*G = point at infinity)
scalar1_lo = "0"
scalar1_hi = "0"
scalar2_lo = "0"
scalar2_hi = "0"
52 changes: 52 additions & 0 deletions noir-examples/embedded_curve_msm/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use std::embedded_curve_ops::{
EmbeddedCurvePoint,
EmbeddedCurveScalar,
multi_scalar_mul,
};

/// Exercises the MultiScalarMul ACIR blackbox with 2 Grumpkin points.
/// Computes s1 * G + s2 * G where G is the Grumpkin generator.
fn main(
scalar1_lo: Field,
scalar1_hi: Field,
scalar2_lo: Field,
scalar2_hi: Field,
) {
// Grumpkin generator
let g = EmbeddedCurvePoint {
x: 1,
y: 17631683881184975370165255887551781615748388533673675138860,
is_infinite: false,
};

let s1 = EmbeddedCurveScalar { lo: scalar1_lo, hi: scalar1_hi };
let s2 = EmbeddedCurveScalar { lo: scalar2_lo, hi: scalar2_hi };

// MSM: result = s1 * G + s2 * G
let result = multi_scalar_mul([g, g], [s1, s2]);

// Prevent dead-code elimination - forces the blackbox to be retained
// Using is_infinite as return value ensures the MSM is computed
assert(result.is_infinite == (scalar1_lo + scalar1_hi + scalar2_lo + scalar2_hi == 0));
}

#[test]
fn test_msm() {
// 3*G on Grumpkin
let expected_x = 18660890509582237958343981571981920822503400000196279471655180441138020044621;
let expected_y = 8902249110305491597038405103722863701255802573786510474664632793109847672620;

main(1, 0, 2, 0);

// Verify by computing independently: 3*G should match
let g = EmbeddedCurvePoint {
x: 1,
y: 17631683881184975370165255887551781615748388533673675138860,
is_infinite: false,
};
let s3 = EmbeddedCurveScalar { lo: 3, hi: 0 };
let check = multi_scalar_mul([g], [s3]);

assert(check.x == expected_x);
assert(check.y == expected_y);
}
6 changes: 6 additions & 0 deletions noir-examples/native_msm/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "native_msm"
type = "bin"
authors = [""]

[dependencies]
5 changes: 5 additions & 0 deletions noir-examples/native_msm/Prover.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# MSM: result = s1 * G + s2 * G = 1*G + 2*G = 3*G
scalar1_lo = "1"
scalar1_hi = "0"
scalar2_lo = "2"
scalar2_hi = "0"
Loading
Loading