Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
profile: minimal
toolchain: stable
- name: Build
run: cargo build --verbose
run: cargo build --verbose --workspace --exclude evm-vrfier

build-wasm32:
runs-on: ubuntu-latest
Expand Down
12 changes: 10 additions & 2 deletions evm-vrfier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ version = "0.1.0"
edition = "2021"

[dependencies]
alloy = { version = "0.13", default-features = false, features = ["contract", "provider-anvil-node"] }
alloy = { version = "0.14", default-features = false, features = ["contract", "provider-anvil-node"] }
ark-ff = { workspace = true }
ark-bls12-381 = { version = "0.5", default-features = false, features = ["curve"] }

[dev-dependencies]
tokio = { version = "1.44", default-features = false }
ark-std = { workspace = true }
ark-ec = { workspace = true }
w3f-pcs = { workspace = true }

[build-dependencies]
foundry-config = { git="https://github.com/foundry-rs/foundry" }
foundry-config = { git = "https://github.com/foundry-rs/foundry" }
foundry-compilers = { version = "0.14.0" }
3 changes: 3 additions & 0 deletions evm-vrfier/contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ src = "src"
out = "out"
libs = ["lib"]

evm_version = "prague"
via_ir = true

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
66 changes: 66 additions & 0 deletions evm-vrfier/contracts/src/BlsGenerators.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
pragma solidity ^0.8.24;

import "./SoladyBls.sol";

library BlsGenerators {
uint256 constant q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001;

function add_fr(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = addmod(a, b, q);
}

function mul_fr(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = mulmod(a, b, q);
}

function G1() internal pure returns (BLS.G1Point memory) {
return BLS.G1Point(
bytes32(uint256(31827880280837800241567138048534752271)),
bytes32(uint256(88385725958748408079899006800036250932223001591707578097800747617502997169851)),
bytes32(uint256(11568204302792691131076548377920244452)),
bytes32(uint256(114417265404584670498511149331300188430316142484413708742216858159411894806497))
);
}

function G2() internal pure returns (BLS.G2Point memory) {
return BLS.G2Point(
bytes32(uint256(3045985886519456750490515843806728273)),
bytes32(uint256(89961632905173714226157479458612185649920463576279427516307505038263245192632)),
bytes32(uint256(26419286191256893424348605754143887205)),
bytes32(uint256(40446337346877272185227670183527379362551741423616556919902061939448715946878)),
bytes32(uint256(17144095208600308495026432580569150746)),
bytes32(uint256(78698209480990513415779284580404715789311803115477290401294577488850054555649)),
bytes32(uint256(8010509799087472606393075511737879449)),
bytes32(uint256(91929332261301883145239454754739358796115486554644188311284324629555800144318))
);
}

function G2_NEG() internal pure returns (BLS.G2Point memory) {
return BLS.G2Point(
bytes32(uint256(3045985886519456750490515843806728273)),
bytes32(uint256(89961632905173714226157479458612185649920463576279427516307505038263245192632)),
bytes32(uint256(26419286191256893424348605754143887205)),
bytes32(uint256(40446337346877272185227670183527379362551741423616556919902061939448715946878)),
bytes32(uint256(17421388336814597573762763446246275004)),
bytes32(uint256(82535940630695547964844822885348920226556672312706312698172214783216175252138)),
bytes32(uint256(26554973746327433462396120515077546301)),
bytes32(uint256(69304817850384178235384652711014277219752988873539414788182467642510429663469))
);
}

function g1_mul(BLS.G1Point memory point, bytes32 scalar) internal view returns (BLS.G1Point memory) {
BLS.G1Point[] memory points = new BLS.G1Point[](1);
bytes32[] memory scalars = new bytes32[](1);
points[0] = point;
scalars[0] = scalar;
return BLS.msm(points, scalars);
}

function g2_mul(BLS.G2Point memory point, bytes32 scalar) internal view returns (BLS.G2Point memory) {
BLS.G2Point[] memory points = new BLS.G2Point[](1);
bytes32[] memory scalars = new bytes32[](1);
points[0] = point;
scalars[0] = scalar;
return BLS.msm(points, scalars);
}
}
93 changes: 93 additions & 0 deletions evm-vrfier/contracts/src/PlonkKzg.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
pragma solidity ^0.8.24;

