arnaucube
arnaucube/circomlibPublic Self-hosted repository
pass fixes size array arg in solidity poseidon implementation
Alexey peretsmobil@gmail.com
Mon, 26 Oct 2020 16:30:10 +0300
commit

1f9d0bd37fbfdea3f09ca706af17b95b59213537

parent

411a7d7576df02476c6f6310f66fef9c96e5daff

2 files changed, 37 insertions(+), 31 deletions(-)

jump to
M src/poseidon_gencontract.js → src/poseidon_gencontract.js

@@ -4,6 +4,7 @@ //

const Contract = require("./evmasm"); const { unstringifyBigInts } = require("ffjavascript").utils; +const Web3Utils = require("web3-utils"); const { C:K, M } = unstringifyBigInts(require("./poseidon_constants.json"));

@@ -99,7 +100,7 @@ C.push("0x0100000000000000000000000000000000000000000000000000000000");

C.push(0); C.calldataload(); C.div(); - C.push("0xc4420fb4"); // poseidon(uint256[]) + C.push(Web3Utils.keccak256(`poseidon(uint256[${nInputs}])`).slice(0, 10)); // poseidon(uint256[]) C.eq(); C.jmpi("start"); C.invalid();

@@ -112,11 +113,10 @@ C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q

// Load t values from the call data. // The function has a single array param param - // [Selector (4)] [Pointer (32)][Length (32)] [data1 (32)] .... - // We ignore the pointer and the length and just load t values to the state - // (Stack positions 0-{t-1}) If the array is shorter, we just set zeros. + // [Selector (4)] [item1 (32)] [item2 (32)] .... + // Stack positions 0-nInputs. for (let i=0; i<t; i++) { - C.push(0x44+(0x20*(t-1-i))); + C.push(0x04+(0x20*(nInputs-i))); C.calldataload(); }

@@ -155,28 +155,33 @@

return C.createTxData(); } -module.exports.abi = [ - { - "constant": true, - "inputs": [ - { - "name": "input", - "type": "uint256[]" - } - ], - "name": "poseidon", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "pure", - "type": "function" - } -]; +function generateABI(nInputs) { + return [ + { + "constant": true, + "inputs": [ + { + "internalType": `uint256[${nInputs}]`, + "name": "input", + "type": `uint256[${nInputs}]` + } + ], + "name": "poseidon", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "pure", + "type": "function" + } + ]; +} +module.exports.generateABI = generateABI; module.exports.createCode = createCode;
M test/poseidoncontract.js → test/poseidoncontract.js

@@ -21,15 +21,16 @@ accounts = await web3.eth.getAccounts();

}); it("Should deploy the contract", async () => { - const C = new web3.eth.Contract(poseidonGenContract.abi); + const C6 = new web3.eth.Contract(poseidonGenContract.generateABI(5)); + const C3 = new web3.eth.Contract(poseidonGenContract.generateABI(2)); - poseidon6 = await C.deploy({ + poseidon6 = await C6.deploy({ data: poseidonGenContract.createCode(5) }).send({ gas: 5000000, from: accounts[0] }); - poseidon3 = await C.deploy({ + poseidon3 = await C3.deploy({ data: poseidonGenContract.createCode(2) }).send({ gas: 5000000,

@@ -37,7 +38,7 @@ from: accounts[0]

}); }); - it("Shold calculate the poseidon correctly t=6", async () => { + it("Should calculate the poseidon correctly t=6", async () => { const res = await poseidon6.methods.poseidon([1,2, 0, 0, 0]).call();

@@ -48,7 +49,7 @@ // console.log("Ref: " + bigInt(res2).toString(16));

assert.equal(res.toString(), res2.toString()); }); - it("Shold calculate the poseidon correctly t=3", async () => { + it("Should calculate the poseidon correctly t=3", async () => { const res = await poseidon3.methods.poseidon([1,2]).call();