Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fields demo #45

Merged
merged 9 commits into from
Oct 19, 2023
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 demo/eth_verifier/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ setup:
foundryup

test:
forge test
forge test -vv

proof:
cd circuit_gen && cargo run
5 changes: 5 additions & 0 deletions demo/eth_verifier/src/BN254.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pragma solidity >=0.8.2 <0.9.0;

library BN254 {

struct G1 {
uint256 x;
uint256 y;
Expand Down Expand Up @@ -39,6 +40,10 @@ library BN254 {
}

function scale(G1 memory p, uint256 k) public view returns (G1 memory) {
if (!in_curve(p) || k == 0) {
return point_at_inf();
}

uint256[4] memory input;
input[0] = p.x;
input[1] = p.y;
Expand Down
13 changes: 13 additions & 0 deletions demo/eth_verifier/src/Commitment.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import {BN254} from "./BN254.sol";

library Commitment {
struct PolyComm {
BN254.G1[] unshifted;
//BN254G1 shifted;
// WARN: The previous field is optional but in Solidity we can't have that.
// for our test circuit (circuit_gen/) it's not necessary
}
}
68 changes: 68 additions & 0 deletions demo/eth_verifier/src/Fields.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

/// @notice Implements 256 bit modular arithmetic over the base field of bn254.
library Base {
type FE is uint256;

using { add, mul, inv } for FE;

uint256 public constant MODULUS =
21888242871839275222246405745257275088696311157297823662689037894645226208583;

function add(
FE self,
FE other
) public pure returns (FE res) {
assembly {
res := addmod(self, other, MODULUS) // addmod has arbitrary precision
}
}

function mul(
FE self,
FE other
) public pure returns (FE res) {
assembly {
res := mulmod(self, other, MODULUS) // mulmod has arbitrary precision
}
}

function inv(FE self) public view returns (FE) {
// TODO:
return FE.wrap(0);
}
}

/// @notice Implements 256 bit modular arithmetic over the scalar field of bn254.
library Scalar {
type FE is uint256;

using { add, mul, inv } for FE;

uint256 public constant MODULUS =
21888242871839275222246405745257275088548364400416034343698204186575808495617;

function add(
FE self,
FE other
) public pure returns (FE res) {
assembly {
res := addmod(self, other, MODULUS) // addmod has arbitrary precision
}
}

function mul(
FE self,
FE other
) public pure returns (FE res) {
assembly {
res := mulmod(self, other, MODULUS) // mulmod has arbitrary precision
}
}

function inv(FE self) public view returns (FE) {
// TODO:
return FE.wrap(0);
}
}
46 changes: 46 additions & 0 deletions demo/eth_verifier/src/Verifier.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import {Scalar, Base} from "./Fields.sol";

library Kimchi {
struct Proof {
uint data;
Expand Down Expand Up @@ -58,6 +60,50 @@ contract KimchiVerifier {
return true;
}

/*
Partial verification:
1. Check the length of evaluations insde the proof. SKIPPED
2. Commit to the negated public input poly
3. Fiat-Shamir (MAY SKIP OR VASTLY SIMPLIFY)
4. Combined chunk polynomials evaluations
5. Commitment to linearized polynomial f
6. Chunked commitment of ft
7. List poly commitments for final verification
*/
function partial_verify(Scalar.FE[] memory public_inputs) public view {
/*
let public_comm = {
if public_input.len() != verifier_index.public {
return Err(VerifyError::IncorrectPubicInputLength(
verifier_index.public,
));
}
let lgr_comm = verifier_index
.srs()
.get_lagrange_basis(verifier_index.domain.size())
.expect("pre-computed committed lagrange bases not found");
let com: Vec<_> = lgr_comm.iter().take(verifier_index.public).collect();
if public_input.is_empty() {
PolyComm::new(
vec![verifier_index.srs().blinding_commitment(); chunk_size],
None,
)
} else {
let elm: Vec<_> = public_input.iter().map(|s| -*s).collect();
let public_comm = PolyComm::<G>::multi_scalar_mul(&com, &elm);
verifier_index
.srs()
.mask_custom(
public_comm.clone(),
&public_comm.map(|_| G::ScalarField::one()),
)
.unwrap()
.commitment
}
};
*/
}

/* TODO WIP
function deserialize_proof(
uint256[] calldata public_inputs,
Expand Down
10 changes: 10 additions & 0 deletions demo/eth_verifier/src/VerifierIndex.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import {BN254} from "./BN254.sol";

library Kimchi {
struct VerifierIndex {
uint data;
}
}
27 changes: 27 additions & 0 deletions demo/eth_verifier/test/Fields.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Test } from "forge-std/Test.sol";
import {console} from "forge-std/console.sol";
import {Scalar, Base} from "../src/Fields.sol";

using { Base.add, Base.mul, Base.inv } for Base.FE;
using { Scalar.add, Scalar.mul, Scalar.inv } for Scalar.FE;

contract FieldsTest is Test {
function test_add_base() public {
Base.FE q = Base.FE.wrap(Base.MODULUS - 1);
Base.FE one = Base.FE.wrap(1);

Base.FE q_plus_one = q.add(one);
assertEq(Base.FE.unwrap(q_plus_one), 0, "p == 0 mod p");
}

function test_add_scalar() public {
Scalar.FE q = Scalar.FE.wrap(Scalar.MODULUS - 1);
Scalar.FE one = Scalar.FE.wrap(1);

Scalar.FE q_plus_one = q.add(one);
assertEq(Scalar.FE.unwrap(q_plus_one), 0, "p == 0 mod p");
}
}