, owner: Address }
pub contract TokenContract uses (ctx: Ctx) {
- mut store: TokenStore
+ mut store: TokenStore,
- init() uses (mut store, ctx) {
- store.owner = ctx.caller()
- }
+ init() uses (mut store, ctx) { store.owner = ctx.caller() }
recv TokenMsg {
Mint { to, amount } uses (mut store, ctx) {
- assert_msg(ctx.caller() == store.owner, "only owner can mint")
+ assert!(ctx.caller() == store.owner, "only owner can mint")
store.total_supply += amount
store.balances.set(key: to, value: store.balances.get(key: to) + amount)
}
@@ -40,7 +33,9 @@ pub contract TokenContract uses (ctx: Ctx) {
Transfer { to, amount } -> bool uses (mut store, ctx) {
let from = ctx.caller()
let bal = store.balances.get(key: from)
- if bal < amount { return false }
+ if bal < amount {
+ return false
+ }
store.balances.set(key: from, value: bal - amount)
store.balances.set(key: to, value: store.balances.get(key: to) + amount)
true
@@ -50,7 +45,9 @@ pub contract TokenContract uses (ctx: Ctx) {
store.balances.get(key: account)
}
- TotalSupply -> u256 uses (store) { store.total_supply }
+ TotalSupply -> u256 uses (store) {
+ store.total_supply
+ }
}
}
@@ -92,16 +89,20 @@ struct GovStore {
/// Read a token balance via typed cross-contract call.
fn token_balance(token: Address, account: Address) -> u256
- uses (call: mut Call)
+uses (call: mut Call)
{
- call.static(addr: token, gas: 100000, message: TokenMsg::BalanceOf { account })
+ call.static(
+ addr: token,
+ gas: 100000,
+ message: TokenMsg::BalanceOf { account },
+ )
}
pub contract GovContract uses (ctx: Ctx, call: mut Call) {
- mut store: GovStore
+ mut store: GovStore,
init(token: Address, voting_period: u256, quorum: u256)
- uses (mut store)
+ uses (mut store)
{
store.token = token
store.voting_period = voting_period
@@ -110,7 +111,10 @@ pub contract GovContract uses (ctx: Ctx, call: mut Call) {
recv GovMsg {
Propose { description } -> u256 uses (mut store, ctx, mut call) {
- assert_msg(token_balance(token: store.token, account: ctx.caller()) > 0, "proposer has no tokens")
+ assert!(
+ token_balance(token: store.token, account: ctx.caller()) > 0,
+ "proposer has no tokens",
+ )
let id = store.proposal_count
store.proposal_count = id + 1
@@ -125,15 +129,24 @@ pub contract GovContract uses (ctx: Ctx, call: mut Call) {
let caller = ctx.caller()
let block = ctx.block_number()
- assert_msg(block >= store.vote_starts.get(key: proposal_id), "voting not started")
- assert_msg(block <= store.vote_ends.get(key: proposal_id), "voting ended")
- assert_msg(!store.has_voted.get(key: (proposal_id, caller)), "already voted")
+ assert!(
+ block >= store.vote_starts.get(key: proposal_id),
+ "voting not started",
+ )
+ assert!(
+ block <= store.vote_ends.get(key: proposal_id),
+ "voting ended",
+ )
+ assert!(
+ !store.has_voted.get(key: (proposal_id, caller)),
+ "already voted",
+ )
store.has_voted.set(key: (proposal_id, caller), value: true)
let weight = token_balance(token: store.token, account: caller)
- + store.delegated_weight.get(key: caller)
- assert_msg(weight > 0, "no voting power")
+ + store.delegated_weight.get(key: caller)
+ assert!(weight > 0, "no voting power")
if support {
let v = store.yes_votes.get(key: proposal_id)
@@ -163,18 +176,23 @@ pub contract GovContract uses (ctx: Ctx, call: mut Call) {
}
Execute { proposal_id } -> bool uses (mut store, ctx) {
- assert_msg(ctx.block_number() > store.vote_ends.get(key: proposal_id), "voting not ended")
- assert_msg(!store.executed.get(key: proposal_id), "already executed")
+ assert!(
+ ctx.block_number() > store.vote_ends.get(key: proposal_id),
+ "voting not ended",
+ )
+ assert!(!store.executed.get(key: proposal_id), "already executed")
let yes = store.yes_votes.get(key: proposal_id)
let no = store.no_votes.get(key: proposal_id)
- assert_msg(yes + no >= store.quorum, "quorum not reached")
+ assert!(yes + no >= store.quorum, "quorum not reached")
store.executed.set(key: proposal_id, value: true)
yes > no
}
- GetProposal { proposal_id } -> (u256, u256, u256, bool) uses (store) {
+ GetProposal { proposal_id } -> (u256, u256, u256, bool)
+ uses (store)
+ {
(
store.yes_votes.get(key: proposal_id),
store.no_votes.get(key: proposal_id),
@@ -183,15 +201,16 @@ pub contract GovContract uses (ctx: Ctx, call: mut Call) {
)
}
- ProposalCount -> u256 uses (store) { store.proposal_count }
+ ProposalCount -> u256 uses (store) {
+ store.proposal_count
+ }
GetDelegate { account } -> Address uses (store) {
store.delegates.get(key: account)
}
VotingPower { account } -> u256 uses (store, mut call) {
- token_balance(token: store.token, account)
- + store.delegated_weight.get(key: account)
+ token_balance(token: store.token, account) + store.delegated_weight.get(key: account)
}
}
}
diff --git a/examples/governance/test/GovernanceBench.t.sol b/examples/governance/test/GovernanceBench.t.sol
index 8a6b1ac..961069c 100644
--- a/examples/governance/test/GovernanceBench.t.sol
+++ b/examples/governance/test/GovernanceBench.t.sol
@@ -81,14 +81,12 @@ contract GovernanceBenchTest {
// --- Build Fe contracts ---
uint256 optLevel = vm.envOr("FE_SONA_OPT_LEVEL", uint256(2));
- string[] memory cmd = new string[](7);
+ string[] memory cmd = new string[](5);
cmd[0] = vm.envOr("FE_BIN", "fe");
cmd[1] = "build";
- cmd[2] = "--backend";
- cmd[3] = "sonatina";
- cmd[4] = "-O";
- cmd[5] = optLevel == 0 ? "0" : optLevel == 1 ? "1" : "2";
- cmd[6] = "fe";
+ cmd[2] = "-O";
+ cmd[3] = optLevel == 0 ? "0" : optLevel == 1 ? "1" : "2";
+ cmd[4] = "fe";
vm.ffi(cmd);
// Read TokenContract bytecode
diff --git a/examples/math/fe/src/full_math.fe b/examples/math/fe/src/full_math.fe
index c8e649e..ba0ecdf 100644
--- a/examples/math/fe/src/full_math.fe
+++ b/examples/math/fe/src/full_math.fe
@@ -15,12 +15,16 @@ pub fn mul_div(a: u256, b: u256, denominator: u256) -> u256 {
// Simple case: result fits in 256 bits
if prod1 == 0 {
- if denominator == 0 { assert(false) }
+ if denominator == 0 {
+ assert!(false)
+ }
return prod0 / denominator
}
// Overflow check
- if denominator <= prod1 { assert(false) }
+ if denominator <= prod1 {
+ assert!(false)
+ }
// Subtract remainder to make division exact
let remainder = mulmod(a, b, denominator)
@@ -53,7 +57,9 @@ pub fn mul_div(a: u256, b: u256, denominator: u256) -> u256 {
pub fn mul_div_rounding_up(a: u256, b: u256, denominator: u256) -> u256 {
let mut result = mul_div(a, b, denominator)
if mulmod(a, b, denominator) > 0 {
- if result == 0 - 1 { assert(false) }
+ if result == 0 - 1 {
+ assert!(false)
+ }
result = result + 1
}
result
diff --git a/examples/math/test/FullMathBench.t.sol b/examples/math/test/FullMathBench.t.sol
index fbb2286..e0a5518 100644
--- a/examples/math/test/FullMathBench.t.sol
+++ b/examples/math/test/FullMathBench.t.sol
@@ -46,14 +46,12 @@ contract FullMathBenchTest {
uint256 optLevel = vm.envOr("FE_SONA_OPT_LEVEL", uint256(2));
require(optLevel <= 2, "BAD_FE_SONA_OPT_LEVEL");
- string[] memory cmd = new string[](7);
+ string[] memory cmd = new string[](5);
cmd[0] = vm.envOr("FE_BIN", "fe");
cmd[1] = "build";
- cmd[2] = "--backend";
- cmd[3] = "sonatina";
- cmd[4] = "-O";
- cmd[5] = optLevel == 0 ? "0" : optLevel == 1 ? "1" : "2";
- cmd[6] = "fe"; // local math ingot
+ cmd[2] = "-O";
+ cmd[3] = optLevel == 0 ? "0" : optLevel == 1 ? "1" : "2";
+ cmd[4] = "fe"; // local math ingot
vm.ffi(cmd);
// Deploy Fe contract from compiled bytecode
diff --git a/examples/merkle/test/MerkleProofBench.t.sol b/examples/merkle/test/MerkleProofBench.t.sol
index cf9714b..64cc8a6 100644
--- a/examples/merkle/test/MerkleProofBench.t.sol
+++ b/examples/merkle/test/MerkleProofBench.t.sol
@@ -32,14 +32,12 @@ contract MerkleProofBenchTest {
vm.pauseGasMetering();
uint256 optLevel = vm.envOr("FE_SONA_OPT_LEVEL", uint256(2));
- string[] memory cmd = new string[](7);
+ string[] memory cmd = new string[](5);
cmd[0] = vm.envOr("FE_BIN", "fe");
cmd[1] = "build";
- cmd[2] = "--backend";
- cmd[3] = "sonatina";
- cmd[4] = "-O";
- cmd[5] = optLevel == 0 ? "0" : optLevel == 1 ? "1" : "2";
- cmd[6] = "fe";
+ cmd[2] = "-O";
+ cmd[3] = optLevel == 0 ? "0" : optLevel == 1 ? "1" : "2";
+ cmd[4] = "fe";
vm.ffi(cmd);
string[] memory readCmd = new string[](3);
diff --git a/examples/poseidon/fe/src/constants.fe b/examples/poseidon/fe/src/constants.fe
index 76de484..c6043c0 100644
--- a/examples/poseidon/fe/src/constants.fe
+++ b/examples/poseidon/fe/src/constants.fe
@@ -1,7 +1,6 @@
/// Poseidon optimized constants for T=3 (2-input) over BN254.
/// Source: iden3/circomlibjs poseidon_constants_opt.json
/// Uses the Filecoin/Neptune sparse matrix optimization.
-
/// BN254 scalar field prime
pub const PRIME: u256 = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
@@ -388,14 +387,38 @@ pub const S: [u256; 285] = [
/// MDS matrix (full rounds)
pub const M: [[u256; 3]; 3] = [
- [0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771, 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7],
- [0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0, 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23, 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911],
- [0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d, 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa, 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0],
+ [
+ 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b,
+ 0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771,
+ 0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7,
+ ],
+ [
+ 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0,
+ 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23,
+ 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911,
+ ],
+ [
+ 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d,
+ 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa,
+ 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0,
+ ],
]
/// Pre-sparse matrix (applied before partial rounds)
pub const P_MAT: [[u256; 3]; 3] = [
- [0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, 0x1e6f20a11d1e31e43f83dcedddb9a0236203f5f24ae72c925a8a79a66831f51d, 0x1bd8c528472e57bdc722a141f8785694484f426725403ae24084e3027e782467],
- [0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0, 0x2d51ba82c8073c6d6bacf1ad5e56655b7143625b0a9e9c3190527a1a5f05079a, 0x1b07d6d51e6f7e97e0ab10fc2e51ea83ce0611f940ff0731b5f927fe8d6a77c9],
- [0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d, 0x11e12a40d262ae88e8376f62d19edf43093cdef1ccf34d985a3e53f0bc5765a0, 0x221c170e4d02a2479c6f3e47b5ff55781574f980d89038308a3ef37cce8463bd],
+ [
+ 0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b,
+ 0x1e6f20a11d1e31e43f83dcedddb9a0236203f5f24ae72c925a8a79a66831f51d,
+ 0x1bd8c528472e57bdc722a141f8785694484f426725403ae24084e3027e782467,
+ ],
+ [
+ 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0,
+ 0x2d51ba82c8073c6d6bacf1ad5e56655b7143625b0a9e9c3190527a1a5f05079a,
+ 0x1b07d6d51e6f7e97e0ab10fc2e51ea83ce0611f940ff0731b5f927fe8d6a77c9,
+ ],
+ [
+ 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d,
+ 0x11e12a40d262ae88e8376f62d19edf43093cdef1ccf34d985a3e53f0bc5765a0,
+ 0x221c170e4d02a2479c6f3e47b5ff55781574f980d89038308a3ef37cce8463bd,
+ ],
]
diff --git a/examples/poseidon/fe/src/fp.fe b/examples/poseidon/fe/src/fp.fe
index 3be100e..256eae9 100644
--- a/examples/poseidon/fe/src/fp.fe
+++ b/examples/poseidon/fe/src/fp.fe
@@ -2,9 +2,7 @@ use std::evm::crypto::{addmod, mulmod}
use core::ops::{Add, Mul}
use super::constants::PRIME
-pub struct Fp {
- pub val: u256,
-}
+pub struct Fp { pub val: u256 }
impl Copy for Fp {}
@@ -21,10 +19,12 @@ impl Mul for Fp {
}
impl Fp {
- pub const fn new(val: u256) -> Fp { Fp { val } }
-
- pub const fn zero() -> Fp { Fp { val: 0 } }
-
+ pub const fn new(val: u256) -> Fp {
+ Fp { val }
+ }
+ pub const fn zero() -> Fp {
+ Fp { val: 0 }
+ }
pub const fn pow5(self) -> Fp {
let x2: Fp = self * self
let x4: Fp = x2 * x2
diff --git a/examples/poseidon/fe/src/lib.fe b/examples/poseidon/fe/src/lib.fe
index 05bbdea..561df0a 100644
--- a/examples/poseidon/fe/src/lib.fe
+++ b/examples/poseidon/fe/src/lib.fe
@@ -6,7 +6,6 @@
/// All pure functions are const fn, enabling compile-time evaluation
/// via CTFE. The static_asserts below verify known-answer vectors at
/// compile time with zero gas cost.
-
pub use constants::{PRIME, C, S, M, P_MAT, N_ROUNDS_F, N_ROUNDS_P}
pub use fp::Fp
@@ -54,7 +53,9 @@ pub const fn hash(a: u256, b: u256) -> u256 {
while r < N_ROUNDS_P {
s0 = s0.pow5() + Fp::new(val: C[(N_ROUNDS_F / 2 + 1) * 3 + r])
let off: usize = 5 * r
- let new_s0 = Fp::new(val: S[off]) * s0 + Fp::new(val: S[off + 1]) * s1 + Fp::new(val: S[off + 2]) * s2
+ let new_s0 = Fp::new(val: S[off]) * s0
+ + Fp::new(val: S[off + 1]) * s1
+ + Fp::new(val: S[off + 2]) * s2
s1 = s1 + s0 * Fp::new(val: S[off + 3])
s2 = s2 + s0 * Fp::new(val: S[off + 4])
s0 = new_s0
@@ -64,7 +65,13 @@ pub const fn hash(a: u256, b: u256) -> u256 {
// Second half full rounds
let mut r: usize = 0
while r < N_ROUNDS_F / 2 - 1 {
- let (r0, r1, r2) = full_round(s0, s1, s2, rc: (N_ROUNDS_F / 2 + 1) * 3 + N_ROUNDS_P + r * 3, mat: M)
+ let (r0, r1, r2) = full_round(
+ s0,
+ s1,
+ s2,
+ rc: (N_ROUNDS_F / 2 + 1) * 3 + N_ROUNDS_P + r * 3,
+ mat: M,
+ )
s0 = r0
s1 = r1
s2 = r2
@@ -80,6 +87,9 @@ pub const fn hash(a: u256, b: u256) -> u256 {
}
// Known-answer vectors from circomlibjs buildPoseidon(), verified at compile time.
-static_assert(hash(a: 0, b: 0) == 0x2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864)
-static_assert(hash(a: 1, b: 2) == 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a)
-static_assert(hash(a: 42, b: 17) == 0x18ddf7be412cfc792364a46eba440316dbb2427346063b747899e6ee0c3aa214)
+static_assert(hash(a: 0, b: 0)
+ == 0x2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864)
+static_assert(hash(a: 1, b: 2)
+ == 0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a)
+static_assert(hash(a: 42, b: 17)
+ == 0x18ddf7be412cfc792364a46eba440316dbb2427346063b747899e6ee0c3aa214)
diff --git a/examples/poseidon/test/PoseidonBench.t.sol b/examples/poseidon/test/PoseidonBench.t.sol
index 22d1f4e..bf7ed19 100644
--- a/examples/poseidon/test/PoseidonBench.t.sol
+++ b/examples/poseidon/test/PoseidonBench.t.sol
@@ -24,15 +24,13 @@ contract PoseidonBenchTest {
vm.pauseGasMetering();
// Deploy Fe Poseidon
- uint256 optLevel = vm.envOr("FE_SONA_OPT_LEVEL", uint256(0));
- string[] memory cmd = new string[](7);
+ uint256 optLevel = vm.envOr("FE_SONA_OPT_LEVEL", uint256(2));
+ string[] memory cmd = new string[](5);
cmd[0] = vm.envOr("FE_BIN", "fe");
cmd[1] = "build";
- cmd[2] = "--backend";
- cmd[3] = "sonatina";
- cmd[4] = "-O";
- cmd[5] = optLevel == 0 ? "0" : optLevel == 1 ? "1" : "2";
- cmd[6] = "fe";
+ cmd[2] = "-O";
+ cmd[3] = optLevel == 0 ? "0" : optLevel == 1 ? "1" : "2";
+ cmd[4] = "fe";
vm.ffi(cmd);
string[] memory readCmd = new string[](3);
diff --git a/examples/reverts/README.md b/examples/reverts/README.md
new file mode 100644
index 0000000..5570e4c
--- /dev/null
+++ b/examples/reverts/README.md
@@ -0,0 +1,19 @@
+# Revert output
+
+This example demonstrates Fe contract reverts that Foundry decodes like standard Solidity payloads:
+
+- checked arithmetic overflow emits `Panic(0x11)`, displayed as `panic: arithmetic underflow or overflow (0x11)`
+- `assert!(false)` emits `Panic(0x01)`, displayed as `panic: assertion failed (0x01)`
+- `assert!(false, "boom")` emits `Error(string)`, displayed as `boom`
+
+Run:
+
+```bash
+FE_BIN="$HOME/code/fe/master/target/release/fe" forge test -vv
+```
+
+To see Foundry's decoded failure output directly, run the opt-in display tests. These intentionally fail:
+
+```bash
+FE_BIN="$HOME/code/fe/master/target/release/fe" forge test --match-test test_display --no-match-test '^$' -vvv
+```
diff --git a/examples/reverts/fe/fe.toml b/examples/reverts/fe/fe.toml
new file mode 100644
index 0000000..54cb9c2
--- /dev/null
+++ b/examples/reverts/fe/fe.toml
@@ -0,0 +1,3 @@
+[ingot]
+name = "reverts"
+version = "0.1.0"
diff --git a/examples/reverts/fe/src/lib.fe b/examples/reverts/fe/src/lib.fe
new file mode 100644
index 0000000..83941e1
--- /dev/null
+++ b/examples/reverts/fe/src/lib.fe
@@ -0,0 +1,29 @@
+use std::abi::sol
+
+msg RevertOutputMsg {
+ #[selector = sol("checkedOverflow()")]
+ CheckedOverflow,
+ #[selector = sol("failedAssert()")]
+ FailedAssert,
+ #[selector = sol("failedAssertMsg()")]
+ FailedAssertMsg,
+}
+
+pub contract RevertOutput {
+ init() {}
+
+ recv RevertOutputMsg {
+ CheckedOverflow {} {
+ let x: u8 = 255
+ let y: u8 = x + 1
+ }
+
+ FailedAssert {} {
+ assert!(false)
+ }
+
+ FailedAssertMsg {} {
+ assert!(false, "boom")
+ }
+ }
+}
diff --git a/examples/reverts/foundry.toml b/examples/reverts/foundry.toml
new file mode 100644
index 0000000..03f580c
--- /dev/null
+++ b/examples/reverts/foundry.toml
@@ -0,0 +1,11 @@
+[profile.default]
+test = "test"
+ffi = true
+auto_detect_solc = true
+optimizer = true
+optimizer_runs = 200
+no_match_test = "test_display_"
+
+fs_permissions = [
+ { access = "read", path = "/" },
+]
diff --git a/examples/reverts/test/RevertOutput.t.sol b/examples/reverts/test/RevertOutput.t.sol
new file mode 100644
index 0000000..6277366
--- /dev/null
+++ b/examples/reverts/test/RevertOutput.t.sol
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.24;
+
+interface Vm {
+ function ffi(string[] calldata) external returns (bytes memory);
+ function envOr(string calldata name, string calldata defaultValue) external returns (string memory);
+ function expectRevert(bytes calldata revertData) external;
+}
+
+interface IRevertOutput {
+ function checkedOverflow() external;
+ function failedAssert() external;
+ function failedAssertMsg() external;
+}
+
+contract RevertOutputTest {
+ address private constant HEVM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code"))));
+ Vm private constant vm = Vm(HEVM_ADDRESS);
+
+ bytes4 private constant PANIC_SELECTOR = 0x4e487b71;
+ bytes4 private constant ERROR_SELECTOR = 0x08c379a0;
+
+ IRevertOutput private fe;
+
+ function setUp() public {
+ string[] memory buildCmd = new string[](3);
+ buildCmd[0] = "bash";
+ buildCmd[1] = "-lc";
+ buildCmd[2] = string.concat(
+ "fe_bin=${FE_BIN:-}; ",
+ "if { [ -z \"$fe_bin\" ] || [ \"$fe_bin\" = fe ]; } ",
+ "&& [ -x \"$HOME/code/fe/master/target/release/fe\" ]; then ",
+ "fe_bin=\"$HOME/code/fe/master/target/release/fe\"; ",
+ "fi; ",
+ "\"${fe_bin:-fe}\" build fe"
+ );
+ vm.ffi(buildCmd);
+
+ string[] memory readCmd = new string[](3);
+ readCmd[0] = "bash";
+ readCmd[1] = "-c";
+ readCmd[2] = "printf '0x'; tr -d '\\n' < fe/out/RevertOutput.bin";
+ bytes memory initcode = vm.ffi(readCmd);
+
+ address deployed;
+ assembly {
+ deployed := create(0, add(initcode, 0x20), mload(initcode))
+ }
+ require(deployed != address(0), "Fe deploy failed");
+ fe = IRevertOutput(deployed);
+ }
+
+ function test_fe_checked_overflow_reverts_with_solidity_panic() public {
+ vm.expectRevert(abi.encodeWithSelector(PANIC_SELECTOR, uint256(0x11)));
+ fe.checkedOverflow();
+ }
+
+ function test_fe_assert_reverts_with_solidity_panic() public {
+ vm.expectRevert(abi.encodeWithSelector(PANIC_SELECTOR, uint256(0x01)));
+ fe.failedAssert();
+ }
+
+ function test_fe_assert_msg_reverts_with_solidity_error_string() public {
+ vm.expectRevert(abi.encodeWithSelector(ERROR_SELECTOR, "boom"));
+ fe.failedAssertMsg();
+ }
+
+ function test_display_fe_checked_overflow() public {
+ fe.checkedOverflow();
+ }
+
+ function test_display_fe_assert() public {
+ fe.failedAssert();
+ }
+
+ function test_display_fe_assert_msg() public {
+ fe.failedAssertMsg();
+ }
+}
diff --git a/examples/verifier/fe/src/circuit.fe b/examples/verifier/fe/src/circuit.fe
index 5f055bd..533442c 100644
--- a/examples/verifier/fe/src/circuit.fe
+++ b/examples/verifier/fe/src/circuit.fe
@@ -6,7 +6,6 @@
///
/// A code generator targeting Fe would emit ONE of these — ~50 lines of
/// const declarations — instead of a 2000-line assembly monolith.
-
/// Describes a Halo2-style circuit's shape for verification.
pub struct CircuitShape {
/// Number of advice columns (prover witness).
@@ -41,10 +40,7 @@ const fn openvm_circuit() -> CircuitShape {
/// Verification key as const data.
/// In Solidity: 26 hex constants scattered across 2036 lines.
/// In Fe: a struct literal.
-pub struct VKPoint {
- pub x: u256,
- pub y: u256,
-}
+pub struct VKPoint { pub x: u256, pub y: u256 }
pub struct Halo2CircuitVK {
/// Transcript initialization constant.
@@ -54,7 +50,8 @@ pub struct Halo2CircuitVK {
/// Permutation commitments.
pub permutation_comms: [VKPoint; 4],
/// KZG SRS G2 point ([x]_2).
- pub g2_x: [u256; 4], // x_imag, x_real, y_imag, y_real
+ pub g2_x: [u256; 4],
+ // x_imag, x_real, y_imag, y_real
}
/// The OpenVM verification key — the 26 unique constants from Halo2Verifier.sol,
diff --git a/examples/verifier/fe/src/field.fe b/examples/verifier/fe/src/field.fe
index 32a56a1..07488b3 100644
--- a/examples/verifier/fe/src/field.fe
+++ b/examples/verifier/fe/src/field.fe
@@ -11,7 +11,6 @@ pub const F_Q: u256 = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593
/// compile-time parameter: Field and Field are distinct types
/// that the compiler monomorphizes into the same addmod/mulmod opcodes,
/// but you can't accidentally cross them.
-
pub const fn add(_ a: u256, _ b: u256) -> u256 {
addmod(a, b, MODULUS)
}
@@ -26,7 +25,13 @@ pub const fn sub(_ a: u256, _ b: u256) -> u256 {
/// Modular exponentiation via the modexp precompile (address 0x05).
pub fn exp(_ base: u256, _ exponent: u256) -> u256 {
- modexp(base, exponent, MODULUS)
+ match modexp(base, exp: exponent, modulus: MODULUS) {
+ Result::Ok(value,) => value,
+ Result::Err(_,) => {
+ assert!(false)
+ 0
+ },
+ }
}
/// Modular inverse: a^(-1) mod MODULUS via Fermat's little theorem.
diff --git a/examples/verifier/fe/src/groth16.fe b/examples/verifier/fe/src/groth16.fe
index cb3b192..600faa5 100644
--- a/examples/verifier/fe/src/groth16.fe
+++ b/examples/verifier/fe/src/groth16.fe
@@ -12,15 +12,12 @@ use std::evm::Evm
/// Fe version: the verifier is a reusable function parameterized by a
/// VerifyingKey struct. The same code works for any circuit — swap the
/// key, not the verifier. EC operations use the bn254 module.
-
/// A validated scalar field element. Guaranteed < SCALAR_FIELD on construction.
-pub struct ScalarInput {
- pub val: u256,
-}
+pub struct ScalarInput { pub val: u256 }
impl ScalarInput {
pub fn new(val: u256) -> ScalarInput {
- assert_msg(val < F_Q, "input exceeds scalar field")
+ assert!(val < F_Q, "input exceeds scalar field")
ScalarInput { val }
}
}
@@ -35,18 +32,20 @@ pub struct VerifyingKey {
pub ic: [G1Point; IC_LEN],
}
-pub struct Proof {
- pub a: G1Point,
- pub b: G2Point,
- pub c: G1Point,
-}
+pub struct Proof { pub a: G1Point, pub b: G2Point, pub c: G1Point }
/// Verify a Groth16 proof with N public inputs.
/// Inputs are validated on construction (ScalarInput::new asserts < SCALAR_FIELD).
-pub fn verify(vk: VerifyingKey, proof: Proof, inputs: [ScalarInput; N]) -> bool uses (evm: mut Evm) {
+pub fn verify(
+ vk: VerifyingKey,
+ proof: Proof,
+ inputs: [ScalarInput; N],
+) -> bool
+uses (evm: mut Evm)
+{
// Compute vk_x = IC[0] + sum(inputs[i] * IC[i+1])
let mut vk_x = vk.ic[0]
- for i in 0..N {
+ for i in 0 .. N {
vk_x = vk_x + vk.ic[i + 1].scale(s: inputs[i].val)
}
@@ -55,9 +54,13 @@ pub fn verify(vk: VerifyingKey,
// Pairing check: e(-A, B) * e(alpha, beta) * e(vk_x, gamma) * e(C, delta) == 1
pairing_4(
- a1: neg_a, b1: proof.b,
- a2: vk.alpha1, b2: vk.beta2,
- a3: vk_x, b3: vk.gamma2,
- a4: proof.c, b4: vk.delta2,
+ a1: neg_a,
+ b1: proof.b,
+ a2: vk.alpha1,
+ b2: vk.beta2,
+ a3: vk_x,
+ b3: vk.gamma2,
+ a4: proof.c,
+ b4: vk.delta2,
)
}
diff --git a/examples/verifier/fe/src/halo2.fe b/examples/verifier/fe/src/halo2.fe
index 7b61e5e..b42650c 100644
--- a/examples/verifier/fe/src/halo2.fe
+++ b/examples/verifier/fe/src/halo2.fe
@@ -13,7 +13,6 @@ use std::evm::crypto::{mulmod, addmod}
use std::evm::{Evm, RawOps}
/// BN254 scalar field — for all polynomial evaluations and challenges.
-
/// Halo2/KZG verification key.
///
/// In Solidity: 24 hardcoded hex constants inlined at the top of a 2036-line
@@ -24,10 +23,8 @@ pub struct Halo2VK {
/// Fixed commitments from the circuit (preprocessed polynomials).
/// The number of these varies by circuit, but the verifier logic is the same.
pub fixed_comms: [G1Point; 1],
-
/// Permutation commitments.
pub permutation_comms: [G1Point; 4],
-
/// The constant term embedded in the transcript initialization.
pub transcript_init: u256,
}
@@ -42,31 +39,22 @@ pub struct Halo2VK {
pub struct Halo2Proof {
/// Evaluations of instance (public input) polynomials at challenge point.
pub instance_evals: [u256; 1],
-
/// Advice column commitments (prover's witness).
pub advice_comms: [G1Point; 5],
-
/// Evaluations of advice polynomials at challenge point.
pub advice_evals: [u256; 14],
-
/// Evaluations of fixed polynomials at challenge point.
pub fixed_evals: [u256; 2],
-
/// Permutation product commitments.
pub permutation_z_comms: [G1Point; 4],
-
/// Evaluations of permutation polynomials.
pub permutation_evals: [u256; 12],
-
/// Vanishing argument commitment.
pub vanishing_random_comm: G1Point,
-
/// Quotient polynomial commitments.
pub h_comms: [G1Point; 4],
-
/// Random evaluation.
pub random_eval: u256,
-
/// KZG opening proofs.
pub w_x: G1Point,
pub w_g: G1Point,
@@ -80,9 +68,11 @@ pub struct Halo2Proof {
/// ...
///
/// In Fe: a loop.
-pub fn read_field_elements_from_calldata(offset: u256, count: usize) -> [u256; 32] uses (evm: mut Evm) {
+pub fn read_field_elements_from_calldata(offset: u256, count: usize) -> [u256; 32]
+uses (evm: mut Evm)
+{
let mut elems: [u256; 32] = [0; 32]
- for i in 0..count {
+ for i in 0 .. count {
let raw = evm.calldataload(offset + (i as u256) * 32)
elems[i] = raw % F_Q
}
@@ -120,21 +110,21 @@ pub fn validate_ec_point(p: G1Point) -> bool {
/// ...
///
/// In Fe: append to transcript, squeeze.
-pub fn derive_challenges(
- vk: Halo2VK, proof: Halo2Proof,
-) -> (u256, u256, u256, u256, u256) uses (evm: mut Evm) {
+pub fn derive_challenges(vk: Halo2VK, proof: Halo2Proof) -> (u256, u256, u256, u256, u256)
+uses (evm: mut Evm)
+{
let mut t = Transcript::new()
// Initialize with VK constant
t = t.write_u256(val: vk.transcript_init)
// Append instance evaluations
- for i in 0..1 {
+ for i in 0 .. 1 {
t = t.write_u256(val: proof.instance_evals[i])
}
// Append advice commitments
- for i in 0..5 {
+ for i in 0 .. 5 {
t = t.write_g1(p: proof.advice_comms[i])
}
@@ -150,13 +140,13 @@ pub fn derive_challenges(
let (gamma, _, mut t) = t.squeeze()
// Append permutation commitments for alpha
- for i in 0..4 {
+ for i in 0 .. 4 {
t = t.write_g1(p: proof.permutation_z_comms[i])
}
let (alpha, _, mut t) = t.squeeze()
// Append quotient commitments for x (evaluation point)
- for i in 0..4 {
+ for i in 0 .. 4 {
t = t.write_g1(p: proof.h_comms[i])
}
let (x, _, _) = t.squeeze()
@@ -172,10 +162,7 @@ pub fn derive_challenges(
/// success := and(eq(staticcall(gas(), 0x6, ...), 1), success) // ecAdd
///
/// In Fe: msm::msm() — one function call.
-pub fn kzg_accumulate(
- commitments: [G1Point; 21],
- scalars: [u256; 21],
-) -> G1Point {
+pub fn kzg_accumulate(commitments: [G1Point; 21], scalars: [u256; 21]) -> G1Point {
msm::msm<21>(commitments, scalars)
}
@@ -185,10 +172,9 @@ pub fn kzg_accumulate(
/// hand-laid-out memory.
///
/// In Fe: use our bn254 pairing primitive.
-pub fn kzg_pairing_check(
- p: G1Point, q: G1Point,
- g2_srs: G2Point,
-) -> bool uses (evm: mut Evm) {
+pub fn kzg_pairing_check(p: G1Point, q: G1Point, g2_srs: G2Point) -> bool
+uses (evm: mut Evm)
+{
// e(-P, [x]_2) * e(Q, G2_generator) == 1
let neg_p = negate(p: p)
diff --git a/examples/verifier/fe/src/msm.fe b/examples/verifier/fe/src/msm.fe
index aa9361f..ebd75c8 100644
--- a/examples/verifier/fe/src/msm.fe
+++ b/examples/verifier/fe/src/msm.fe
@@ -3,7 +3,7 @@ use ec::bn254::G1Point
/// Multi-scalar multiplication: sum(scalars[i] * points[i]).
pub fn msm(_ points: [G1Point; N], _ scalars: [u256; N]) -> G1Point {
let mut acc = points[0].scale(s: scalars[0])
- for i in 1..N {
+ for i in 1 .. N {
acc = acc + points[i].scale(s: scalars[i])
}
acc
diff --git a/examples/verifier/fe/src/plonk.fe b/examples/verifier/fe/src/plonk.fe
index 14519d4..1ff12c3 100644
--- a/examples/verifier/fe/src/plonk.fe
+++ b/examples/verifier/fe/src/plonk.fe
@@ -9,13 +9,15 @@ use std::evm::{Evm, RawMem}
/// Plonk proof verification on BN254.
/// Ported from SP1's Rust verifier (crates/verifier/src/plonk/).
/// Rust: 904 lines across 4 files. Solidity: 1341 lines of assembly.
-
-// Fiat-Shamir challenge labels (ASCII, left-aligned in u256)
-const GAMMA_LABEL: u256 = 0x67616d6d61000000000000000000000000000000000000000000000000000000 // "gamma"
-const BETA_LABEL: u256 = 0x6265746100000000000000000000000000000000000000000000000000000000 // "beta"
-const ALPHA_LABEL: u256 = 0x616c706861000000000000000000000000000000000000000000000000000000 // "alpha"
-const ZETA_LABEL: u256 = 0x7a65746100000000000000000000000000000000000000000000000000000000 // "zeta"
-
+ // Fiat-Shamir challenge labels (ASCII, left-aligned in u256)
+const GAMMA_LABEL: u256 = 0x67616d6d61000000000000000000000000000000000000000000000000000000
+// "gamma"
+const BETA_LABEL: u256 = 0x6265746100000000000000000000000000000000000000000000000000000000
+// "beta"
+const ALPHA_LABEL: u256 = 0x616c706861000000000000000000000000000000000000000000000000000000
+// "alpha"
+const ZETA_LABEL: u256 = 0x7a65746100000000000000000000000000000000000000000000000000000000
+// "zeta"
pub struct PlonkVK {
pub n: u256,
@@ -29,23 +31,31 @@ pub struct PlonkVK {
pub qo: G1Point,
pub qk: G1Point,
pub s: [G1Point; 3],
- pub qcp: [G1Point; 1], // BSB22 custom gate commitments (SP1 has 1)
+ pub qcp: [G1Point; 1],
+ // BSB22 custom gate commitments (SP1 has 1)
pub commit_constraint_idx: [usize; 1],
- pub g2_srs: [G2Point; 2], // [G2, [alpha]G2]
- pub g1_srs: G1Point, // G1 generator from SRS
+ pub g2_srs: [G2Point; 2],
+ // [G2, [alpha]G2]
+ pub g1_srs: G1Point,
+ // G1 generator from SRS
}
pub struct PlonkProof {
- pub lro: [G1Point; 3], // [L], [R], [O]
- pub z: G1Point, // grand product
- pub h: [G1Point; 3], // quotient [H0], [H1], [H2]
+ pub lro: [G1Point; 3],
+ // [L], [R], [O]
+ pub z: G1Point,
+ // grand product
+ pub h: [G1Point; 3],
+ // quotient [H0], [H1], [H2]
pub bsb22_commitments: [G1Point; 1],
// Batched opening proof
pub batched_h: G1Point,
- pub claimed_values: [u256; 6], // l, r, o, s1, s2, qcp[0]
+ pub claimed_values: [u256; 6],
+ // l, r, o, s1, s2, qcp[0]
// Shifted opening proof
pub z_shifted_h: G1Point,
- pub z_shifted_value: u256, // z(omega*zeta)
+ pub z_shifted_value: u256,
+ // z(omega*zeta)
}
// Transcript with Writable trait is in transcript.fe.
@@ -56,20 +66,33 @@ pub struct PlonkProof {
// This is the gnark hash_fr function from the Solidity verifier.
/// DST "BSB22-Plonk" as individual bytes for mstore8
-const HASH_FR_LEN_IN_BYTES: u256 = 48 // 0x30
-const HASH_FR_SIZE_DOMAIN: u256 = 11 // length of "BSB22-Plonk"
-const HASH_FR_BB: u256 = 340282366920938463463374607431768211456 // 2^128
+const HASH_FR_LEN_IN_BYTES: u256 = 48
+// 0x30
+const HASH_FR_SIZE_DOMAIN: u256 = 11
+// length of "BSB22-Plonk"
+const HASH_FR_BB: u256 = 340282366920938463463374607431768211456
+// 2^128
+
+fn sha256_word(offset: u256, len: u256) -> u256 {
+ match sha256(offset, len) {
+ Result::Ok(value,) => value,
+ Result::Err(_,) => {
+ assert!(false)
+ 0
+ },
+ }
+}
fn hash_fr(_ x: u256, _ y: u256) -> u256 uses (evm: mut Evm) {
let ptr = std::evm::alloc(256)
// Round 0: SHA256(zeros64 || x || y || 0x00 || 0x30 || 0x00 || "BSB22-Plonk" || 0x0b)
- evm.mstore(addr: ptr, value: 0) // 32 zero bytes
- evm.mstore(addr: ptr + 32, value: 0) // 32 zero bytes
+ evm.mstore(addr: ptr, value: 0) // 32 zero bytes
+ evm.mstore(addr: ptr + 32, value: 0) // 32 zero bytes
evm.mstore(addr: ptr + 64, value: x)
evm.mstore(addr: ptr + 96, value: y)
evm.mstore8(addr: ptr + 128, value: 0)
- evm.mstore8(addr: ptr + 129, value: 48) // HASH_FR_LEN_IN_BYTES
+ evm.mstore8(addr: ptr + 129, value: 48) // HASH_FR_LEN_IN_BYTES
evm.mstore8(addr: ptr + 130, value: 0)
// "BSB22-Plonk" = 42 53 42 32 32 2d 50 6c 6f 6e 6b
evm.mstore8(addr: ptr + 131, value: 0x42)
@@ -83,13 +106,13 @@ fn hash_fr(_ x: u256, _ y: u256) -> u256 uses (evm: mut Evm) {
evm.mstore8(addr: ptr + 139, value: 0x6f)
evm.mstore8(addr: ptr + 140, value: 0x6e)
evm.mstore8(addr: ptr + 141, value: 0x6b)
- evm.mstore8(addr: ptr + 142, value: 11) // HASH_FR_SIZE_DOMAIN
+ evm.mstore8(addr: ptr + 142, value: 11) // HASH_FR_SIZE_DOMAIN
- let b0 = sha256(ptr, 143)
+ let b0 = sha256_word(offset: ptr, len: 143)
// Round 1: SHA256(b0 || 0x01 || "BSB22-Plonk" || 0x0b)
evm.mstore(addr: ptr, value: b0)
- evm.mstore8(addr: ptr + 32, value: 1) // HASH_FR_ONE
+ evm.mstore8(addr: ptr + 32, value: 1) // HASH_FR_ONE
evm.mstore8(addr: ptr + 33, value: 0x42)
evm.mstore8(addr: ptr + 34, value: 0x53)
evm.mstore8(addr: ptr + 35, value: 0x42)
@@ -103,11 +126,11 @@ fn hash_fr(_ x: u256, _ y: u256) -> u256 uses (evm: mut Evm) {
evm.mstore8(addr: ptr + 43, value: 0x6b)
evm.mstore8(addr: ptr + 44, value: 11)
- let b1 = sha256(ptr, 45)
+ let b1 = sha256_word(offset: ptr, len: 45)
// Round 2: SHA256((b0 ^ b1) || 0x02 || "BSB22-Plonk" || 0x0b)
evm.mstore(addr: ptr, value: b0 ^ b1)
- evm.mstore8(addr: ptr + 32, value: 2) // HASH_FR_TWO
+ evm.mstore8(addr: ptr + 32, value: 2) // HASH_FR_TWO
evm.mstore8(addr: ptr + 33, value: 0x42)
evm.mstore8(addr: ptr + 34, value: 0x53)
evm.mstore8(addr: ptr + 35, value: 0x42)
@@ -121,10 +144,10 @@ fn hash_fr(_ x: u256, _ y: u256) -> u256 uses (evm: mut Evm) {
evm.mstore8(addr: ptr + 43, value: 0x6b)
evm.mstore8(addr: ptr + 44, value: 11)
- let b2 = sha256(ptr, 45)
+ let b2 = sha256_word(offset: ptr, len: 45)
// Result: 2^128 * b1 + b2[:16] mod R
- let b2_high = b2 >> 128 // top 16 bytes of b2
+ let b2_high = b2 >> 128 // top 16 bytes of b2
addmod(mulmod(b1, HASH_FR_BB, F_Q), b2_high, F_Q)
}
@@ -147,96 +170,99 @@ fn batch_invert_2(_ a: u256, _ b: u256) -> (u256, u256) {
/// Debug: compute and return challenge hashes for comparison.
/// Returns (gamma_raw, beta_raw, alpha_raw, zeta_raw)
-pub fn debug_challenges(
- vk: own PlonkVK, proof: own PlonkProof,
- pub_inputs: [u256; 5],
-) -> (u256, u256, u256, u256) uses (evm: mut Evm) {
+pub fn debug_challenges(vk: own PlonkVK, proof: own PlonkProof, pub_inputs: [u256; 5]) -> (
+ u256,
+ u256,
+ u256,
+ u256,
+)
+uses (evm: mut Evm)
+{
let mut t = Transcript::new()
// gamma
t = t.write_label(label: GAMMA_LABEL, label_len: 5)
- t = t.write_g1(p:vk.s[0])
- t = t.write_g1(p:vk.s[1])
- t = t.write_g1(p:vk.s[2])
- t = t.write_g1(p:vk.ql)
- t = t.write_g1(p:vk.qr)
- t = t.write_g1(p:vk.qm)
- t = t.write_g1(p:vk.qo)
- t = t.write_g1(p:vk.qk)
- t = t.write_g1(p:vk.qcp[0])
+ t = t.write_g1(p: vk.s[0])
+ t = t.write_g1(p: vk.s[1])
+ t = t.write_g1(p: vk.s[2])
+ t = t.write_g1(p: vk.ql)
+ t = t.write_g1(p: vk.qr)
+ t = t.write_g1(p: vk.qm)
+ t = t.write_g1(p: vk.qo)
+ t = t.write_g1(p: vk.qk)
+ t = t.write_g1(p: vk.qcp[0])
let mut pi_idx: usize = 0
while pi_idx < 5 {
- t = t.write_u256(val:pub_inputs[pi_idx])
+ t = t.write_u256(val: pub_inputs[pi_idx])
pi_idx = pi_idx + 1
}
- t = t.write_g1(p:proof.lro[0])
- t = t.write_g1(p:proof.lro[1])
- t = t.write_g1(p:proof.lro[2])
+ t = t.write_g1(p: proof.lro[0])
+ t = t.write_g1(p: proof.lro[1])
+ t = t.write_g1(p: proof.lro[2])
let (_, gamma_raw, mut t) = t.squeeze()
// beta
t = t.write_label(label: BETA_LABEL, label_len: 4)
- t = t.write_u256(val:gamma_raw)
+ t = t.write_u256(val: gamma_raw)
let (_, beta_raw, mut t) = t.squeeze()
// alpha
t = t.write_label(label: ALPHA_LABEL, label_len: 5)
- t = t.write_u256(val:beta_raw)
- t = t.write_g1(p:proof.bsb22_commitments[0])
- t = t.write_g1(p:proof.z)
+ t = t.write_u256(val: beta_raw)
+ t = t.write_g1(p: proof.bsb22_commitments[0])
+ t = t.write_g1(p: proof.z)
let (_, alpha_raw, mut t) = t.squeeze()
// zeta
t = t.write_label(label: ZETA_LABEL, label_len: 4)
- t = t.write_u256(val:alpha_raw)
- t = t.write_g1(p:proof.h[0])
- t = t.write_g1(p:proof.h[1])
- t = t.write_g1(p:proof.h[2])
+ t = t.write_u256(val: alpha_raw)
+ t = t.write_g1(p: proof.h[0])
+ t = t.write_g1(p: proof.h[1])
+ t = t.write_g1(p: proof.h[2])
let (_, zeta_raw, t) = t.squeeze()
(gamma_raw, beta_raw, alpha_raw, zeta_raw)
}
/// Debug: return (pi_total, const_lin) for verification debugging.
-pub fn debug_pi(
- vk: own PlonkVK, proof: own PlonkProof,
- pub_inputs: [u256; 5],
-) -> (u256, u256) uses (evm: mut Evm) {
+pub fn debug_pi(vk: own PlonkVK, proof: own PlonkProof, pub_inputs: [u256; 5]) -> (u256, u256)
+uses (evm: mut Evm)
+{
let one: u256 = 1
// Reuse the challenge derivation from verify
let mut t = Transcript::new()
t = t.write_label(label: GAMMA_LABEL, label_len: 5)
- t = t.write_g1(p:vk.s[0])
- t = t.write_g1(p:vk.s[1])
- t = t.write_g1(p:vk.s[2])
- t = t.write_g1(p:vk.ql)
- t = t.write_g1(p:vk.qr)
- t = t.write_g1(p:vk.qm)
- t = t.write_g1(p:vk.qo)
- t = t.write_g1(p:vk.qk)
- t = t.write_g1(p:vk.qcp[0])
+ t = t.write_g1(p: vk.s[0])
+ t = t.write_g1(p: vk.s[1])
+ t = t.write_g1(p: vk.s[2])
+ t = t.write_g1(p: vk.ql)
+ t = t.write_g1(p: vk.qr)
+ t = t.write_g1(p: vk.qm)
+ t = t.write_g1(p: vk.qo)
+ t = t.write_g1(p: vk.qk)
+ t = t.write_g1(p: vk.qcp[0])
let mut pi_idx: usize = 0
while pi_idx < 5 {
- t = t.write_u256(val:pub_inputs[pi_idx])
+ t = t.write_u256(val: pub_inputs[pi_idx])
pi_idx = pi_idx + 1
}
- t = t.write_g1(p:proof.lro[0])
- t = t.write_g1(p:proof.lro[1])
- t = t.write_g1(p:proof.lro[2])
+ t = t.write_g1(p: proof.lro[0])
+ t = t.write_g1(p: proof.lro[1])
+ t = t.write_g1(p: proof.lro[2])
let (gamma, gamma_raw, mut t) = t.squeeze()
t = t.write_label(label: BETA_LABEL, label_len: 4)
- t = t.write_u256(val:gamma_raw)
+ t = t.write_u256(val: gamma_raw)
let (beta, beta_raw, mut t) = t.squeeze()
t = t.write_label(label: ALPHA_LABEL, label_len: 5)
- t = t.write_u256(val:beta_raw)
- t = t.write_g1(p:proof.bsb22_commitments[0])
- t = t.write_g1(p:proof.z)
+ t = t.write_u256(val: beta_raw)
+ t = t.write_g1(p: proof.bsb22_commitments[0])
+ t = t.write_g1(p: proof.z)
let (alpha, alpha_raw, mut t) = t.squeeze()
t = t.write_label(label: ZETA_LABEL, label_len: 4)
- t = t.write_u256(val:alpha_raw)
- t = t.write_g1(p:proof.h[0])
- t = t.write_g1(p:proof.h[1])
- t = t.write_g1(p:proof.h[2])
+ t = t.write_u256(val: alpha_raw)
+ t = t.write_g1(p: proof.h[0])
+ t = t.write_g1(p: proof.h[1])
+ t = t.write_g1(p: proof.h[2])
let (zeta, zeta_raw, _) = t.squeeze()
// Compute PI
@@ -248,7 +274,10 @@ pub fn debug_pi(
while i < 5 {
let den = field::sub(zeta, omega_i)
let den_inv = field::inv(den)
- let li = field::mul(field::mul(field::mul(zh_zeta, omega_i), den_inv), vk.n_inv)
+ let li = field::mul(
+ field::mul(field::mul(zh_zeta, omega_i), den_inv),
+ vk.n_inv,
+ )
pi = field::add(pi, field::mul(li, pub_inputs[i]))
omega_i = field::mul(omega_i, vk.omega)
i = i + 1
@@ -261,7 +290,7 @@ pub fn debug_pi(
let bsb_den_inv = field::inv(bsb_den)
let bsb_lagrange = field::mul(
field::mul(field::mul(zh_zeta, omega_i), bsb_den_inv),
- vk.n_inv
+ vk.n_inv,
)
pi = field::add(pi, field::mul(h_fr, bsb_lagrange))
@@ -271,10 +300,9 @@ pub fn debug_pi(
/// Verify a Plonk proof with 2 public inputs (SP1 standard).
/// Follows SP1 verify_plonk_algebraic() from verify.rs.
-pub fn verify(
- vk: own PlonkVK, proof: own PlonkProof,
- pub_inputs: [u256; 5],
-) -> bool uses (evm: mut Evm) {
+pub fn verify(vk: own PlonkVK, proof: own PlonkProof, pub_inputs: [u256; 5]) -> bool
+uses (evm: mut Evm)
+{
let one: u256 = 1
// --- 1. Fiat-Shamir challenge derivation ---
@@ -286,44 +314,44 @@ pub fn verify(
// gamma: bind VK public data + public inputs, then commit wire polys
// Hash("gamma" || s1 || s2 || s3 || ql || qr || qm || qo || qk || qcp[0] || pub_inputs || [L] || [R] || [O])
t = t.write_label(label: GAMMA_LABEL, label_len: 5) // "gamma"
- t = t.write_g1(p:vk.s[0])
- t = t.write_g1(p:vk.s[1])
- t = t.write_g1(p:vk.s[2])
- t = t.write_g1(p:vk.ql)
- t = t.write_g1(p:vk.qr)
- t = t.write_g1(p:vk.qm)
- t = t.write_g1(p:vk.qo)
- t = t.write_g1(p:vk.qk)
- t = t.write_g1(p:vk.qcp[0])
+ t = t.write_g1(p: vk.s[0])
+ t = t.write_g1(p: vk.s[1])
+ t = t.write_g1(p: vk.s[2])
+ t = t.write_g1(p: vk.ql)
+ t = t.write_g1(p: vk.qr)
+ t = t.write_g1(p: vk.qm)
+ t = t.write_g1(p: vk.qo)
+ t = t.write_g1(p: vk.qk)
+ t = t.write_g1(p: vk.qcp[0])
let mut pi_idx: usize = 0
while pi_idx < 5 {
- t = t.write_u256(val:pub_inputs[pi_idx])
+ t = t.write_u256(val: pub_inputs[pi_idx])
pi_idx = pi_idx + 1
}
- t = t.write_g1(p:proof.lro[0])
- t = t.write_g1(p:proof.lro[1])
- t = t.write_g1(p:proof.lro[2])
+ t = t.write_g1(p: proof.lro[0])
+ t = t.write_g1(p: proof.lro[1])
+ t = t.write_g1(p: proof.lro[2])
let (gamma, gamma_raw, mut t) = t.squeeze()
// beta: SHA256("beta" || gamma_raw_hash)
// Note: gnark chains the RAW 32-byte hash, not the reduced field element
t = t.write_label(label: BETA_LABEL, label_len: 4) // "beta"
- t = t.write_u256(val:gamma_raw)
+ t = t.write_u256(val: gamma_raw)
let (beta, beta_raw, mut t) = t.squeeze()
// alpha: SHA256("alpha" || beta_raw_hash || bsb22_commitments || Z)
t = t.write_label(label: ALPHA_LABEL, label_len: 5) // "alpha"
- t = t.write_u256(val:beta_raw)
- t = t.write_g1(p:proof.bsb22_commitments[0])
- t = t.write_g1(p:proof.z)
+ t = t.write_u256(val: beta_raw)
+ t = t.write_g1(p: proof.bsb22_commitments[0])
+ t = t.write_g1(p: proof.z)
let (alpha, alpha_raw, mut t) = t.squeeze()
// zeta: SHA256("zeta" || alpha_raw_hash || H0 || H1 || H2)
t = t.write_label(label: ZETA_LABEL, label_len: 4) // "zeta"
- t = t.write_u256(val:alpha_raw)
- t = t.write_g1(p:proof.h[0])
- t = t.write_g1(p:proof.h[1])
- t = t.write_g1(p:proof.h[2])
+ t = t.write_u256(val: alpha_raw)
+ t = t.write_g1(p: proof.h[0])
+ t = t.write_g1(p: proof.h[1])
+ t = t.write_g1(p: proof.h[2])
let (zeta, zeta_raw, _) = t.squeeze()
// --- 2. Compute zeta^n - 1 and L1(zeta) ---
@@ -333,18 +361,21 @@ pub fn verify(
// L1(zeta) = (zeta^n - 1) / (n * (zeta - 1))
let l1_zeta = field::mul(
field::mul(zh_zeta, field::inv(field::sub(zeta, one))),
- vk.n_inv
+ vk.n_inv,
)
// --- 3. Compute PI(zeta) = sum of L_i(zeta) * pub_inputs[i] ---
// L_i(zeta) = (zh * omega^i) / (n * (zeta - omega^i))
let mut pi: u256 = 0
- let mut omega_i: u256 = 1 // omega^0 = 1
+ let mut omega_i: u256 = 1 // omega^0 = 1
let mut i: usize = 0
while i < 5 {
let den = field::sub(zeta, omega_i)
let den_inv = field::inv(den)
- let li = field::mul(field::mul(field::mul(zh_zeta, omega_i), den_inv), vk.n_inv)
+ let li = field::mul(
+ field::mul(field::mul(zh_zeta, omega_i), den_inv),
+ vk.n_inv,
+ )
pi = field::add(pi, field::mul(li, pub_inputs[i]))
omega_i = field::mul(omega_i, vk.omega)
i = i + 1
@@ -360,7 +391,7 @@ pub fn verify(
let bsb_den_inv = field::inv(bsb_den)
let bsb_lagrange = field::mul(
field::mul(field::mul(zh_zeta, omega_i), bsb_den_inv),
- vk.n_inv
+ vk.n_inv,
)
pi = field::add(pi, field::mul(h_fr, bsb_lagrange))
@@ -380,15 +411,24 @@ pub fn verify(
let term_a = field::add(l, field::add(field::mul(beta, s1), gamma))
let term_b = field::add(r, field::add(field::mul(beta, s2), gamma))
let term_c = field::add(o, gamma)
- let perm_term = field::mul(field::mul(field::mul(term_a, term_b), term_c), field::mul(alpha, zu))
+ let perm_term = field::mul(
+ field::mul(field::mul(term_a, term_b), term_c),
+ field::mul(alpha, zu),
+ )
let const_lin = field::neg(
- field::add(field::sub(pi, alpha_sq_l1), perm_term)
+ field::add(field::sub(pi, alpha_sq_l1), perm_term),
)
// --- 6. Linearized polynomial coefficients ---
// _s1 = alpha * (l + beta*s1 + gamma) * (r + beta*s2 + gamma) * beta * zu
- let coeff_s1 = field::mul(field::mul(field::mul(term_a, term_b), field::mul(beta, alpha)), zu)
+ let coeff_s1 = field::mul(
+ field::mul(
+ field::mul(term_a, term_b),
+ field::mul(beta, alpha),
+ ),
+ zu,
+ )
// _s2 = -alpha * (l + beta*zeta + gamma) * (r + beta*u*zeta + gamma) * (o + beta*u^2*zeta + gamma)
let u_zeta = field::mul(vk.coset_shift, zeta)
@@ -396,7 +436,9 @@ pub fn verify(
let s2_a = field::add(l, field::add(field::mul(beta, zeta), gamma))
let s2_b = field::add(r, field::add(field::mul(beta, u_zeta), gamma))
let s2_c = field::add(o, field::add(field::mul(beta, u2_zeta), gamma))
- let coeff_s2 = field::neg(field::mul(field::mul(field::mul(s2_a, s2_b), s2_c), alpha))
+ let coeff_s2 = field::neg(
+ field::mul(field::mul(field::mul(s2_a, s2_b), s2_c), alpha),
+ )
// coeff_z = alpha^2*L1(zeta) + coeff_s2
let coeff_z = field::add(alpha_sq_l1, coeff_s2)
@@ -419,15 +461,29 @@ pub fn verify(
let points: [G1Point; 11] = [
proof.bsb22_commitments[0],
- vk.ql, vk.qr, vk.qm, vk.qo, vk.qk,
- vk.s[2], proof.z,
- proof.h[0], proof.h[1], proof.h[2],
+ vk.ql,
+ vk.qr,
+ vk.qm,
+ vk.qo,
+ vk.qk,
+ vk.s[2],
+ proof.z,
+ proof.h[0],
+ proof.h[1],
+ proof.h[2],
]
let scalars: [u256; 11] = [
qc_val,
- l, r, rl, o, one,
- coeff_s1, coeff_z,
- coeff_h0, coeff_h1, coeff_h2,
+ l,
+ r,
+ rl,
+ o,
+ one,
+ coeff_s1,
+ coeff_z,
+ coeff_h0,
+ coeff_h1,
+ coeff_h2,
]
let linearized = msm::msm<11>(points, scalars)
@@ -438,26 +494,30 @@ pub fn verify(
// Derive gamma_kzg for folding
let mut t2 = Transcript::new()
- t2 = t2.write_label(label: 0x67616d6d61000000000000000000000000000000000000000000000000000000, label_len: 5) // "gamma"
- t2 = t2.write_u256(val:zeta)
+ t2 = t2
+ .write_label(
+ label: 0x67616d6d61000000000000000000000000000000000000000000000000000000,
+ label_len: 5,
+ ) // "gamma"
+ t2 = t2.write_u256(val: zeta)
// Write all 7 digests
- t2 = t2.write_g1(p:linearized)
- t2 = t2.write_g1(p:proof.lro[0])
- t2 = t2.write_g1(p:proof.lro[1])
- t2 = t2.write_g1(p:proof.lro[2])
- t2 = t2.write_g1(p:vk.s[0])
- t2 = t2.write_g1(p:vk.s[1])
- t2 = t2.write_g1(p:vk.qcp[0])
+ t2 = t2.write_g1(p: linearized)
+ t2 = t2.write_g1(p: proof.lro[0])
+ t2 = t2.write_g1(p: proof.lro[1])
+ t2 = t2.write_g1(p: proof.lro[2])
+ t2 = t2.write_g1(p: vk.s[0])
+ t2 = t2.write_g1(p: vk.s[1])
+ t2 = t2.write_g1(p: vk.qcp[0])
// Write all 7 claimed values
- t2 = t2.write_u256(val:const_lin)
- t2 = t2.write_u256(val:l)
- t2 = t2.write_u256(val:r)
- t2 = t2.write_u256(val:o)
- t2 = t2.write_u256(val:s1)
- t2 = t2.write_u256(val:s2)
- t2 = t2.write_u256(val:qc_val)
+ t2 = t2.write_u256(val: const_lin)
+ t2 = t2.write_u256(val: l)
+ t2 = t2.write_u256(val: r)
+ t2 = t2.write_u256(val: o)
+ t2 = t2.write_u256(val: s1)
+ t2 = t2.write_u256(val: s2)
+ t2 = t2.write_u256(val: qc_val)
// Write zu (data transcript)
- t2 = t2.write_u256(val:zu)
+ t2 = t2.write_u256(val: zu)
let (gamma_kzg, _, _) = t2.squeeze()
// gamma_kzg raw hash not needed (separate transcript)
@@ -473,8 +533,11 @@ pub fn verify(
// Folded digest = MSM(digests, gamma_kzg^i)
let fold_points: [G1Point; 7] = [
linearized,
- proof.lro[0], proof.lro[1], proof.lro[2],
- vk.s[0], vk.s[1],
+ proof.lro[0],
+ proof.lro[1],
+ proof.lro[2],
+ vk.s[0],
+ vk.s[1],
vk.qcp[0],
]
let fold_scalars: [u256; 7] = [g0, g1, g2, g3, g4, g5, g6]
@@ -496,15 +559,21 @@ pub fn verify(
// then derive_randomness(fs, "u", [folded_digest, Z, batched_h, z_shifted_h])
// computes SHA256("u" || zeta_raw_hash || gamma_kzg || folded_digest || Z || batched_h || z_shifted_h)
let mut t3 = Transcript::new()
- t3 = t3.write_label(label: 0x7500000000000000000000000000000000000000000000000000000000000000, label_len: 1) // "u"
- t3 = t3.write_u256(val:zeta_raw) // chain from previous challenge (zeta's raw hash)
+ t3 = t3
+ .write_label(
+ label: 0x7500000000000000000000000000000000000000000000000000000000000000,
+ label_len: 1,
+ ) // "u"
+ t3 = t3.write_u256(
+ val: zeta_raw,
+ ) // chain from previous challenge (zeta's raw hash)
// gamma_kzg bound to "u" challenge by fold_proof
- t3 = t3.write_u256(val:gamma_kzg)
+ t3 = t3.write_u256(val: gamma_kzg)
// derive_randomness binds these points
- t3 = t3.write_g1(p:folded_digest)
- t3 = t3.write_g1(p:proof.z)
- t3 = t3.write_g1(p:proof.batched_h)
- t3 = t3.write_g1(p:proof.z_shifted_h)
+ t3 = t3.write_g1(p: folded_digest)
+ t3 = t3.write_g1(p: proof.z)
+ t3 = t3.write_g1(p: proof.batched_h)
+ t3 = t3.write_g1(p: proof.z_shifted_h)
let (u_challenge, _, _) = t3.squeeze()
// --- 10. KZG batch verification ---
@@ -513,30 +582,44 @@ pub fn verify(
let shifted_zeta = field::mul(zeta, vk.omega)
// folded_quotients = batched_h + u * z_shifted_h
- let folded_quotients = g1_add(a: proof.batched_h, b: g1_mul(p: proof.z_shifted_h, s: u_challenge))
+ let folded_quotients = g1_add(
+ a: proof.batched_h,
+ b: g1_mul(p: proof.z_shifted_h, s: u_challenge),
+ )
// folded_digests = folded_digest + u * proof.z
// - folded_eval_commit
// + zeta * batched_h + u * shifted_zeta * z_shifted_h
- let folded_evals_commit = g1_mul(p: vk.g1_srs, s: field::add(folded_eval, field::mul(u_challenge, zu)))
+ let folded_evals_commit = g1_mul(
+ p: vk.g1_srs,
+ s: field::add(folded_eval, field::mul(u_challenge, zu)),
+ )
let point_term = g1_add(
a: g1_mul(p: proof.batched_h, s: zeta),
- b: g1_mul(p: proof.z_shifted_h, s: field::mul(u_challenge, shifted_zeta))
+ b: g1_mul(
+ p: proof.z_shifted_h,
+ s: field::mul(u_challenge, shifted_zeta),
+ ),
)
let lhs = g1_add(
a: g1_add(
a: g1_add(a: folded_digest, b: g1_mul(p: proof.z, s: u_challenge)),
- b: negate(p: folded_evals_commit)
+ b: negate(p: folded_evals_commit),
),
- b: point_term
+ b: point_term,
)
let neg_quotients = negate(p: folded_quotients)
// Pairing check: e(lhs, G2) * e(-folded_quotients, [alpha]G2) == 1
- pairing_2(a1: lhs, b1: vk.g2_srs[0], a2: neg_quotients, b2: vk.g2_srs[1])
+ pairing_2(
+ a1: lhs,
+ b1: vk.g2_srs[0],
+ a2: neg_quotients,
+ b2: vk.g2_srs[1],
+ )
}
// -----------------------------------------------------------------------
@@ -551,7 +634,9 @@ fn test_hash_fr() uses (evm: mut Evm) {
let x: u256 = 0x27086e886de4f31d65e997d9dd08e35dd6590101d9185db7c8c5dd7dd9348c9c
let y: u256 = 0x1b711862d9757e744014177960751f5f5a84f14bbc1b019021db0666b8e55fc3
let result = hash_fr(x, y)
- assert(result == 0x11fde042bd38090174940ef4ce967657b9b334a8f80c25694311c8846320a582)
+ assert!(
+ result == 0x11fde042bd38090174940ef4ce967657b9b334a8f80c25694311c8846320a582,
+ )
}
#[test]
@@ -560,7 +645,7 @@ fn test_field_inv() {
let two: u256 = 2
let inv2 = field::inv(two)
let product = field::mul(two, inv2)
- assert(product == 1)
+ assert!(product == 1)
}
#[test]
@@ -569,7 +654,7 @@ fn test_pow_mod() {
let omega: u256 = 5709868443893258075976348696661355716898495876243883251619397131511003808859
let n: u256 = 16777216
let result = pow_mod(omega, n)
- assert(result == 1)
+ assert!(result == 1)
}
#[test]
@@ -581,7 +666,9 @@ fn test_transcript_gamma() uses (evm: mut Evm) {
// Just hash "gamma" alone to verify the label encoding
let (_, gamma_only_raw, t) = t.squeeze()
// SHA256("gamma") = 0xbe9d587defa1f0c09ef49eb17e206983a5f8f8289e4281860bd0ee5a19592c67
- assert(gamma_only_raw == 0xbe9d587defa1f0c09ef49eb17e206983a5f8f8289e4281860bd0ee5a19592c67)
+ assert!(
+ gamma_only_raw == 0xbe9d587defa1f0c09ef49eb17e206983a5f8f8289e4281860bd0ee5a19592c67,
+ )
}
#[test]
@@ -589,8 +676,8 @@ fn test_batch_invert() {
let a: u256 = 7
let b: u256 = 13
let (a_inv, b_inv) = batch_invert_2(a, b)
- assert(field::mul(a, a_inv) == 1)
- assert(field::mul(b, b_inv) == 1)
+ assert!(field::mul(a, a_inv) == 1)
+ assert!(field::mul(b, b_inv) == 1)
}
#[test]
@@ -616,7 +703,7 @@ fn test_const_lin() {
let zh_zeta = field::sub(zeta_power_n, one)
let l1_zeta = field::mul(
field::mul(zh_zeta, field::inv(field::sub(zeta, one))),
- n_inv
+ n_inv,
)
let alpha_sq_l1 = field::mul(field::mul(alpha, alpha), l1_zeta)
@@ -624,12 +711,17 @@ fn test_const_lin() {
let term_a = field::add(l, field::add(field::mul(beta, s1), gamma))
let term_b = field::add(r, field::add(field::mul(beta, s2), gamma))
let term_c = field::add(o, gamma)
- let perm_term = field::mul(field::mul(field::mul(term_a, term_b), term_c), field::mul(alpha, zu))
+ let perm_term = field::mul(
+ field::mul(field::mul(term_a, term_b), term_c),
+ field::mul(alpha, zu),
+ )
let inner = field::add(field::sub(pi, alpha_sq_l1), perm_term)
let const_lin = field::neg(inner)
- assert(const_lin == 0x22eb75080a77724bc8dc8c0548f18bef1975fa6c302909af13c960db6c585954)
+ assert!(
+ const_lin == 0x22eb75080a77724bc8dc8c0548f18bef1975fa6c302909af13c960db6c585954,
+ )
}
#[test]
@@ -651,14 +743,25 @@ fn test_linearization_coefficients() {
let zeta_power_n = pow_mod(zeta, n)
let zh_zeta = field::sub(zeta_power_n, one)
- let l1_zeta = field::mul(field::mul(zh_zeta, field::inv(field::sub(zeta, one))), n_inv)
+ let l1_zeta = field::mul(
+ field::mul(zh_zeta, field::inv(field::sub(zeta, one))),
+ n_inv,
+ )
let alpha_sq_l1 = field::mul(field::mul(alpha, alpha), l1_zeta)
// coeff_s1
let term_a = field::add(l, field::add(field::mul(beta, s1), gamma))
let term_b = field::add(r, field::add(field::mul(beta, s2), gamma))
- let coeff_s1 = field::mul(field::mul(field::mul(term_a, term_b), field::mul(beta, alpha)), zu)
- assert(coeff_s1 == 0x014e31ed4d81ae6dd405e472b9107d89e37137cb2f7e0fc5d32ac04e149f3989)
+ let coeff_s1 = field::mul(
+ field::mul(
+ field::mul(term_a, term_b),
+ field::mul(beta, alpha),
+ ),
+ zu,
+ )
+ assert!(
+ coeff_s1 == 0x014e31ed4d81ae6dd405e472b9107d89e37137cb2f7e0fc5d32ac04e149f3989,
+ )
// coeff_s2 / coeff_z
let u_zeta = field::mul(coset_shift, zeta)
@@ -666,9 +769,13 @@ fn test_linearization_coefficients() {
let s2_a = field::add(l, field::add(field::mul(beta, zeta), gamma))
let s2_b = field::add(r, field::add(field::mul(beta, u_zeta), gamma))
let s2_c = field::add(o, field::add(field::mul(beta, u2_zeta), gamma))
- let coeff_s2 = field::neg(field::mul(field::mul(field::mul(s2_a, s2_b), s2_c), alpha))
+ let coeff_s2 = field::neg(
+ field::mul(field::mul(field::mul(s2_a, s2_b), s2_c), alpha),
+ )
let coeff_z = field::add(alpha_sq_l1, coeff_s2)
- assert(coeff_z == 0x0d51bf1d4a66e52d8bb72ec963f83620301a16c69392558e1953b15c3fa555c4)
+ assert!(
+ coeff_z == 0x0d51bf1d4a66e52d8bb72ec963f83620301a16c69392558e1953b15c3fa555c4,
+ )
// Quotient coefficients
let n_plus_two = n + 2
@@ -677,9 +784,15 @@ fn test_linearization_coefficients() {
let coeff_h0 = field::neg(zh_zeta)
let coeff_h1 = field::neg(field::mul(zeta_np2, zh_zeta))
let coeff_h2 = field::neg(field::mul(zeta_np2_sq, zh_zeta))
- assert(coeff_h0 == 0x2708f62ad73df8922601f3c8a66ee33858d4488264f5ada9885746cd1d181879)
- assert(coeff_h1 == 0x11a7fff44d705a9129a01901a0183754b4e256d6d5f790c3b12a04daad6d7260)
- assert(coeff_h2 == 0x0cd41c8f7b46057ad0ca5113f129ccb033f0db5f2bdd4b4742baf44cffd6f9cd)
+ assert!(
+ coeff_h0 == 0x2708f62ad73df8922601f3c8a66ee33858d4488264f5ada9885746cd1d181879,
+ )
+ assert!(
+ coeff_h1 == 0x11a7fff44d705a9129a01901a0183754b4e256d6d5f790c3b12a04daad6d7260,
+ )
+ assert!(
+ coeff_h2 == 0x0cd41c8f7b46057ad0ca5113f129ccb033f0db5f2bdd4b4742baf44cffd6f9cd,
+ )
}
#[test]
@@ -691,42 +804,111 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
omega: 5709868443893258075976348696661355716898495876243883251619397131511003808859,
nb_public_inputs: 2,
coset_shift: 5,
- ql: G1Point { x: 2714773032566361735398260413518107570706289019141573602093747023461681138141, y: 10207220609888567477852282724812707756861966294950666667119692155077205992894 },
- qr: G1Point { x: 17919274808167168584263187859012763816365260341587621260815379357637476029962, y: 14558165337321799812085033100515533981610351056305142204990949940017867076397 },
- qm: G1Point { x: 1814703450159964740292891910795980721108620081843240976053374083376051887455, y: 11252528960397523304289223453506717847025678682133692300385063157160041127070 },
- qo: G1Point { x: 20843277058771674275997213106654908867381045039357421108797602213552545033079, y: 9646775541123942436366130063934415659078920798926708026864638413383214238671 },
- qk: G1Point { x: 5484717465597821820411103650564499774744032473047103693751158150047197753654, y: 5561799343038529497262757012400750786503050088440144551259537360162821571059 },
+ ql: G1Point {
+ x: 2714773032566361735398260413518107570706289019141573602093747023461681138141,
+ y: 10207220609888567477852282724812707756861966294950666667119692155077205992894,
+ },
+ qr: G1Point {
+ x: 17919274808167168584263187859012763816365260341587621260815379357637476029962,
+ y: 14558165337321799812085033100515533981610351056305142204990949940017867076397,
+ },
+ qm: G1Point {
+ x: 1814703450159964740292891910795980721108620081843240976053374083376051887455,
+ y: 11252528960397523304289223453506717847025678682133692300385063157160041127070,
+ },
+ qo: G1Point {
+ x: 20843277058771674275997213106654908867381045039357421108797602213552545033079,
+ y: 9646775541123942436366130063934415659078920798926708026864638413383214238671,
+ },
+ qk: G1Point {
+ x: 5484717465597821820411103650564499774744032473047103693751158150047197753654,
+ y: 5561799343038529497262757012400750786503050088440144551259537360162821571059,
+ },
s: [
- G1Point { x: 16111562061301112215931665617877464360548491176332584512747295033804502769274, y: 15035232142063390140879951391784254536324051421746307325879221184372296043705 },
- G1Point { x: 899944321381010541211546037826620464002745326050515852312919625047231523882, y: 61717668739330555376092528203839789132705738484346798874082062974863965392 },
- G1Point { x: 9316901462569250008665217603385561854185385862824092362271612343176126127375, y: 13799900238612879579721466063922041459340434537392216736920805107993374657577 },
+ G1Point {
+ x: 16111562061301112215931665617877464360548491176332584512747295033804502769274,
+ y: 15035232142063390140879951391784254536324051421746307325879221184372296043705,
+ },
+ G1Point {
+ x: 899944321381010541211546037826620464002745326050515852312919625047231523882,
+ y: 61717668739330555376092528203839789132705738484346798874082062974863965392,
+ },
+ G1Point {
+ x: 9316901462569250008665217603385561854185385862824092362271612343176126127375,
+ y: 13799900238612879579721466063922041459340434537392216736920805107993374657577,
+ },
+ ],
+ qcp: [
+ G1Point {
+ x: 21578473557091588309361521643625606794648013014197133181947992670819103775934,
+ y: 18236588362476326695195531997097392315059481348147701548685746610417604595065,
+ },
],
- qcp: [G1Point { x: 21578473557091588309361521643625606794648013014197133181947992670819103775934, y: 18236588362476326695195531997097392315059481348147701548685746610417604595065 }],
commit_constraint_idx: [10900304],
g2_srs: [
- G2Point { x_imag: 11559732032986387107991004021392285783925812861821192530917403151452391805634, x_real: 10857046999023057135944570762232829481370756359578518086990519993285655852781, y_imag: 4082367875863433681332203403145435568316851327593401208105741076214120093531, y_real: 8495653923123431417604973247489272438418190587263600148770280649306958101930 },
- G2Point { x_imag: 15805639136721018565402881920352193254830339253282065586954346329754995870280, x_real: 19089565590083334368588890253123139704298730990782503769911324779715431555531, y_imag: 9779648407879205346559610309258181044130619080926897934572699915909528404984, y_real: 6779728121489434657638426458390319301070371227460768374343986326751507916979 },
+ G2Point {
+ x_imag: 11559732032986387107991004021392285783925812861821192530917403151452391805634,
+ x_real: 10857046999023057135944570762232829481370756359578518086990519993285655852781,
+ y_imag: 4082367875863433681332203403145435568316851327593401208105741076214120093531,
+ y_real: 8495653923123431417604973247489272438418190587263600148770280649306958101930,
+ },
+ G2Point {
+ x_imag: 15805639136721018565402881920352193254830339253282065586954346329754995870280,
+ x_real: 19089565590083334368588890253123139704298730990782503769911324779715431555531,
+ y_imag: 9779648407879205346559610309258181044130619080926897934572699915909528404984,
+ y_real: 6779728121489434657638426458390319301070371227460768374343986326751507916979,
+ },
],
- g1_srs: G1Point { x: 14312776538779914388377568895031746459131577658076416373430523308756343304251, y: 11763105256161367503191792604679297387056316997144156930871823008787082098465 },
+ g1_srs: G1Point {
+ x: 14312776538779914388377568895031746459131577658076416373430523308756343304251,
+ y: 11763105256161367503191792604679297387056316997144156930871823008787082098465,
+ },
}
// Construct the proof from known test vector bytes
let proof = PlonkProof {
lro: [
- G1Point { x: 0x2dac3ba24f360a6deda246f6d3e9d8080ed09f97126ef9af18c5de05ca340416, y: 0x054a4430da47cc1a780b8c91f2c4a3347b1523d220bee21f7b10016e0df7e708 },
- G1Point { x: 0x235ff58eb8e9feb8cf75355f3daec83dd4dde0ebe08ca90ea98510aba1585f4f, y: 0x0d1716e7f3a01ac0ac6f3a1f6130256444c0b25a114f9300abaeb0d0838d29b2 },
- G1Point { x: 0x2c1dbdf8e4d0f950e7d062751c52a03ad451685e0d23b45563aa87a7d74ec1cf, y: 0x2cff1161e6d5c9272c3892a76adeb9a5aada5d7065c8e41121ebf4bd9d0fb2cc },
+ G1Point {
+ x: 0x2dac3ba24f360a6deda246f6d3e9d8080ed09f97126ef9af18c5de05ca340416,
+ y: 0x054a4430da47cc1a780b8c91f2c4a3347b1523d220bee21f7b10016e0df7e708,
+ },
+ G1Point {
+ x: 0x235ff58eb8e9feb8cf75355f3daec83dd4dde0ebe08ca90ea98510aba1585f4f,
+ y: 0x0d1716e7f3a01ac0ac6f3a1f6130256444c0b25a114f9300abaeb0d0838d29b2,
+ },
+ G1Point {
+ x: 0x2c1dbdf8e4d0f950e7d062751c52a03ad451685e0d23b45563aa87a7d74ec1cf,
+ y: 0x2cff1161e6d5c9272c3892a76adeb9a5aada5d7065c8e41121ebf4bd9d0fb2cc,
+ },
],
- z: G1Point { x: 0x1657a289347c1973783849c4545c7ed8f0ea65f1eb40b31678d627e70b79bfd1, y: 0x1592517f8902c7364f90126fe04c28381fe12e165adcf82217876359a544e218 },
+ z: G1Point {
+ x: 0x1657a289347c1973783849c4545c7ed8f0ea65f1eb40b31678d627e70b79bfd1,
+ y: 0x1592517f8902c7364f90126fe04c28381fe12e165adcf82217876359a544e218,
+ },
h: [
- G1Point { x: 0x1aed4c55f27c9cb2021ddae086085388d250dc257cc61ece968e674b25ed18a3, y: 0x2e9fbdee2b76ceb2c26d73c760252070fab8d5c04dd4f5616ca352666bb18782 },
- G1Point { x: 0x0bb1920bd0959e61569ec796bd832e78f92e20320fc9cc9ae6ae8470dab64371, y: 0x09fdd853d0db78b9ce5811df7c7bf6a7c0486cf433219034e1c43206b64a404a },
- G1Point { x: 0x19280febb426e548e99e6279adceffaa4ddae622ec50624afb4ea827467adc41, y: 0x099d164e7abfdc97d9b168461c2626e88239d30529974cb1b582d7362ed6d6d5 },
+ G1Point {
+ x: 0x1aed4c55f27c9cb2021ddae086085388d250dc257cc61ece968e674b25ed18a3,
+ y: 0x2e9fbdee2b76ceb2c26d73c760252070fab8d5c04dd4f5616ca352666bb18782,
+ },
+ G1Point {
+ x: 0x0bb1920bd0959e61569ec796bd832e78f92e20320fc9cc9ae6ae8470dab64371,
+ y: 0x09fdd853d0db78b9ce5811df7c7bf6a7c0486cf433219034e1c43206b64a404a,
+ },
+ G1Point {
+ x: 0x19280febb426e548e99e6279adceffaa4ddae622ec50624afb4ea827467adc41,
+ y: 0x099d164e7abfdc97d9b168461c2626e88239d30529974cb1b582d7362ed6d6d5,
+ },
],
bsb22_commitments: [
- G1Point { x: 0x27086e886de4f31d65e997d9dd08e35dd6590101d9185db7c8c5dd7dd9348c9c, y: 0x1b711862d9757e744014177960751f5f5a84f14bbc1b019021db0666b8e55fc3 },
+ G1Point {
+ x: 0x27086e886de4f31d65e997d9dd08e35dd6590101d9185db7c8c5dd7dd9348c9c,
+ y: 0x1b711862d9757e744014177960751f5f5a84f14bbc1b019021db0666b8e55fc3,
+ },
],
- batched_h: G1Point { x: 0x24577aded4d6983f59f123e52821f39141c397fcc957b4f7a2a4ede57b55ef10, y: 0x05e37b2c4f98ccba063aef65967db4e19547a1e18bea96ab8ec861b7a3e085db },
+ batched_h: G1Point {
+ x: 0x24577aded4d6983f59f123e52821f39141c397fcc957b4f7a2a4ede57b55ef10,
+ y: 0x05e37b2c4f98ccba063aef65967db4e19547a1e18bea96ab8ec861b7a3e085db,
+ },
claimed_values: [
0x2a2af70b568d007ce53077a078437c2acf6cad206354b0ffa823b4de87918a05,
0x03a674ce289759e10b9da150b523d55886b63dc8526f0e36132edb5239c0c238,
@@ -735,7 +917,10 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
0x0dad3ef6870691a71276c4f6f185fb14cfe8c7a418c26b3620ce09eff0d21a42,
0x28ecd97e273c00ce59504ccc15bfe8a2d8f87d1bbd7dc63df606b3c975080a6f,
],
- z_shifted_h: G1Point { x: 0x2a5ab0dadfc301d004d4863346963baebbd7ea536022a8b90cd9b52d865d5c9c, y: 0x1e6437eaa886f121c46132f1bcd890827f7860cc63e5b27d8319f9b0cab8d27e },
+ z_shifted_h: G1Point {
+ x: 0x2a5ab0dadfc301d004d4863346963baebbd7ea536022a8b90cd9b52d865d5c9c,
+ y: 0x1e6437eaa886f121c46132f1bcd890827f7860cc63e5b27d8319f9b0cab8d27e,
+ },
z_shifted_value: 0x2c1660be901029bf87b9796eedddc65aef146a4419ae4a123ee18aacfa9c41d1,
}
@@ -760,13 +945,29 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
let points: [G1Point; 11] = [
proof.bsb22_commitments[0],
- vk.ql, vk.qr, vk.qm, vk.qo, vk.qk,
- vk.s[2], proof.z,
- proof.h[0], proof.h[1], proof.h[2],
+ vk.ql,
+ vk.qr,
+ vk.qm,
+ vk.qo,
+ vk.qk,
+ vk.s[2],
+ proof.z,
+ proof.h[0],
+ proof.h[1],
+ proof.h[2],
]
let scalars: [u256; 11] = [
- qc_val, l, r, rl, o, one,
- coeff_s1, coeff_z, coeff_h0, coeff_h1, coeff_h2,
+ qc_val,
+ l,
+ r,
+ rl,
+ o,
+ one,
+ coeff_s1,
+ coeff_z,
+ coeff_h0,
+ coeff_h1,
+ coeff_h2,
]
let linearized = msm::msm<11>(points, scalars)
@@ -780,23 +981,27 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
// gamma_kzg transcript
let mut t2 = Transcript::new()
- t2 = t2.write_label(label: 0x67616d6d61000000000000000000000000000000000000000000000000000000, label_len: 5)
- t2 = t2.write_u256(val:zeta)
- t2 = t2.write_g1(p:linearized)
- t2 = t2.write_g1(p:proof.lro[0])
- t2 = t2.write_g1(p:proof.lro[1])
- t2 = t2.write_g1(p:proof.lro[2])
- t2 = t2.write_g1(p:vk.s[0])
- t2 = t2.write_g1(p:vk.s[1])
- t2 = t2.write_g1(p:vk.qcp[0])
- t2 = t2.write_u256(val:const_lin)
- t2 = t2.write_u256(val:l)
- t2 = t2.write_u256(val:r)
- t2 = t2.write_u256(val:o)
- t2 = t2.write_u256(val:s1)
- t2 = t2.write_u256(val:s2)
- t2 = t2.write_u256(val:qc_val)
- t2 = t2.write_u256(val:zu)
+ t2 = t2
+ .write_label(
+ label: 0x67616d6d61000000000000000000000000000000000000000000000000000000,
+ label_len: 5,
+ )
+ t2 = t2.write_u256(val: zeta)
+ t2 = t2.write_g1(p: linearized)
+ t2 = t2.write_g1(p: proof.lro[0])
+ t2 = t2.write_g1(p: proof.lro[1])
+ t2 = t2.write_g1(p: proof.lro[2])
+ t2 = t2.write_g1(p: vk.s[0])
+ t2 = t2.write_g1(p: vk.s[1])
+ t2 = t2.write_g1(p: vk.qcp[0])
+ t2 = t2.write_u256(val: const_lin)
+ t2 = t2.write_u256(val: l)
+ t2 = t2.write_u256(val: r)
+ t2 = t2.write_u256(val: o)
+ t2 = t2.write_u256(val: s1)
+ t2 = t2.write_u256(val: s2)
+ t2 = t2.write_u256(val: qc_val)
+ t2 = t2.write_u256(val: zu)
let (gamma_kzg, _, _) = t2.squeeze()
// Fold
@@ -810,8 +1015,12 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
let fold_points: [G1Point; 7] = [
linearized,
- proof.lro[0], proof.lro[1], proof.lro[2],
- vk.s[0], vk.s[1], vk.qcp[0],
+ proof.lro[0],
+ proof.lro[1],
+ proof.lro[2],
+ vk.s[0],
+ vk.s[1],
+ vk.qcp[0],
]
let fold_scalars: [u256; 7] = [g0, g1, g2, g3, g4, g5, g6]
let folded_digest = msm::msm<7>(fold_points, fold_scalars)
@@ -828,20 +1037,24 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
folded_eval = field::add(folded_eval, field::mul(claimed[6], g6))
// KZG points — test each individually
- let _t1 = g1_mul(p: proof.batched_h, s: 1) // W_zeta
- let _t2 = g1_mul(p: proof.z_shifted_h, s: 1) // W_zeta_omega
- let _t3 = g1_mul(p: vk.g1_srs, s: 1) // G1 SRS
+ let _t1 = g1_mul(p: proof.batched_h, s: 1) // W_zeta
+ let _t2 = g1_mul(p: proof.z_shifted_h, s: 1) // W_zeta_omega
+ let _t3 = g1_mul(p: vk.g1_srs, s: 1) // G1 SRS
// Derive U challenge
let zeta_raw: u256 = 0xc3b84ae752216a5cae098493e1282230f2d8db540b958f2c6d0067f9ee0fed8a
let mut t3 = Transcript::new()
- t3 = t3.write_label(label: 0x7500000000000000000000000000000000000000000000000000000000000000, label_len: 1)
- t3 = t3.write_u256(val:zeta_raw)
- t3 = t3.write_u256(val:gamma_kzg)
- t3 = t3.write_g1(p:folded_digest)
- t3 = t3.write_g1(p:proof.z)
- t3 = t3.write_g1(p:proof.batched_h)
- t3 = t3.write_g1(p:proof.z_shifted_h)
+ t3 = t3
+ .write_label(
+ label: 0x7500000000000000000000000000000000000000000000000000000000000000,
+ label_len: 1,
+ )
+ t3 = t3.write_u256(val: zeta_raw)
+ t3 = t3.write_u256(val: gamma_kzg)
+ t3 = t3.write_g1(p: folded_digest)
+ t3 = t3.write_g1(p: proof.z)
+ t3 = t3.write_g1(p: proof.batched_h)
+ t3 = t3.write_g1(p: proof.z_shifted_h)
let (u_challenge, _, _) = t3.squeeze()
let omega: u256 = 5709868443893258075976348696661355716898495876243883251619397131511003808859
@@ -851,16 +1064,19 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
use ec::bn254::negate
// Step A
- let u_times_zsh = g1_mul(p: proof.z_shifted_h, s: u_challenge) // checkpoint A1
- let folded_quotients = g1_add(a: proof.batched_h, b: u_times_zsh) // checkpoint A2
+ let u_times_zsh = g1_mul(p: proof.z_shifted_h, s: u_challenge) // checkpoint A1
+ let folded_quotients = g1_add(a: proof.batched_h, b: u_times_zsh) // checkpoint A2
// Step B
let eval_sum = field::add(folded_eval, field::mul(u_challenge, zu))
- let folded_evals_commit = g1_mul(p: vk.g1_srs, s: eval_sum) // checkpoint B
+ let folded_evals_commit = g1_mul(p: vk.g1_srs, s: eval_sum) // checkpoint B
// Step C: point_term = zeta * batched_h + u * shifted_zeta * z_shifted_h
let zeta_times_wz = g1_mul(p: proof.batched_h, s: zeta)
- let us_zeta_times_wzo = g1_mul(p: proof.z_shifted_h, s: field::mul(u_challenge, shifted_zeta))
+ let us_zeta_times_wzo = g1_mul(
+ p: proof.z_shifted_h,
+ s: field::mul(u_challenge, shifted_zeta),
+ )
let point_term = g1_add(a: zeta_times_wz, b: us_zeta_times_wzo)
// Step D: lhs = folded_digest + u*Z - folded_evals_commit + point_term
@@ -876,41 +1092,123 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
n: 16777216,
n_inv: 21888241567198334088790460357988866238279339518792980768180410072331574733841,
omega: 5709868443893258075976348696661355716898495876243883251619397131511003808859,
- nb_public_inputs: 2, coset_shift: 5,
- ql: G1Point { x: 2714773032566361735398260413518107570706289019141573602093747023461681138141, y: 10207220609888567477852282724812707756861966294950666667119692155077205992894 },
- qr: G1Point { x: 17919274808167168584263187859012763816365260341587621260815379357637476029962, y: 14558165337321799812085033100515533981610351056305142204990949940017867076397 },
- qm: G1Point { x: 1814703450159964740292891910795980721108620081843240976053374083376051887455, y: 11252528960397523304289223453506717847025678682133692300385063157160041127070 },
- qo: G1Point { x: 20843277058771674275997213106654908867381045039357421108797602213552545033079, y: 9646775541123942436366130063934415659078920798926708026864638413383214238671 },
- qk: G1Point { x: 5484717465597821820411103650564499774744032473047103693751158150047197753654, y: 5561799343038529497262757012400750786503050088440144551259537360162821571059 },
+ nb_public_inputs: 2,
+ coset_shift: 5,
+ ql: G1Point {
+ x: 2714773032566361735398260413518107570706289019141573602093747023461681138141,
+ y: 10207220609888567477852282724812707756861966294950666667119692155077205992894,
+ },
+ qr: G1Point {
+ x: 17919274808167168584263187859012763816365260341587621260815379357637476029962,
+ y: 14558165337321799812085033100515533981610351056305142204990949940017867076397,
+ },
+ qm: G1Point {
+ x: 1814703450159964740292891910795980721108620081843240976053374083376051887455,
+ y: 11252528960397523304289223453506717847025678682133692300385063157160041127070,
+ },
+ qo: G1Point {
+ x: 20843277058771674275997213106654908867381045039357421108797602213552545033079,
+ y: 9646775541123942436366130063934415659078920798926708026864638413383214238671,
+ },
+ qk: G1Point {
+ x: 5484717465597821820411103650564499774744032473047103693751158150047197753654,
+ y: 5561799343038529497262757012400750786503050088440144551259537360162821571059,
+ },
s: [
- G1Point { x: 16111562061301112215931665617877464360548491176332584512747295033804502769274, y: 15035232142063390140879951391784254536324051421746307325879221184372296043705 },
- G1Point { x: 899944321381010541211546037826620464002745326050515852312919625047231523882, y: 61717668739330555376092528203839789132705738484346798874082062974863965392 },
- G1Point { x: 9316901462569250008665217603385561854185385862824092362271612343176126127375, y: 13799900238612879579721466063922041459340434537392216736920805107993374657577 },
+ G1Point {
+ x: 16111562061301112215931665617877464360548491176332584512747295033804502769274,
+ y: 15035232142063390140879951391784254536324051421746307325879221184372296043705,
+ },
+ G1Point {
+ x: 899944321381010541211546037826620464002745326050515852312919625047231523882,
+ y: 61717668739330555376092528203839789132705738484346798874082062974863965392,
+ },
+ G1Point {
+ x: 9316901462569250008665217603385561854185385862824092362271612343176126127375,
+ y: 13799900238612879579721466063922041459340434537392216736920805107993374657577,
+ },
+ ],
+ qcp: [
+ G1Point {
+ x: 21578473557091588309361521643625606794648013014197133181947992670819103775934,
+ y: 18236588362476326695195531997097392315059481348147701548685746610417604595065,
+ },
],
- qcp: [G1Point { x: 21578473557091588309361521643625606794648013014197133181947992670819103775934, y: 18236588362476326695195531997097392315059481348147701548685746610417604595065 }],
commit_constraint_idx: [10900304],
g2_srs: [
- G2Point { x_imag: 11559732032986387107991004021392285783925812861821192530917403151452391805634, x_real: 10857046999023057135944570762232829481370756359578518086990519993285655852781, y_imag: 4082367875863433681332203403145435568316851327593401208105741076214120093531, y_real: 8495653923123431417604973247489272438418190587263600148770280649306958101930 },
- G2Point { x_imag: 15805639136721018565402881920352193254830339253282065586954346329754995870280, x_real: 19089565590083334368588890253123139704298730990782503769911324779715431555531, y_imag: 9779648407879205346559610309258181044130619080926897934572699915909528404984, y_real: 6779728121489434657638426458390319301070371227460768374343986326751507916979 },
+ G2Point {
+ x_imag: 11559732032986387107991004021392285783925812861821192530917403151452391805634,
+ x_real: 10857046999023057135944570762232829481370756359578518086990519993285655852781,
+ y_imag: 4082367875863433681332203403145435568316851327593401208105741076214120093531,
+ y_real: 8495653923123431417604973247489272438418190587263600148770280649306958101930,
+ },
+ G2Point {
+ x_imag: 15805639136721018565402881920352193254830339253282065586954346329754995870280,
+ x_real: 19089565590083334368588890253123139704298730990782503769911324779715431555531,
+ y_imag: 9779648407879205346559610309258181044130619080926897934572699915909528404984,
+ y_real: 6779728121489434657638426458390319301070371227460768374343986326751507916979,
+ },
],
- g1_srs: G1Point { x: 14312776538779914388377568895031746459131577658076416373430523308756343304251, y: 11763105256161367503191792604679297387056316997144156930871823008787082098465 },
+ g1_srs: G1Point {
+ x: 14312776538779914388377568895031746459131577658076416373430523308756343304251,
+ y: 11763105256161367503191792604679297387056316997144156930871823008787082098465,
+ },
}
let proof2 = PlonkProof {
lro: [
- G1Point { x: 0x2dac3ba24f360a6deda246f6d3e9d8080ed09f97126ef9af18c5de05ca340416, y: 0x054a4430da47cc1a780b8c91f2c4a3347b1523d220bee21f7b10016e0df7e708 },
- G1Point { x: 0x235ff58eb8e9feb8cf75355f3daec83dd4dde0ebe08ca90ea98510aba1585f4f, y: 0x0d1716e7f3a01ac0ac6f3a1f6130256444c0b25a114f9300abaeb0d0838d29b2 },
- G1Point { x: 0x2c1dbdf8e4d0f950e7d062751c52a03ad451685e0d23b45563aa87a7d74ec1cf, y: 0x2cff1161e6d5c9272c3892a76adeb9a5aada5d7065c8e41121ebf4bd9d0fb2cc },
+ G1Point {
+ x: 0x2dac3ba24f360a6deda246f6d3e9d8080ed09f97126ef9af18c5de05ca340416,
+ y: 0x054a4430da47cc1a780b8c91f2c4a3347b1523d220bee21f7b10016e0df7e708,
+ },
+ G1Point {
+ x: 0x235ff58eb8e9feb8cf75355f3daec83dd4dde0ebe08ca90ea98510aba1585f4f,
+ y: 0x0d1716e7f3a01ac0ac6f3a1f6130256444c0b25a114f9300abaeb0d0838d29b2,
+ },
+ G1Point {
+ x: 0x2c1dbdf8e4d0f950e7d062751c52a03ad451685e0d23b45563aa87a7d74ec1cf,
+ y: 0x2cff1161e6d5c9272c3892a76adeb9a5aada5d7065c8e41121ebf4bd9d0fb2cc,
+ },
],
- z: G1Point { x: 0x1657a289347c1973783849c4545c7ed8f0ea65f1eb40b31678d627e70b79bfd1, y: 0x1592517f8902c7364f90126fe04c28381fe12e165adcf82217876359a544e218 },
+ z: G1Point {
+ x: 0x1657a289347c1973783849c4545c7ed8f0ea65f1eb40b31678d627e70b79bfd1,
+ y: 0x1592517f8902c7364f90126fe04c28381fe12e165adcf82217876359a544e218,
+ },
h: [
- G1Point { x: 0x1aed4c55f27c9cb2021ddae086085388d250dc257cc61ece968e674b25ed18a3, y: 0x2e9fbdee2b76ceb2c26d73c760252070fab8d5c04dd4f5616ca352666bb18782 },
- G1Point { x: 0x0bb1920bd0959e61569ec796bd832e78f92e20320fc9cc9ae6ae8470dab64371, y: 0x09fdd853d0db78b9ce5811df7c7bf6a7c0486cf433219034e1c43206b64a404a },
- G1Point { x: 0x19280febb426e548e99e6279adceffaa4ddae622ec50624afb4ea827467adc41, y: 0x099d164e7abfdc97d9b168461c2626e88239d30529974cb1b582d7362ed6d6d5 },
+ G1Point {
+ x: 0x1aed4c55f27c9cb2021ddae086085388d250dc257cc61ece968e674b25ed18a3,
+ y: 0x2e9fbdee2b76ceb2c26d73c760252070fab8d5c04dd4f5616ca352666bb18782,
+ },
+ G1Point {
+ x: 0x0bb1920bd0959e61569ec796bd832e78f92e20320fc9cc9ae6ae8470dab64371,
+ y: 0x09fdd853d0db78b9ce5811df7c7bf6a7c0486cf433219034e1c43206b64a404a,
+ },
+ G1Point {
+ x: 0x19280febb426e548e99e6279adceffaa4ddae622ec50624afb4ea827467adc41,
+ y: 0x099d164e7abfdc97d9b168461c2626e88239d30529974cb1b582d7362ed6d6d5,
+ },
],
- bsb22_commitments: [G1Point { x: 0x27086e886de4f31d65e997d9dd08e35dd6590101d9185db7c8c5dd7dd9348c9c, y: 0x1b711862d9757e744014177960751f5f5a84f14bbc1b019021db0666b8e55fc3 }],
- batched_h: G1Point { x: 0x24577aded4d6983f59f123e52821f39141c397fcc957b4f7a2a4ede57b55ef10, y: 0x05e37b2c4f98ccba063aef65967db4e19547a1e18bea96ab8ec861b7a3e085db },
- claimed_values: [0x2a2af70b568d007ce53077a078437c2acf6cad206354b0ffa823b4de87918a05, 0x03a674ce289759e10b9da150b523d55886b63dc8526f0e36132edb5239c0c238, 0x19d465a94658e64d3798897c8438352029a3d285a049af99ff195c36359c16d0, 0x086e2bbb1679e24af18ee4aac62fded55640735e7c6aeda82abe2c01a3f307c9, 0x0dad3ef6870691a71276c4f6f185fb14cfe8c7a418c26b3620ce09eff0d21a42, 0x28ecd97e273c00ce59504ccc15bfe8a2d8f87d1bbd7dc63df606b3c975080a6f],
- z_shifted_h: G1Point { x: 0x2a5ab0dadfc301d004d4863346963baebbd7ea536022a8b90cd9b52d865d5c9c, y: 0x1e6437eaa886f121c46132f1bcd890827f7860cc63e5b27d8319f9b0cab8d27e },
+ bsb22_commitments: [
+ G1Point {
+ x: 0x27086e886de4f31d65e997d9dd08e35dd6590101d9185db7c8c5dd7dd9348c9c,
+ y: 0x1b711862d9757e744014177960751f5f5a84f14bbc1b019021db0666b8e55fc3,
+ },
+ ],
+ batched_h: G1Point {
+ x: 0x24577aded4d6983f59f123e52821f39141c397fcc957b4f7a2a4ede57b55ef10,
+ y: 0x05e37b2c4f98ccba063aef65967db4e19547a1e18bea96ab8ec861b7a3e085db,
+ },
+ claimed_values: [
+ 0x2a2af70b568d007ce53077a078437c2acf6cad206354b0ffa823b4de87918a05,
+ 0x03a674ce289759e10b9da150b523d55886b63dc8526f0e36132edb5239c0c238,
+ 0x19d465a94658e64d3798897c8438352029a3d285a049af99ff195c36359c16d0,
+ 0x086e2bbb1679e24af18ee4aac62fded55640735e7c6aeda82abe2c01a3f307c9,
+ 0x0dad3ef6870691a71276c4f6f185fb14cfe8c7a418c26b3620ce09eff0d21a42,
+ 0x28ecd97e273c00ce59504ccc15bfe8a2d8f87d1bbd7dc63df606b3c975080a6f,
+ ],
+ z_shifted_h: G1Point {
+ x: 0x2a5ab0dadfc301d004d4863346963baebbd7ea536022a8b90cd9b52d865d5c9c,
+ y: 0x1e6437eaa886f121c46132f1bcd890827f7860cc63e5b27d8319f9b0cab8d27e,
+ },
z_shifted_value: 0x2c1660be901029bf87b9796eedddc65aef146a4419ae4a123ee18aacfa9c41d1,
}
// NOTE: Full verify() can't be tested via `fe test` because the large
@@ -928,15 +1226,15 @@ fn test_verify_end_to_end() uses (evm: mut Evm) {
fn test_kzg_fold_scalars() {
// Verify that gamma_kzg powers are computed correctly
// Given a known gamma_kzg, the powers should be [1, g, g^2, g^3, ...]
- let g: u256 = 7 // arbitrary test value
+ let g: u256 = 7 // arbitrary test value
let g0: u256 = 1
let g1 = g
let g2 = field::mul(g1, g)
let g3 = field::mul(g2, g)
- assert(g0 == 1)
- assert(g1 == 7)
- assert(g2 == 49)
- assert(g3 == 343)
+ assert!(g0 == 1)
+ assert!(g1 == 7)
+ assert!(g2 == 49)
+ assert!(g3 == 343)
// Folded eval = sum(claimed[i] * g^i)
let claimed: [u256; 4] = [10, 20, 30, 40]
@@ -946,7 +1244,7 @@ fn test_kzg_fold_scalars() {
folded = field::add(folded, field::mul(claimed[2], g2))
folded = field::add(folded, field::mul(claimed[3], g3))
// 10*1 + 20*7 + 30*49 + 40*343 = 10 + 140 + 1470 + 13720 = 15340
- assert(folded == 15340)
+ assert!(folded == 15340)
}
#[test]
@@ -955,10 +1253,13 @@ fn test_v6_gamma_label_and_vk() uses (evm: mut Evm) {
let mut t = Transcript::new()
t = t.write_label(label: GAMMA_LABEL, label_len: 5)
// S1_X from v6 VK
- t = t.write_u256(val:9956956733383539527828528704346982954811130189972564286856709656590492390783)
+ t = t
+ .write_u256(
+ val: 9956956733383539527828528704346982954811130189972564286856709656590492390783,
+ )
// Just test the first 37 bytes produce the right start
// If this passes, the label encoding and first VK value are correct
- assert(t.len == 37)
+ assert!(t.len == 37)
}
#[test]
@@ -967,50 +1268,125 @@ fn test_v6_gamma_challenge() uses (evm: mut Evm) {
let mut t = Transcript::new()
t = t.write_label(label: GAMMA_LABEL, label_len: 5)
// S1 (x, y)
- t = t.write_u256(val:9956956733383539527828528704346982954811130189972564286856709656590492390783)
- t = t.write_u256(val:16561941243254960602343726886092320314575403533969071986056337989120686189882)
+ t = t
+ .write_u256(
+ val: 9956956733383539527828528704346982954811130189972564286856709656590492390783,
+ )
+ t = t
+ .write_u256(
+ val: 16561941243254960602343726886092320314575403533969071986056337989120686189882,
+ )
// S2 (x, y)
- t = t.write_u256(val:20374741449540543556499660179263983188390530543434373332462519860014413516289)
- t = t.write_u256(val:8513455195626237033487485922347652175901063415320070186421575800344119284165)
+ t = t
+ .write_u256(
+ val: 20374741449540543556499660179263983188390530543434373332462519860014413516289,
+ )
+ t = t
+ .write_u256(
+ val: 8513455195626237033487485922347652175901063415320070186421575800344119284165,
+ )
// S3 (x, y)
- t = t.write_u256(val:17142227368091895742859950676182428277541451282467607716193503860042663502549)
- t = t.write_u256(val:12829174888268721439052436070745892278566825005271705420525175951948128646413)
+ t = t
+ .write_u256(
+ val: 17142227368091895742859950676182428277541451282467607716193503860042663502549,
+ )
+ t = t
+ .write_u256(
+ val: 12829174888268721439052436070745892278566825005271705420525175951948128646413,
+ )
// QL (x, y)
- t = t.write_u256(val:10936403877113400171814029258586094421105837069937643866695822256928377913968)
- t = t.write_u256(val:17311182666118490454430265150735546359745608671115556843788944971563039300016)
+ t = t
+ .write_u256(
+ val: 10936403877113400171814029258586094421105837069937643866695822256928377913968,
+ )
+ t = t
+ .write_u256(
+ val: 17311182666118490454430265150735546359745608671115556843788944971563039300016,
+ )
// QR (x, y)
- t = t.write_u256(val:16032802090162682725903814972017385562886704406468141346968145983310475511911)
- t = t.write_u256(val:16803777488545011133374943287703653910096989118082992957503857327508542673114)
+ t = t
+ .write_u256(
+ val: 16032802090162682725903814972017385562886704406468141346968145983310475511911,
+ )
+ t = t
+ .write_u256(
+ val: 16803777488545011133374943287703653910096989118082992957503857327508542673114,
+ )
// QM (x, y)
- t = t.write_u256(val:7041740842251303753059524333065028234525995021747993588573234611770565484750)
- t = t.write_u256(val:7756772573841616356086078220846315947185632323121180681135487008638788536094)
+ t = t
+ .write_u256(
+ val: 7041740842251303753059524333065028234525995021747993588573234611770565484750,
+ )
+ t = t
+ .write_u256(
+ val: 7756772573841616356086078220846315947185632323121180681135487008638788536094,
+ )
// QO (x, y)
- t = t.write_u256(val:8807113593766821411972572357967651651345992430818514862534237402324085851875)
- t = t.write_u256(val:9827115302746495531711628100661677137543191000457083504235238115987266270156)
+ t = t
+ .write_u256(
+ val: 8807113593766821411972572357967651651345992430818514862534237402324085851875,
+ )
+ t = t
+ .write_u256(
+ val: 9827115302746495531711628100661677137543191000457083504235238115987266270156,
+ )
// QK (x, y)
- t = t.write_u256(val:4659055902458442531441402775737578699425178194825095727614170820825642511722)
- t = t.write_u256(val:2854792741677890224744936867769988448466277171603338196705997958237726289995)
+ t = t
+ .write_u256(
+ val: 4659055902458442531441402775737578699425178194825095727614170820825642511722,
+ )
+ t = t
+ .write_u256(
+ val: 2854792741677890224744936867769988448466277171603338196705997958237726289995,
+ )
// QCP[0] (x, y)
- t = t.write_u256(val:8032592088052402119252717716570843753829708920203926363246235929861264130729)
- t = t.write_u256(val:13824231045893282984607165590437904083147145250603202024200081150405773221988)
+ t = t
+ .write_u256(
+ val: 8032592088052402119252717716570843753829708920203926363246235929861264130729,
+ )
+ t = t
+ .write_u256(
+ val: 13824231045893282984607165590437904083147145250603202024200081150405773221988,
+ )
// 5 public inputs
- t = t.write_u256(val:0x004a55ed3c7a07d0233a027278a8b7ff8681ffbd5d1ec4795c18966f6e693090) // pi0
- t = t.write_u256(val:0x0f1cb7decf31e49c7934c3740bec5df3ead27bc947af739782930df6e37e9d90) // pi1
- t = t.write_u256(val:0) // pi2 exitCode
- t = t.write_u256(val:0x008cd56e10c2fe24795cff1e1d1f40d3a324528d315674da45d26afb376e8670) // pi3 vkRoot
- t = t.write_u256(val:0) // pi4 nonce
+ t = t.write_u256(
+ val: 0x004a55ed3c7a07d0233a027278a8b7ff8681ffbd5d1ec4795c18966f6e693090,
+ ) // pi0
+ t = t.write_u256(
+ val: 0x0f1cb7decf31e49c7934c3740bec5df3ead27bc947af739782930df6e37e9d90,
+ ) // pi1
+ t = t.write_u256(val: 0) // pi2 exitCode
+ t = t
+ .write_u256(
+ val: 0x008cd56e10c2fe24795cff1e1d1f40d3a324528d315674da45d26afb376e8670,
+ ) // pi3 vkRoot
+ t = t.write_u256(val: 0) // pi4 nonce
// Wire commitments L, R, O from v6 proof (starting at byte 100)
- t = t.write_u256(val:0x06232459bd070942b95a2fd99cf8872eeee49ba7cd7ebe07ec3ef1b4b2a74d91) // L.x
- t = t.write_u256(val:0x154e14823bfcf0b1fcd5a43df161341594c070ae4d2814a818c262a435b68188) // L.y
- t = t.write_u256(val:0x15404bf08191a8b3095519798cf76c536f65e264997b59e7f9f554d7b9d24b12) // R.x
- t = t.write_u256(val:0x0887cd80d76b8b56c9261983cae540bfbc77f2aabb5ee16cee0362dfe079bd12) // R.y
- t = t.write_u256(val:0x0940fd1df4048a50b264164a972fc28739dc1365e3dcd3f0fb39a89e5dbf48e2) // O.x
- t = t.write_u256(val:0x2903f07b564d791699df704aeb7fc3a0d196e392eaba115b629a562d7b54daa9) // O.y
+ t = t.write_u256(
+ val: 0x06232459bd070942b95a2fd99cf8872eeee49ba7cd7ebe07ec3ef1b4b2a74d91,
+ ) // L.x
+ t = t.write_u256(
+ val: 0x154e14823bfcf0b1fcd5a43df161341594c070ae4d2814a818c262a435b68188,
+ ) // L.y
+ t = t.write_u256(
+ val: 0x15404bf08191a8b3095519798cf76c536f65e264997b59e7f9f554d7b9d24b12,
+ ) // R.x
+ t = t.write_u256(
+ val: 0x0887cd80d76b8b56c9261983cae540bfbc77f2aabb5ee16cee0362dfe079bd12,
+ ) // R.y
+ t = t.write_u256(
+ val: 0x0940fd1df4048a50b264164a972fc28739dc1365e3dcd3f0fb39a89e5dbf48e2,
+ ) // O.x
+ t = t.write_u256(
+ val: 0x2903f07b564d791699df704aeb7fc3a0d196e392eaba115b629a562d7b54daa9,
+ ) // O.y
let (_, gamma_raw, t) = t.squeeze()
// Expected v6 gamma_raw from SP1 trace
- assert(gamma_raw == 0x86c4ac45a0be843cc24c65d9d559dd135a4ecad0f433372fa79f7979c9c6705c)
+ assert!(
+ gamma_raw == 0x86c4ac45a0be843cc24c65d9d559dd135a4ecad0f433372fa79f7979c9c6705c,
+ )
}
#[test]
@@ -1021,23 +1397,35 @@ fn test_v6_all_challenges() uses (evm: mut Evm) {
// Beta = SHA256("beta" || gamma_raw)
let mut t = Transcript::new()
t = t.write_label(label: BETA_LABEL, label_len: 4)
- t = t.write_u256(val:gamma_raw)
+ t = t.write_u256(val: gamma_raw)
let (_, beta_raw, t) = t.squeeze()
- assert(beta_raw == 0x4e56c438a8b25590e81c8bb610688afb1f226fba52e6edc7363b21baca7eacab)
+ assert!(
+ beta_raw == 0x4e56c438a8b25590e81c8bb610688afb1f226fba52e6edc7363b21baca7eacab,
+ )
// Alpha = SHA256("alpha" || beta_raw || bsb22_commit || Z)
// bsb22 and Z from v6 proof at offsets 0x320 and 0x220 respectively
let mut t = Transcript::new()
t = t.write_label(label: ALPHA_LABEL, label_len: 5)
- t = t.write_u256(val:beta_raw)
+ t = t.write_u256(val: beta_raw)
// BSB22 commitment (v6 proof offset 0x320)
- t = t.write_u256(val:0x296197d04b2d5f020a80db0ee9b7a0d62f0c0576997960bf24b718a65edd5bd2)
- t = t.write_u256(val:0x089afd886e912bef248a89f57e075f5737fe71f57be70fdabb6a55f25f1c092b)
+ t = t.write_u256(
+ val: 0x296197d04b2d5f020a80db0ee9b7a0d62f0c0576997960bf24b718a65edd5bd2,
+ )
+ t = t.write_u256(
+ val: 0x089afd886e912bef248a89f57e075f5737fe71f57be70fdabb6a55f25f1c092b,
+ )
// Z commitment (v6 proof offset 0x220)
- t = t.write_u256(val:0x1b8cf196023c29725a2b372fcb7b02579480e58281ddba98dc4d054620dd1c50)
- t = t.write_u256(val:0x2cb66a9d6e2f0c5dc50e32510c756b0ad319202f34171e69820014d705c3bcea)
+ t = t.write_u256(
+ val: 0x1b8cf196023c29725a2b372fcb7b02579480e58281ddba98dc4d054620dd1c50,
+ )
+ t = t.write_u256(
+ val: 0x2cb66a9d6e2f0c5dc50e32510c756b0ad319202f34171e69820014d705c3bcea,
+ )
let (_, alpha_raw, t) = t.squeeze()
- assert(alpha_raw == 0x8b4c0cc8930c7effedf6847ec5b115c7b78b3b9a74ff18c9fa4ead79e39e14dc)
+ assert!(
+ alpha_raw == 0x8b4c0cc8930c7effedf6847ec5b115c7b78b3b9a74ff18c9fa4ead79e39e14dc,
+ )
}
#[test]
@@ -1047,18 +1435,32 @@ fn test_v6_zeta_challenge() uses (evm: mut Evm) {
// Zeta = SHA256("zeta" || alpha_raw || H0 || H1 || H2)
let mut t = Transcript::new()
t = t.write_label(label: ZETA_LABEL, label_len: 4)
- t = t.write_u256(val:alpha_raw)
+ t = t.write_u256(val: alpha_raw)
// H0
- t = t.write_u256(val:0x2f7c08eac11c4a53dff5104825a743418815599bec73b5b516c4a912343ad33a)
- t = t.write_u256(val:0x1ba1c600ce5d285d97428833bd6050d5708efc922b15ce7778d675071d5e2c0f)
+ t = t.write_u256(
+ val: 0x2f7c08eac11c4a53dff5104825a743418815599bec73b5b516c4a912343ad33a,
+ )
+ t = t.write_u256(
+ val: 0x1ba1c600ce5d285d97428833bd6050d5708efc922b15ce7778d675071d5e2c0f,
+ )
// H1
- t = t.write_u256(val:0x0aef2040bd5a16bf81e154b76387192a91362b431311434801774584c4cca5af)
- t = t.write_u256(val:0x2f82a5996ddafb7b5bc009ee1c336412a1abcb9de944ec961d65de0f07c36178)
+ t = t.write_u256(
+ val: 0x0aef2040bd5a16bf81e154b76387192a91362b431311434801774584c4cca5af,
+ )
+ t = t.write_u256(
+ val: 0x2f82a5996ddafb7b5bc009ee1c336412a1abcb9de944ec961d65de0f07c36178,
+ )
// H2
- t = t.write_u256(val:0x26dd3d2fab429286a3832f221505ac56cdbdc2dff07337a970b6d45aa542b395)
- t = t.write_u256(val:0x2fd4c0d4b57b853c080939eebac4298a3d1dbd19fa28fc2026efd88935bef01f)
+ t = t.write_u256(
+ val: 0x26dd3d2fab429286a3832f221505ac56cdbdc2dff07337a970b6d45aa542b395,
+ )
+ t = t.write_u256(
+ val: 0x2fd4c0d4b57b853c080939eebac4298a3d1dbd19fa28fc2026efd88935bef01f,
+ )
let (_, zeta_raw, t) = t.squeeze()
- assert(zeta_raw == 0x9cfa5df065c8d2170b994be2f13f26328184096125b806282cc4482082fb210d)
+ assert!(
+ zeta_raw == 0x9cfa5df065c8d2170b994be2f13f26328184096125b806282cc4482082fb210d,
+ )
}
#[test]
@@ -1088,29 +1490,41 @@ fn test_v6_pi_computation() uses (evm: mut Evm) {
while i < 5 {
let den = field::sub(zeta, omega_i)
let den_inv = field::inv(den)
- let li = field::mul(field::mul(field::mul(zh_zeta, omega_i), den_inv), n_inv)
+ let li = field::mul(
+ field::mul(field::mul(zh_zeta, omega_i), den_inv),
+ n_inv,
+ )
pi = field::add(pi, field::mul(li, pis[i]))
omega_i = field::mul(omega_i, omega)
i = i + 1
}
- assert(pi == 0x1fc53445308fcd4dec8047d362e47cc9bb24195e189111fea064c47bf560f82a)
+ assert!(
+ pi == 0x1fc53445308fcd4dec8047d362e47cc9bb24195e189111fea064c47bf560f82a,
+ )
// BSB22
let bsb22_x: u256 = 0x296197d04b2d5f020a80db0ee9b7a0d62f0c0576997960bf24b718a65edd5bd2
let bsb22_y: u256 = 0x089afd886e912bef248a89f57e075f5737fe71f57be70fdabb6a55f25f1c092b
let h_fr = hash_fr(bsb22_x, bsb22_y)
- assert(h_fr == 0x179f5050a2bd2f19ea3123f40b245b79058b7fea9ff6f31464e8e65798898c02)
+ assert!(
+ h_fr == 0x179f5050a2bd2f19ea3123f40b245b79058b7fea9ff6f31464e8e65798898c02,
+ )
// BSB22 Lagrange at index 5 + 25298720
let bsb_index: u256 = 25298725
let omega_bsb = pow_mod(omega, bsb_index)
let bsb_den = field::sub(zeta, omega_bsb)
let bsb_den_inv = field::inv(bsb_den)
- let bsb_lagrange = field::mul(field::mul(field::mul(zh_zeta, omega_bsb), bsb_den_inv), n_inv)
+ let bsb_lagrange = field::mul(
+ field::mul(field::mul(zh_zeta, omega_bsb), bsb_den_inv),
+ n_inv,
+ )
pi = field::add(pi, field::mul(h_fr, bsb_lagrange))
- assert(pi == 0x27386b8ab2747c014ccbb1de5b044b4d8559193f19e454ece2d9a6bc8ed51b47)
+ assert!(
+ pi == 0x27386b8ab2747c014ccbb1de5b044b4d8559193f19e454ece2d9a6bc8ed51b47,
+ )
}
#[test]
@@ -1130,7 +1544,10 @@ fn test_v6_const_lin() {
let zeta_power_n = pow_mod(zeta, n)
let zh_zeta = field::sub(zeta_power_n, one)
- let l1_zeta = field::mul(field::mul(zh_zeta, field::inv(field::sub(zeta, one))), n_inv)
+ let l1_zeta = field::mul(
+ field::mul(zh_zeta, field::inv(field::sub(zeta, one))),
+ n_inv,
+ )
let alpha_sq_l1 = field::mul(field::mul(alpha, alpha), l1_zeta)
// v6 proof claimed values (from gnark proof offsets 0x180-0x260)
@@ -1144,12 +1561,17 @@ fn test_v6_const_lin() {
let term_a = field::add(l, field::add(field::mul(beta, s1_eval), gamma))
let term_b = field::add(r, field::add(field::mul(beta, s2_eval), gamma))
let term_c = field::add(o, gamma)
- let perm_term = field::mul(field::mul(field::mul(term_a, term_b), term_c), field::mul(alpha, zu))
+ let perm_term = field::mul(
+ field::mul(field::mul(term_a, term_b), term_c),
+ field::mul(alpha, zu),
+ )
let inner = field::add(field::sub(pi, alpha_sq_l1), perm_term)
let const_lin = field::neg