Skip to content

Commit

Permalink
Deserialize URS in EVM verifier (#121)
Browse files Browse the repository at this point in the history
* Up anvil's block gas limit

* Fixed verify script

* Negate quotient commitment

* Fix trusted setup length

* Added Fq2 sqrt operation (an others necessary)

* Fix fq2 sqrt typo

* Added comments to the fq2 sqrt algorithm

* Added fq2 sqrt test

* Fix FQ1EulerCriterion

* Fix FQ2Sqrt test

* Add import

* Added G2 decompression function

* Formatting

* Added test

* Fixed G2Deserialize

* Changed values order of deser test

* Remove else case

* Fixed deserializatio function

* Added messagepack g2 deserialization functions

* Added pairing urs deserialization

* Fixed G2 point multiplication

* Escape char
  • Loading branch information
xqft authored Jan 25, 2024
1 parent 1a26dec commit 4ec7386
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 19 deletions.
8 changes: 4 additions & 4 deletions eth_verifier/lib/bn254/BN256G2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,10 @@ library BN256G2 {
uint256 s,
BN254.G2Point memory p
) public view returns (BN254.G2Point memory) {
uint pxx = p.x1;
uint pxy = p.x0;
uint pyx = p.y1;
uint pyy = p.y0;
uint pxx = p.x0;
uint pxy = p.x1;
uint pyx = p.y0;
uint pyy = p.y1;

(uint rxx, uint rxy, uint ryx, uint ryy) = ECTwistMul(
s,
Expand Down
54 changes: 54 additions & 0 deletions eth_verifier/lib/msgpack/Deserialize.sol
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,60 @@ library MsgPk {
return BN256G2.G2Deserialize(deser_buffer(buffer));
}

// WARN: using the entire `full_urs` may not be necessary, we would only have to deserialize the
// first two points (in the final verification step, we need the `full_urs` for commitment a
// evaluation polynomial, which seems to be always of degree 1).
function deser_pairing_urs(Stream memory self, PairingURS storage urs) public {
// full_srs and verifier_srs fields
EncodedMap memory urs_map = deser_fixmap(self);

EncodedMap memory full_urs_serialized = abi.decode(find_value(urs_map, abi.encode("full_srs")), (EncodedMap));
EncodedMap memory verifier_urs_serialized =
abi.decode(find_value(urs_map, abi.encode("verifier_srs")), (EncodedMap));

// get data from g and h fields (g is an array of buffers and h is a buffer)
EncodedArray memory full_urs_g_serialized =
abi.decode(find_value(full_urs_serialized, abi.encode("g")), (EncodedArray));
EncodedMap memory full_urs_h_serialized =
abi.decode(find_value(full_urs_serialized, abi.encode("h")), (EncodedMap));

EncodedArray memory verifier_urs_g_serialized =
abi.decode(find_value(verifier_urs_serialized, abi.encode("g")), (EncodedArray));
EncodedMap memory verifier_urs_h_serialized =
abi.decode(find_value(verifier_urs_serialized, abi.encode("h")), (EncodedMap));

// deserialized and save g for both URS
// INFO: we only need the first two points
BN254.G1Point[] memory full_urs_g = new BN254.G1Point[](2);
for (uint256 i = 0; i < full_urs_g.length; i++) {
EncodedMap memory point_buffer = abi.decode(full_urs_g_serialized.values[i], (EncodedMap));
full_urs_g[i] = deser_g1point(point_buffer);
}

require(verifier_urs_g_serialized.values.length == 3, "verifier_urs doesn\'t have three elements");
BN254.G2Point[] memory verifier_urs_g = new BN254.G2Point[](3);
for (uint256 i = 0; i < verifier_urs_g.length; i++) {
EncodedMap memory point_buffer = abi.decode(verifier_urs_g_serialized.values[i], (EncodedMap));
verifier_urs_g[i] = deser_g2point(point_buffer);
}

// deserialized and save h for both URS
BN254.G1Point memory full_urs_h = deser_g1point(full_urs_h_serialized);
BN254.G2Point memory verifier_urs_h = deser_g2point(verifier_urs_h_serialized);

// store values
urs.full_urs.g = full_urs_g;
urs.full_urs.h = full_urs_h;

urs.verifier_urs.g = verifier_urs_g;
urs.verifier_urs.h = verifier_urs_h;

// deserialize and store lagrange bases
// EncodedMap memory lagrange_b_serialized =
// abi.decode(find_value(full_urs_serialized, abi.encode("lagrange_bases")), (EncodedMap));
// deser_lagrange_bases(lagrange_b_serialized, urs.lagrange_bases_unshifted);
}

function deser_linearization(Stream memory self) public view returns (Linearization memory) {
// TODO: only constant_term is deserialized right now.
EncodedArray memory arr = deser_arr32(self);
Expand Down
4 changes: 3 additions & 1 deletion eth_verifier/script/Verify.s.sol

Large diffs are not rendered by default.

9 changes: 2 additions & 7 deletions eth_verifier/src/Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,12 @@ contract KimchiVerifier {
State internal state;
bool state_available;

function setup() public {
//MsgPk.deser_pairing_urs(MsgPk.new_stream(urs_serialized), urs);
// INFO: currently we aren't deserializing the trusted setup from the prover.
// this is because the full_srs is too big. Recently we found that we actually
// don't need the full_srs for verification.
function setup(bytes memory urs_serialized) public {
MsgPk.deser_pairing_urs(MsgPk.new_stream(urs_serialized), urs);

// x is a seed used in the KZG prover for creating the trusted setup.
Scalar.FE x = Scalar.from(42);
uint256 max_domain_size = 16384;
urs.full_urs = create_trusted_setup(x, max_domain_size);
urs.verifier_urs = create_trusted_setup_g2(x, 3);

verifier_index.powers_of_alpha.register(ArgumentType.GateZero, 21);
verifier_index.powers_of_alpha.register(ArgumentType.Permutation, 3);
Expand Down
6 changes: 4 additions & 2 deletions eth_verifier/test/Integration.t.sol

Large diffs are not rendered by default.

8 changes: 3 additions & 5 deletions eth_verifier/test/State.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ contract StateTest is Test {
KimchiVerifier verifier;

function setUp() public virtual {
// Initialize contract. Code was taken from integration test
// bytes
// memory urs_serialized = hex"92dc0020c4200100000000000000000000000000000000000000000000000000000000000000c42055a8e8d2b2221c2e7641eb8f5b656e352c9e7b5aca91da8ca92fe127e7fb2c21c42003bc09f3825fafdefe1cb25b4a296b60f2129a1c3a90826c3dc2021be421aa8ec4206422698aa4f80a088fd4e0d3a3cd517c2cb1f280cb95c9313823b8f8060f1786c4203558cb03f0cf841ed3a8145a7a8084e182731a9628779ef59d3bc47bae8a1192c4202ac41dd231cb8e97ffc3281b20e6799c0ae18afc13d3de1b4b363a0cd070baa7c420b6205dfa129f52601adfd87829901f06f1fd32e22a71f44b769d674448f05d83c4205d1b9b83cdcba66ff9424c7242c67394d7956dabf5407f4105124b7239d43e80c420e95ffc0999a8997b045430aa564c7bd9a25303e8a5ebbe4a99f6329b7f2a64aac4206cca50f1237f867fee63ac65249d6911494680f42d0e71386b1586be39092f9cc4204b9b17d64b384a65d7c80c8ab0f5fff75c69fd147835599753beea03152a3923c4205c0f706b036ed361e787af70acea3533d6e349869e83368979fdbbf382a4900bc420da6652a81754a6263e677d23a55bd729205f5fb64fa39b6771d9b811e5548bafc4208db1ad69d758362a4ecacff98a6910a95b3c2697e455271b2d7c078f1894eb1fc42010f56f1046a1121b1df5c401969b5acbf80eef8bfd5438270e09243413382788c4200cca37d1a3a721792dc232bb6a95bd14143350b6784bcdd4898a0bb34dd8bd2cc4202b7a1991e05b77d911d15ae590ff6f6ad7d1ed572b34654e3ce92e38e4839425c4201977ca4631e9eea53c7ba59d334c14dac7ee1071d6bf6ebf2ab7450c16975d23c4209eb742379ee8664a8bf9c18a40a534bb2961020bd0077cd0b603d2a8b9fe5a17c4201c50af6002db8dfa5a310ce795dcb06de94ead6687687263fd59acbc8612f180c4205241cbed55fbe1193f366e7ea8ad11bc97742eb35ca39129c4931b9bef64df1ec420646e69eb7d4682ad6bff24d40bf22184694c569246385cc127b3ec4a99875a85c42046b77ed1e120130743344ea9372ea58118604c730800e0d7038f2c80211f4f90c4208f20f3c39a09b5615bd8b2a09eec7dbc11b5ea1f8fe7eb0d5a69c1264412d199c42095f0b87ed771c169a8b6c0a6e21b13ab715407a4e6637a0b8fe0a1e3278f32a7c420a80440e1a07157bad23d7a7d3ddd7445f578021650016fc4bfb3324ed967c82bc4202b94fd0b89e7e2c9d245a4e94a539b14c5db26ed5ba4b3989ef0ba0712d4582ec42068f583079aa73425184a328127be63421eae683a25be94a0aa697ce74b5b972dc4209fa10b770e452852612ea392b8521683999d0a168c5eb85a6925d1ffe21d418ac420826a0976821c9309ed896678a97634a2fb1392a64ab8c59c8380012ffb601189c4203096ba3ed0b597fa29da6caa9000a409702b1f945561e82d02ab77b0cfdb649fc4204a718bc27174d557e036bcbcb9874ce5a6e1a63ccbe491e509d4201bfcb50806c420723737cf1cc96bb40021504a4ff45d21914e9484f2113d66545a3826919a9c250a";

bytes memory urs_serialized =
hex"82A866756C6C5F73727382A1679382A474797065A6427566666572A464617461DC0020010000000000000000000000000000000000000000000000000000000000000082A474797065A6427566666572A464617461DC0020343FCC9B2FCC88177D5317CCC5CCE46D58775535CCFBCCF727CCAECCFDCC9ACC8F7CCCD71FCC97CCB65DCCF3CC88CC8982A474797065A6427566666572A464617461DC00204A43CCA4CC91CCBECCFACCA9CCF4CC8307CCAB053DCCE15301CC8904CC885BCCB27ECC8F547A4E1FCCD0CC8BCC864B0DA16882A474797065A6427566666572A464617461DC0020723737CCCF1CCCC96BCCB40021504A4FCCF45D21CC914ECC94CC84CCF2113D66545A3826CC91CC9ACC9C25AC76657269666965725F73727382A1679382A474797065A6427566666572A464617461DC0040CCEDCCF6CC92CCD95CCCBDCCDE46CCDDCCDA5ECCF7CCD422436779445C5E66006A42761E1F12CCEFCCDE0018CCC212CCF3CCAECCB7CC85CCE4CC9712CCE7CCA9353349CCAACCF1255DCCFB31CCB7CCBF60723A480DCC92CC93CC93CC8E1982A474797065A6427566666572A464617461DC0040CCE7CCE6CCAFCC991BCC936DCCD662CCCACCAE0472CCBA13CC801C5F3ACCA3CCAD44CC863D0F090DCC9ACCC8CCA86D11CC91CC9A5606733ACC9E0630CCA5CCE2CCD0CCB1670DCCE93CCCE8CCCC6FCCB0496A7BCCB715CC96CCBA340974CC9282A474797065A6427566666572A464617461DC0040CCA50DCCF21272CCDA0FCC9044CCEACCE527CCA975CCCC3619CCD5CCEB45CCA57A7B3203472A20CCCB073C1FCCF74FCCF90657CCBDCCBECCE361CCD2CC90CCFACCB566CCF5CC8FCCC8CC921F7646CC8DCCEF43CC94CCB6611D25CC9242CC8AA16882A474797065A6427566666572A464617461DC00406959CCBECCF6615463CCA54CCCA6CCC72DCCFCCCD02B6B77CC9ECCDE23400D55CCB043CC984B2206CC92012A00CCF4CCA9CCF6CCBDCCB1CCD34ECCD1CCA57C0E4140CCA0CCCFCCF3CCEFCCB0CCCE24CC844CCCC6CCEDCC9DCCA8CCFC573ECC982D";
verifier = new KimchiVerifier();
verifier.setup();
verifier.setup(urs_serialized);
}

function test_verify_retrieve() public {
Expand Down

0 comments on commit 4ec7386

Please sign in to comment.