import "./BlsGenerators.sol";

contract PlonkKzg {
// The trapdoor `tau` in G2, part of the standard KZG verification key.
BLS.G2Point tau_g2;

constructor(BLS.G2Point memory tau_g2_) {
tau_g2 = tau_g2_;
}

function verify_plonk_kzg(
BLS.G1Point[] memory polys_z1,
BLS.G1Point memory poly_z2,
uint256 z1,
uint256 z2,
uint256[] memory evals_at_z1,
uint256 eval_at_z2,
BLS.G1Point memory proof_z1,
BLS.G1Point memory proof_z2,
bytes32[] memory nus,
uint256 r
) public view returns (bool) {
assert(evals_at_z1.length == polys_z1.length);
assert(nus.length == polys_z1.length);

uint256 n_bases = polys_z1.length + 4;

BLS.G1Point[] memory msm_bases = new BLS.G1Point[](n_bases);
bytes32[] memory msm_scalars = new bytes32[](n_bases);

uint256 i;
for (i = 0; i < polys_z1.length; i++) {
msm_bases[i] = polys_z1[i];
}

for (i = 0; i < polys_z1.length; i++) {
msm_scalars[i] = nus[i];
}

uint256 agg_at_z = 0;
for (i = 0; i < polys_z1.length; i++) {
agg_at_z = BlsGenerators.add_fr(agg_at_z, BlsGenerators.mul_fr(uint256(nus[i]), evals_at_z1[i]));
}
msm_bases[i] = BlsGenerators.G1();
msm_scalars[i] = bytes32(BlsGenerators.q - BlsGenerators.add_fr(agg_at_z, BlsGenerators.mul_fr(r, eval_at_z2)));

msm_bases[++i] = proof_z1;
msm_scalars[i] = bytes32(z1);

msm_bases[++i] = poly_z2;
msm_scalars[i] = bytes32(r);

msm_bases[++i] = proof_z2;
msm_scalars[i] = bytes32(BlsGenerators.mul_fr(r, z2));

BLS.G1Point memory agg_acc = BLS.msm(msm_bases, msm_scalars);
BLS.G1Point memory acc_proof = BLS.add(proof_z1, BlsGenerators.g1_mul(proof_z2, bytes32(r)));
return verify_acc(agg_acc, acc_proof);
}

function verify(BLS.G1Point memory c, uint256 z, uint256 v, BLS.G1Point memory proof) public view returns (bool) {
bytes32[] memory msm_scalars = new bytes32[](2);
BLS.G1Point[] memory msm_bases = new BLS.G1Point[](2);
msm_scalars[0] = bytes32(z);
msm_bases[0] = proof;
msm_scalars[1] = bytes32(BlsGenerators.q - v);
msm_bases[1] = BlsGenerators.G1();
BLS.G1Point memory acc = BLS.msm(msm_bases, msm_scalars);
acc = BLS.add(acc, c);
return verify_acc(acc, proof);
}

function verify_acc(BLS.G1Point memory acc, BLS.G1Point memory acc_proof) public view returns (bool) {
return pairing2(acc, BlsGenerators.G2_NEG(), acc_proof, tau_g2);
}

function pairing2(
BLS.G1Point memory g1_1,
BLS.G2Point memory g2_1,
BLS.G1Point memory g1_2,
BLS.G2Point memory g2_2
) public view returns (bool result) {
BLS.G1Point[] memory g1_points = new BLS.G1Point[](2);
BLS.G2Point[] memory g2_points = new BLS.G2Point[](2);
g1_points[0] = g1_1;
g2_points[0] = g2_1;
g1_points[1] = g1_2;
g2_points[1] = g2_2;
return BLS.pairing(g1_points, g2_points);
}
}
Loading
Loading