Skip to content

Commit

Permalink
Merge pull request #47 from 0xPolygonHermez/feature/update-snark-input
Browse files Browse the repository at this point in the history
update calculateSnarkInput to match pil-stark
  • Loading branch information
invocamanman authored Aug 5, 2022
2 parents 7d7d858 + 440469e commit 2f0c0fb
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 96 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@0xpolygonhermez/zkevm-commonjs",
"description": "Javascript library implementing common utilities for zkevm",
"version": "0.0.37",
"version": "0.0.38",
"main": "index.js",
"scripts": {
"setup": "npm i",
Expand Down
28 changes: 19 additions & 9 deletions src/contract-utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const ethers = require('ethers');
const { Scalar } = require('ffjavascript');
const { FrSNARK } = require('./constants');
const { sha256Snark, padZeros } = require('./utils');
const { string2fea } = require('./smt-utils');
const getPoseidon = require('./poseidon');

/**
* Compute globalHash for STARK circuit
Expand Down Expand Up @@ -55,7 +57,7 @@ function calculateStarkInput(
* @param {String} aggregatorAddress - Aggregator Ethereum address in hex string
* @returns {String} - sha256(globalHash, aggregatorAddress) % FrSNARK in hex encoding
*/
function calculateSnarkInput(
async function calculateSnarkInput(
currentStateRoot,
currentLocalExitRoot,
newStateRoot,
Expand All @@ -65,6 +67,9 @@ function calculateSnarkInput(
timestamp,
aggregatorAddress,
) {
const poseidon = await getPoseidon();
const { F } = poseidon;

const hashKeccak = calculateStarkInput(
currentStateRoot,
currentLocalExitRoot,
Expand All @@ -75,15 +80,20 @@ function calculateSnarkInput(
timestamp,
);

const hashSha256 = ethers.utils.soliditySha256(
['bytes32', 'address'],
[
hashKeccak,
aggregatorAddress,
],
// 20 bytes agggregator adsress
const strAggregatorAddress = padZeros((Scalar.fromString(aggregatorAddress, 16)).toString(16), 40);

// 8 bytes each field element
const feaHashKeccak = string2fea(F, hashKeccak);
const strFea = feaHashKeccak.reduce(
(previousValue, currentValue) => previousValue + padZeros(currentValue.toString(16), 16),
'',
);

return `0x${Scalar.mod(Scalar.fromString(hashSha256, 16), FrSNARK).toString(16).padStart(64, '0')}`;
// build final bytes sha256
const finalStr = strAggregatorAddress.concat(strFea);

return sha256Snark(finalStr);
}

/**
Expand Down
34 changes: 34 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
/* eslint-disable no-restricted-syntax */
const crypto = require('crypto');
const { Scalar } = require('ffjavascript');
const { FrSNARK } = require('./constants');

/**
* Log2 function
* @param {Number} V - value
Expand Down Expand Up @@ -48,8 +52,38 @@ function hexString2byteArray(_hex) {
return byteArray;
}

/**
* Pad a string hex number with 0
* @param {String} str - String input
* @param {Number} length - Length of the resulting string
* @returns {String} Resulting string
*/
function padZeros(str, length) {
if (length > str.length) {
str = '0'.repeat(length - str.length) + str;
}

return str;
}

/**
* (Hash Sha256 of an hexadecimal string) % (Snark field)
* @param {String} str - String input in hexadecimal encoding
* @returns {Scalar} Resulting sha256 hash
*/
function sha256Snark(str) {
const hash = crypto.createHash('sha256')
.update(str, 'hex')
.digest('hex');
const h = Scalar.mod(Scalar.fromString(hash, 16), FrSNARK);

return h;
}

module.exports = {
log2,
byteArray2HexString,
hexString2byteArray,
sha256Snark,
padZeros,
};
15 changes: 8 additions & 7 deletions test/contract-utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ describe('contractUtils', function () {
this.timeout(10000);
let testVector;

const expectedBatchHashData = '0xa4e1166ff3f7ecf8c8ff3049fc2e28b03091d3bf0db4bce702d954840196f79d';
const expectedSnarkInputHash = '0x0b0a9c614cdc5473f2a9251d171230e92e5ae31fab0b165b13586100dad3a2c0';
const expectedStarkHashExecutor = '0x73855bab378977b439591bdee0bbde9c1b1cf3f48e20418da906ab7abfcc42cf';
const expectedBatchHashData = '0x9370689d3c20a5a4739f902a31e2ea20c7d7be121a0fc19468a2e1b5d87f4111';
// input taken from pil-stark
const expectedSnarkInputHash = '14918438705377636817563619860509474434188349281706594260803853913155748736842';
const expectedStarkHashExecutor = '0xd072c5e95f2a1aa8dee6f1e0667f72f9e66ed47f7ff5f5e3ad6f504379c73c26';

before(async () => {
testVector = JSON.parse(fs.readFileSync(path.join(pathTestVectors, 'inputs-executor/input_0.json')));
testVector = JSON.parse(fs.readFileSync(path.join(pathTestVectors, 'inputs-executor/input_executor.json')));
});

it('calculateBatchHashData', async () => {
Expand All @@ -34,7 +35,7 @@ describe('contractUtils', function () {
});

it('calculateSnarkInput', async () => {
const aggregatorAddress = '0x123456789ABCDDEF123456789ABCDDEF12345678';
const aggregatorAddress = '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266';

const {
oldLocalExitRoot,
Expand All @@ -45,7 +46,7 @@ describe('contractUtils', function () {
timestamp,
} = testVector;

const computedGlobalHash = await contractUtils.calculateSnarkInput(
const computedSnark = await contractUtils.calculateSnarkInput(
oldStateRoot,
oldLocalExitRoot,
newStateRoot,
Expand All @@ -56,7 +57,7 @@ describe('contractUtils', function () {
aggregatorAddress,
);

expect(computedGlobalHash).to.be.equal(expectedSnarkInputHash);
expect(computedSnark.toString()).to.be.equal(expectedSnarkInputHash.toString());
});

it('calculateStarkInput', async () => {
Expand Down
79 changes: 0 additions & 79 deletions test/helpers/test-vectors/inputs-executor/input_0.json

This file was deleted.

80 changes: 80 additions & 0 deletions test/helpers/test-vectors/inputs-executor/input_executor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"oldStateRoot": "0x2dc4db4293af236cb329700be43f08ace740a05088f8c7654736871709687e90",
"db": {
"0x2dc4db4293af236cb329700be43f08ace740a05088f8c7654736871709687e90": [
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0d1f0da5a7b620c8",
"43fd1e18e59fd724",
"d428d25da0cb1888",
"e31f5542ac227c06",
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0000000000000000"
],
"0xe31f5542ac227c06d428d25da0cb188843fd1e18e59fd7240d1f0da5a7b620c8": [
"ed22ec7734d89ff2",
"b2e639153607b7c5",
"42b2bd6ec2788851",
"b781932941084783",
"3e63658ee0db910d",
"0b3e34316e81aa10",
"e0dc203d93f4e3e5",
"e10053d0ebc64602",
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0000000000000000"
],
"0xb78193294108478342b2bd6ec2788851b2e639153607b7c5ed22ec7734d89ff2": [
"16dde42596b907f0",
"49015d7e991a1528",
"94dd9dadd060910b",
"60b4d5e9af514018",
"b69b044f5e694795",
"f57d81efba5d4445",
"339438195426ad0a",
"3efad1dd58c2259d",
"0000000000000001",
"0000000000000000",
"0000000000000000",
"0000000000000000"
],
"0x3efad1dd58c2259d339438195426ad0af57d81efba5d4445b69b044f5e694795": [
"00000000dea00000",
"0000000035c9adc5",
"0000000000000036",
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0000000000000000",
"0000000000000000"
],
"0xe10053d0ebc64602e0dc203d93f4e3e50b3e34316e81aa103e63658ee0db910d": [
"66ee2be0687eea76",
"6926f8ca8796c78a",
"4c2f3e938869b82d",
"649e63bfe1247ba4",
"b69b044f5e694795",
"f57d81efba5d4445",
"339438195426ad0a",
"3efad1dd58c2259d",
"0000000000000001",
"0000000000000000",
"0000000000000000",
"0000000000000000"
]
},
"sequencerAddr": "0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D",
"batchL2Data": "0xee80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff88016345785d8a0000808203e880801cee7e01dc62f69a12c3510c6d64de04ee6346d84b6a017f3e786c7d87f963e75d8cc91fa983cd6d9cf55fff80d73bd26cd333b0f098acc1e58edb1fd484ad731b",
"newStateRoot": "0xbff23fc2c168c033aaac77503ce18f958e9689d5cdaebb88c5524ce5c0319de3",
"oldLocalExitRoot": "0x17c04c3760510b48c6012742c540a81aba4bca2f78b9d14bfd2f123e2e53ea3e",
"newLocalExitRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"globalExitRoot": "0x090bcaf734c4f06c93954a827b45a6e8c67b8e0fd1e0a35a1c5982d6961828f9",
"numBatch": 1,
"timestamp": 1944498031,
"contractsBytecode": {}
}

0 comments on commit 2f0c0fb

Please sign in to comment.