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

Solidity verifier sponge #83

Merged
merged 11 commits into from
Nov 17, 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 eth_verifier/lib/Alphas.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import "./Fields.sol";
import "./bn254/Fields.sol";

using {Scalar.mul} for Scalar.FE;

Expand Down
4 changes: 2 additions & 2 deletions eth_verifier/lib/Commitment.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import "./BN254.sol";
import "./Fields.sol";
import "./bn254/BN254.sol";
import "./bn254/Fields.sol";
import "./Utils.sol";

using { BN254.add, BN254.scale_scalar } for BN254.G1Point;
Expand Down
2 changes: 1 addition & 1 deletion eth_verifier/lib/Evaluations.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import "./Fields.sol";
import "./bn254/Fields.sol";

struct PointEvaluations {
/// evaluation at the challenge point zeta
Expand Down
58 changes: 39 additions & 19 deletions eth_verifier/lib/Oracles.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import "./Fields.sol";
import "./bn254/Fields.sol";
import "./VerifierIndex.sol";
import "./Evaluations.sol";
import "./Alphas.sol";
import "./sponge/Sponge.sol";
import "./Commitment.sol";

library Oracles {
using {to_field_with_length, to_field} for ScalarChallenge;
Expand All @@ -16,27 +18,57 @@ library Oracles {
Scalar.pow
} for Scalar.FE;
using {AlphasLib.instantiate} for Alphas;
using {
KeccakSponge.reinit,
KeccakSponge.absorb_base,
KeccakSponge.absorb_scalar,
KeccakSponge.absorb_commitment,
KeccakSponge.challenge_base,
KeccakSponge.challenge_scalar,
KeccakSponge.digest_base,
KeccakSponge.digest_scalar
} for Sponge;

uint64 internal constant CHALLENGE_LENGTH_IN_LIMBS = 2;

function fiat_shamir(VerifierIndex storage index) public {
// WARN: We'll skip the use of a sponge and generate challenges from pseudo-random numbers
function fiat_shamir(
VerifierIndex storage index,
PolyComm memory public_comm,
Sponge storage base_sponge,
Sponge storage scalar_sponge
) public {
Scalar.FE endo_coeff = Scalar.from(0); // FIXME: not zero

base_sponge.reinit();

base_sponge.absorb_base(verifier_digest(index));
base_sponge.absorb_commitment(public_comm);

// TODO: absorb the commitments to the registers / witness columns
// TODO: lookups

// Sample beta and gamma from the sponge
Scalar.FE beta = challenge();
Scalar.FE gamma = challenge();
Scalar.FE beta = base_sponge.challenge_scalar();
Scalar.FE gamma = base_sponge.challenge_scalar();

// Sample alpha prime
ScalarChallenge memory alpha_chal = scalar_chal();
ScalarChallenge memory alpha_chal = ScalarChallenge(base_sponge.challenge_scalar());
// Derive alpha using the endomorphism
Scalar.FE alpha = alpha_chal.to_field(endo_coeff);

// TODO: enforce length of the $t$ commitment

// TODO: absorb commitment to the quotient poly

// Sample alpha prime
ScalarChallenge memory zeta_chal = scalar_chal();
ScalarChallenge memory zeta_chal = ScalarChallenge(base_sponge.challenge_scalar());
// Derive alpha using the endomorphism
Scalar.FE zeta = zeta_chal.to_field(endo_coeff);

scalar_sponge.reinit();
scalar_sponge.absorb_scalar(base_sponge.digest_scalar());


// often used values
Scalar.FE zeta1 = zeta.pow(index.domain_size);
Scalar.FE zetaw = zeta.mul(index.domain_gen);
Expand Down Expand Up @@ -71,18 +103,6 @@ library Oracles {
// combined inner prod
}

/// @notice creates a challenge frm hashing the current block timestamp.
/// @notice this function is only going to be used for the demo and never in
/// @notice a serious environment. DO NOT use this in any other case.
function challenge() internal view returns (Scalar.FE) {
Scalar.from(uint256(keccak256(abi.encode(block.timestamp))));
}

/// @notice creates a `ScaharChallenge` using `challenge()`.
function scalar_chal() internal view returns (ScalarChallenge memory) {
return ScalarChallenge(challenge());
}

struct ScalarChallenge {
Scalar.FE chal;
}
Expand Down
4 changes: 2 additions & 2 deletions eth_verifier/lib/Utils.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import "./BN254.sol";
import "./Fields.sol";
import "./bn254/BN254.sol";
import "./bn254/Fields.sol";
import "./UtilsExternal.sol";
import "forge-std/console.sol";

Expand Down
9 changes: 7 additions & 2 deletions eth_verifier/lib/VerifierIndex.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import {BN254} from "./BN254.sol";
import {BN254} from "./bn254/BN254.sol";
import {URS} from "./Commitment.sol";
import "./Fields.sol";
import "./bn254/Fields.sol";
import "./Alphas.sol";
import "./Evaluations.sol";

Expand All @@ -15,3 +15,8 @@ struct VerifierIndex {
Scalar.FE domain_gen;
Alphas powers_of_alpha;
}

function verifier_digest(VerifierIndex storage index) returns (Base.FE) {
// FIXME: todo!
return Base.from(42);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

pragma solidity ^0.8.0;

import "./UtilsExternal.sol";
import "../UtilsExternal.sol";
import "./Fields.sol";

/// @notice Barreto-Naehrig curve over a 254 bit prime field
Expand Down
44 changes: 40 additions & 4 deletions eth_verifier/lib/Fields.sol → eth_verifier/lib/bn254/Fields.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ library Base {
uint256 public constant MODULUS =
21888242871839275222246405745257275088696311157297823662689037894645226208583;

function zero() public pure returns (FE) {
return FE.wrap(0);
}

function from(uint n) public pure returns (FE) {
return FE.wrap(n % MODULUS);
}

function from_bytes_be(bytes memory b) public pure returns (FE) {
uint256 integer = 0;
for (uint i = 0; i < 32; i++) {
integer <<= 8;
integer += uint8(b[i]);
}
return FE.wrap(integer % MODULUS);
}

function add(
FE self,
FE other
Expand All @@ -27,12 +44,16 @@ library Base {
}

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

function inv(FE self) public view returns (FE) {
// TODO:
return FE.wrap(0);
(uint inverse, uint gcd) = Aux.xgcd(FE.unwrap(self), MODULUS);
require(gcd == 1, "gcd not 1");

return FE.wrap(inverse);
}

function neg(FE self) public pure returns (FE) {
Expand Down Expand Up @@ -77,7 +98,6 @@ library Base {
}
}
}
import "forge-std/console.sol";

/// @notice Implements 256 bit modular arithmetic over the scalar field of bn254.
library Scalar {
Expand All @@ -92,10 +112,26 @@ library Scalar {
19103219067921713944291392827692070036145651957329286315305642004821462161904;
uint256 public constant TWO_ADICITY = 28;

function zero() public pure returns (FE) {
return FE.wrap(0);
}

function from(uint n) public pure returns (FE) {
return FE.wrap(n % MODULUS);
}

function from_bytes_be(bytes memory b) public pure returns (FE) {
uint256 integer = 0;
uint count = b.length <= 32 ? b.length : 32;

for (uint i = 0; i < count; i++) {
integer <<= 8;
integer += uint8(b[i]);
}
integer <<= (32 - count) * 8;
return FE.wrap(integer % MODULUS);
}

function add(
FE self,
FE other
Expand Down
3 changes: 1 addition & 2 deletions eth_verifier/lib/msgpack/Deserialize.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ pragma solidity >=0.4.16 <0.9.0;

import {Kimchi} from "../../src/Verifier.sol";
import "../Commitment.sol";
import "../BN254.sol";
import "../bn254/BN254.sol";
import "../Evaluations.sol";
import "../Proof.sol";
import "../State.sol";
import "../Utils.sol";
import {console} from "forge-std/console.sol";

library MsgPk {
struct Stream {
Expand Down
101 changes: 101 additions & 0 deletions eth_verifier/lib/sponge/Sponge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import "../bn254/Fields.sol";
import "../bn254/BN254.sol";
import "../Commitment.sol";

struct Sponge {
bytes state;
}

library KeccakSponge {
// Basic methods

function reinit(Sponge storage self) external {
self.state = new bytes(0);
}

function absorb(Sponge storage self, bytes memory b) external {
for (uint i = 0; i < b.length; i++) {
self.state.push(b[i]);
}
}

function squeeze(
Sponge memory self,
uint byte_count
) public pure returns (bytes memory digest) {
digest = new bytes(byte_count);
bytes32 output;

for (uint i = 0; i < byte_count; i++) {
if (i % 32 == 0) {
output = keccak256(self.state);
self.state = abi.encode(output);
}

digest[i] = output[i % 32];
}
}

// KZG methods

function absorb_base(Sponge storage self, Base.FE elem) external {
bytes memory b = abi.encode(elem);
for (uint i = 0; i < b.length; i++) {
self.state.push(b[i]);
}
}

function absorb_scalar(Sponge storage self, Scalar.FE elem) external {
bytes memory b = abi.encode(elem);
for (uint i = 0; i < b.length; i++) {
self.state.push(b[i]);
}
}

function absorb_g(
Sponge storage self,
BN254.G1Point memory point
) external {
bytes memory b = abi.encode(point);
for (uint i = 0; i < b.length; i++) {
self.state.push(b[i]);
}
}

function absorb_commitment(
Sponge storage self,
PolyComm memory comm
) external {
bytes memory b = abi.encode(comm);
for (uint i = 0; i < b.length; i++) {
self.state.push(b[i]);
}
}

function challenge_base(
Sponge storage self
) external pure returns (Base.FE chal) {
chal = Base.from_bytes_be(squeeze(self, 16));
}

function challenge_scalar(
Sponge storage self
) external pure returns (Scalar.FE chal) {
chal = Scalar.from_bytes_be(squeeze(self, 16));
}

function digest_base(
Sponge storage self
) external pure returns (Base.FE digest) {
digest = Base.from_bytes_be(squeeze(self, 32));
}

function digest_scalar(
Sponge storage self
) external pure returns (Scalar.FE digest) {
digest = Scalar.from_bytes_be(squeeze(self, 32));
}
}
9 changes: 6 additions & 3 deletions eth_verifier/src/Verifier.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

import "../lib/Fields.sol";
import "../lib/BN254.sol";
import "../lib/bn254/Fields.sol";
import "../lib/bn254/BN254.sol";
import "../lib/VerifierIndex.sol";
import "../lib/Commitment.sol";
import "../lib/Oracles.sol";
Expand Down Expand Up @@ -48,6 +48,9 @@ contract KimchiVerifier {
VerifierIndex verifier_index;
ProverProof proof;

Sponge base_sponge;
Sponge scalar_sponge;

State internal state;
bool state_available;

Expand Down Expand Up @@ -156,7 +159,7 @@ contract KimchiVerifier {
).commitment;
}

Oracles.fiat_shamir(verifier_index);
Oracles.fiat_shamir(verifier_index, public_comm, base_sponge, scalar_sponge);
}

/*
Expand Down
Loading