Skip to content

Commit

Permalink
Demo verifier test debug (#63)
Browse files Browse the repository at this point in the history
* WIP generating test proof

* KZG test generator done

* Add verifier index

* Update makefile

* Verifier steps

* chore: forge init

* forge install: forge-std

v1.7.1

* rest.yml removed

* Initial files

* serializedProof as an input

* Added some operations over bn254 using precompiles

* Moved bn254.sol

* BN254.sol file included

* Added bn254 test

* Fix test

* Deprecated old verifier

* Delete duplicated file

* Fix foundry submodule name

* WIP deserialize_proof in verifier.sol

* adding ark-bn254 crate

* bn254 file

* Add fields demo (#45)

* WIP Implementing Fields and Commitments

* Added inv field

* Added scalar field

* Added 'using for'

* Small tweak

* Added base field test

* Fixed base test, added scalar test

* Removed inv

* Solidity verifier step 2 (#51)

* WIP step 2

* WIP step 2

* Added polycomm msm, continued step2

* Added mask_custom

* Remove commented blocks

* deserialization of opening proof

* improving error return in deserializeOpeningProof

* changes in test_deserialize_opening_proof

* Replace solidity verifier bn254 lib and fixes (#54)

* WIP replace bn254 lib

* Fix length

* Multiple fixes

* Added partial_verify run test

* Fix partial verify test

* Add CI job

* Added setup step to CI job

* Added ci make rule

* Use action

* Revert BN254

* Remove utils.sol

* Fix partial verify test

* small changes

* New bn254 (#56)

* Revert "Revert BN254"

This reverts commit 934d3bb.

* Revert "Remove utils.sol"

This reverts commit 999ce22.

* Added rmp serialization

* Better test for deser

* Refactor, cleared some code

* Formatting

* Removed unused circuit_gen

* WIP Deserialize URS

* WIP URS deserialization

* Fixed deser, added test

* Added comments'

* Implemented pow for base field

* Removed unnecesary log

* Added FFT

* Fix fft

* WIP generating basis

* Finish iFFT

* Finished calculate_lagrange_bases

* Implemented inv for field

* Refactor xgcd

* Fixed lagrange_base nested arrays problem

* WIP Iterative FFT

* Finished iterative FFT

* Fixed circular dependency

* Fix out of bounds err

* Uncomment test

* New pow of two related functions

* Fix get_primitive_root_of_unity()

* Remove conflict market

* Fix makefile

* Fix xgcd

* Fix inv scalar field

* Fix is_pow_of_two()

* Fix get_twiddles arr

* Fixed last part of calculate_lagrange_basis

* Fix flat polycomm

---------

Co-authored-by: Pablo Deymonnaz <[email protected]>
  • Loading branch information
xqft and pablodeymo authored Nov 1, 2023
1 parent 4c13418 commit 2c79349
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 56 deletions.
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[submodule "verifier_circuit/o1js"]
path = verifier_circuit/o1js
url = https://github.com/lambdaclass/o1js.git
url = https://github.com/lambdaclass/o1js.git
branch = kzg_prover
[submodule "demo/eth_verifier/lib/forge-std"]
path = demo/eth_verifier/lib/forge-std
url = https://github.com/foundry-rs/forge-std
url = https://github.com/foundry-rs/forge-std
28 changes: 24 additions & 4 deletions demo/eth_verifier/src/Commitment.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ error MSMInvalidLengths();
struct URS {
BN254.G1Point[] g;
BN254.G1Point h;
mapping(uint256 => PolyComm[]) lagrange_bases;
mapping(uint256 => PolyCommFlat) lagrange_bases_unshifted;
}

struct PolyComm {
Expand All @@ -22,6 +22,25 @@ struct PolyComm {
// for our test circuit (circuit_gen/) it's not necessary
}

struct PolyCommFlat {
BN254.G1Point[] unshifteds;
uint unshifted_length;
}

function poly_comm_unflat(PolyCommFlat memory com) pure returns (PolyComm[] memory res) {
// FIXME: assumes that every unshifted is the same length

res = new PolyComm[](com.unshifteds.length / com.unshifted_length);
for (uint i = 0; i < res.length; i++) {
uint n = com.unshifted_length;
BN254.G1Point[] memory unshifted = new BN254.G1Point[](n);
for (uint j = 0; j < n; j++) {
unshifted[j] = com.unshifteds[j + i*n];
}
res[i] = PolyComm(unshifted);
}
}

// @notice Executes multi-scalar multiplication between scalars `elm` and commitments `com`.
// @notice If empty, returns a commitment with the point at infinity.
function polycomm_msm(PolyComm[] memory com, Scalar.FE[] memory elm)
Expand Down Expand Up @@ -128,7 +147,7 @@ function calculate_lagrange_bases(
BN254.G1Point[] memory g,
BN254.G1Point memory h,
uint domain_size,
mapping(uint256 => PolyComm[]) storage lagrange_bases
mapping(uint256 => PolyCommFlat) storage lagrange_bases_unshifted
) {
uint urs_size = g.length;
uint num_unshifteds = (domain_size + urs_size - 1) / urs_size;
Expand All @@ -154,11 +173,12 @@ function calculate_lagrange_bases(
unshifted[i] = lg_fft;
}

PolyComm[] storage bases = lagrange_bases[domain_size];
PolyCommFlat storage bases_unshifted = lagrange_bases_unshifted[domain_size];
bases_unshifted.unshifted_length = unshifted.length;

for (uint i = 0; i < domain_size; i++) {
for (uint j = 0; j < unshifted.length; j++) {
bases[i].unshifted.push(unshifted[j][i]);
bases_unshifted.unshifteds.push(unshifted[j][i]);
}
}
}
69 changes: 37 additions & 32 deletions demo/eth_verifier/src/Fields.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ library Base {
}
}
}
import "forge-std/console.sol";

/// @notice Implements 256 bit modular arithmetic over the scalar field of bn254.
library Scalar {
Expand All @@ -88,7 +89,7 @@ library Scalar {
21888242871839275222246405745257275088548364400416034343698204186575808495617;

uint256 public constant TWO_ADIC_PRIMITIVE_ROOT_OF_UNITY =
11026779196025039675543067535165575398706865421176733435921293210460577938844;
19103219067921713944291392827692070036145651957329286315305642004821462161904;
uint256 public constant TWO_ADICITY = 28;

function from(uint n) public pure returns (FE) {
Expand Down Expand Up @@ -117,9 +118,9 @@ library Scalar {
res = mul(self, self);
}

function inv(FE self) public pure returns (FE) {
(uint gcd, uint inverse) = Aux.xgcd(FE.unwrap(self), MODULUS);
require(gcd == 1);
function inv(FE self) public view returns (FE) {
(uint inverse, uint gcd) = Aux.xgcd(FE.unwrap(self), MODULUS);
require(gcd == 1, "gcd not 1");

return FE.wrap(inverse);
}
Expand Down Expand Up @@ -172,7 +173,7 @@ library Scalar {
// https://github.com/lambdaclass/lambdaworks/
function get_primitive_root_of_unity(
uint order
) public pure returns (FE) {
) public view returns (FE root) {
if (order == 0) {
return FE.wrap(1);
}
Expand All @@ -186,52 +187,56 @@ library Scalar {
root = square(root);
}

require(FE.unwrap(pow(root, order)) == 1, "not a root of unity");
return root;
require(FE.unwrap(pow(root, 1 << order)) == 1, "not a root of unity");
}
}

library Aux {

/// @notice Extended euclidean algorithm. Returns [gcd, Bezout_a]
/// @notice so gcd = a*Bezout_a + b*Bezout_b.
/// @notice source: https://www.extendedeuclideanalgorithm.com/code
function xgcd(
uint a,
uint b
) public pure returns (uint s1, uint t1) {
uint r1 = a;
uint r2 = b;
s1 = 1;
t1 = 0;
uint s2 = 0;
uint t2 = 1;
) public pure returns (uint s0, uint t0) {
uint r0 = a;
uint r1 = b;
s0 = 1;
uint s1 = 0;
t0 = 0;
uint t1 = 1;

uint n = 0;
while (r2 > 0) {
uint q = r1 / r2;
r1 = r1 > q*r2 ? r1 - q*r2 : q*r2 - r1; // abs
s1 = s1 + q*s2;
while (r1 > 0) {
uint q = r0 / r1;
r0 = r0 > q*r1 ? r0 - q*r1 : q*r1 - r0; // abs

// swap r0, r1
uint temp = r0;
r0 = r1;
r1 = temp;

s0 = s0 + q*s1;

// swap s1, s2
uint temp = s1;
s1 = s2;
s2 = temp;
// swap s0, s1
temp = s0;
s0 = s1;
s1 = temp;

t1 = t1 + q*t2;
t0 = t0 + q*t1;

// swap t1, t2
temp = t1;
t1 = t2;
t2 = temp;
// swap t0, t1
temp = t0;
t0 = t1;
t1 = temp;

n += 1;
n++;
}

if (n % 2 > 0) {
s1 = b - s1;
if (n % 2 != 0) {
s0 = b - s0;
} else {
t1 = a - t1;
t0 = a - t0;
}
}
}
34 changes: 20 additions & 14 deletions demo/eth_verifier/src/Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ library Utils {
function get_twiddles(uint order) public view returns (Scalar.FE[] memory twiddles) {
Scalar.FE root_inv = Scalar.get_primitive_root_of_unity(order).inv();

for (uint i = 0; i < 1 << (order - 1); i++) {
uint size = 1 << (order - 1);
twiddles = new Scalar.FE[](size);
for (uint i = 0; i < size; i++) {
twiddles[i] = root_inv.pow(i);
}
}
Expand All @@ -83,7 +85,7 @@ library Utils {
/// @notice reverses the `log2(size)` first bits of `i`
function bit_reverse(uint i, uint size) public pure returns (uint) {
if (size == 1) return i;
return UtilsExternal.reverseEndianness(i) >> (256 - log2(size));
return UtilsExternal.reverseEndianness(i) >> (256 - max_log2(size));
}

/// @notice runs inverse FFT for BN254.
Expand All @@ -106,32 +108,36 @@ library Utils {
/// @notice returns true if n is a power of two.
function is_power_of_two(uint256 n) public pure returns (bool) {
do {
if (n == 1) return true;
if (n == 2) return true;
n /= 2;
} while (n % 2 == 0);

return false;
}

/// @notice returns the binary logarithm of n.
function log2(uint256 n) public pure returns (uint256 res) {
/// @notice returns the next power of two of n, or n if it's already a pow of two,
// and the order.
function next_power_of_two(uint256 n) public pure returns (uint res, uint order) {
res = n - 1;
for (uint i = 1; i < 256; i *= 2) {
res |= res >> i;
}
res = res + 1;
order = trailing_zeros(res);
}

/// @notice returns the next power of two of n, or n if it's already a pow of two,
// and the order.
function next_power_of_two(uint256 n) public pure returns (uint256 res, uint256 pow) {
if (is_power_of_two(n)) {
return (n, log2(n));
/// @notice returns the trailing zeros of n.
function trailing_zeros(uint256 n) public pure returns (uint i) {
i = 0;
while (n & 1 == 0) {
n >>= 1;
i++;
}
pow = log2(n) + 1;
res = 1 << pow;
}

require(is_power_of_two(res));
require(res > n);
/// @notice returns the log2 of the next power of two of n.
function max_log2(uint256 n) public pure returns (uint log) {
(uint _res, uint log) = next_power_of_two(n);
}

/// @notice returns the odd and even terms of the `points` array.
Expand Down
7 changes: 4 additions & 3 deletions demo/eth_verifier/src/Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ contract KimchiVerifier {
uint256 max_poly_size
) {
for (uint i = 0; i < g.length; i++) {
verifier_index.urs.g[i] = g[i];
verifier_index.urs.g.push(g[i]);
}
verifier_index.urs.h = h;
calculate_lagrange_bases(g, h, domain_size, verifier_index.urs.lagrange_bases);
calculate_lagrange_bases(g, h, domain_size, verifier_index.urs.lagrange_bases_unshifted);
verifier_index.public_len = public_len;
verifier_index.domain_size = domain_size;
verifier_index.max_poly_size = max_poly_size;
Expand Down Expand Up @@ -129,10 +129,11 @@ contract KimchiVerifier {
if (public_inputs.length != verifier_index.public_len) {
revert IncorrectPublicInputLength();
}
PolyComm[] memory lgr_comm = verifier_index.urs.lagrange_bases[
PolyCommFlat memory lgr_comm_flat = verifier_index.urs.lagrange_bases_unshifted[
verifier_index.domain_size
];
PolyComm[] memory comm = new PolyComm[](verifier_index.public_len);
PolyComm[] memory lgr_comm = poly_comm_unflat(lgr_comm_flat);
// INFO: can use unchecked on for loops to save gas
for (uint256 i = 0; i < verifier_index.public_len; i++) {
comm[i] = lgr_comm[i];
Expand Down
4 changes: 3 additions & 1 deletion demo/eth_verifier/test/Integration.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "../src/BN254.sol";
import "../src/Verifier.sol";
import "../src/msgpack/Deserialize.sol";
import "../src/Commitment.sol";
import "../src/Fields.sol";

contract DeserializeTest is Test {
function test_partial_verify() public {
Expand All @@ -16,6 +17,7 @@ contract DeserializeTest is Test {
(BN254.G1Point[] memory g, BN254.G1Point memory h, uint256 _i) = MsgPk
.deserializeURS(urs_serialized);

//KimchiVerifier verifier = new KimchiVerifier(g, h, 0, 32, 32);
KimchiVerifier verifier = new KimchiVerifier(g, h, 0, 32, 32);
verifier.partial_verify(new Scalar.FE[](0));
}
}

0 comments on commit 2c79349

Please sign in to comment.