Merge pull request #51 from tornadocash/upstream
pass fixes size array arg in solidity poseidon implementation
This commit is contained in:
commit
45f190b445
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
const { unstringifyBigInts } = require("ffjavascript").utils;
|
const { unstringifyBigInts } = require("ffjavascript").utils;
|
||||||
|
const Web3Utils = require("web3-utils");
|
||||||
|
|
||||||
const { C:K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
const { C:K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
||||||
|
|
||||||
@ -99,8 +100,13 @@ function createCode(nInputs) {
|
|||||||
C.push(0);
|
C.push(0);
|
||||||
C.calldataload();
|
C.calldataload();
|
||||||
C.div();
|
C.div();
|
||||||
C.push("0xc4420fb4"); // poseidon(uint256[])
|
C.dup(0);
|
||||||
|
C.push(Web3Utils.keccak256(`poseidon(uint256[${nInputs}])`).slice(0, 10)); // poseidon(uint256[n])
|
||||||
C.eq();
|
C.eq();
|
||||||
|
C.swap(1);
|
||||||
|
C.push(Web3Utils.keccak256(`poseidon(bytes32[${nInputs}])`).slice(0, 10)); // poseidon(bytes32[n])
|
||||||
|
C.eq();
|
||||||
|
C.or();
|
||||||
C.jmpi("start");
|
C.jmpi("start");
|
||||||
C.invalid();
|
C.invalid();
|
||||||
|
|
||||||
@ -112,11 +118,10 @@ function createCode(nInputs) {
|
|||||||
|
|
||||||
// Load t values from the call data.
|
// Load t values from the call data.
|
||||||
// The function has a single array param param
|
// The function has a single array param param
|
||||||
// [Selector (4)] [Pointer (32)][Length (32)] [data1 (32)] ....
|
// [Selector (4)] [item1 (32)] [item2 (32)] ....
|
||||||
// We ignore the pointer and the length and just load t values to the state
|
// Stack positions 0-nInputs.
|
||||||
// (Stack positions 0-{t-1}) If the array is shorter, we just set zeros.
|
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.push(0x44+(0x20*(t-1-i)));
|
C.push(0x04+(0x20*(nInputs-i)));
|
||||||
C.calldataload();
|
C.calldataload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,28 +160,54 @@ function createCode(nInputs) {
|
|||||||
return C.createTxData();
|
return C.createTxData();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.abi = [
|
function generateABI(nInputs) {
|
||||||
{
|
return [
|
||||||
"constant": true,
|
{
|
||||||
"inputs": [
|
"constant": true,
|
||||||
{
|
"inputs": [
|
||||||
"name": "input",
|
{
|
||||||
"type": "uint256[]"
|
"internalType": `bytes32[${nInputs}]`,
|
||||||
}
|
"name": "input",
|
||||||
],
|
"type": `bytes32[${nInputs}]`
|
||||||
"name": "poseidon",
|
}
|
||||||
"outputs": [
|
],
|
||||||
{
|
"name": "poseidon",
|
||||||
"name": "",
|
"outputs": [
|
||||||
"type": "uint256"
|
{
|
||||||
}
|
"internalType": "bytes32",
|
||||||
],
|
"name": "",
|
||||||
"payable": false,
|
"type": "bytes32"
|
||||||
"stateMutability": "pure",
|
}
|
||||||
"type": "function"
|
],
|
||||||
}
|
"payable": false,
|
||||||
];
|
"stateMutability": "pure",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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;
|
module.exports.createCode = createCode;
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,15 +21,16 @@ describe("Poseidon Smart contract test", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should deploy the contract", async () => {
|
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)
|
data: poseidonGenContract.createCode(5)
|
||||||
}).send({
|
}).send({
|
||||||
gas: 5000000,
|
gas: 5000000,
|
||||||
from: accounts[0]
|
from: accounts[0]
|
||||||
});
|
});
|
||||||
poseidon3 = await C.deploy({
|
poseidon3 = await C3.deploy({
|
||||||
data: poseidonGenContract.createCode(2)
|
data: poseidonGenContract.createCode(2)
|
||||||
}).send({
|
}).send({
|
||||||
gas: 5000000,
|
gas: 5000000,
|
||||||
@ -37,7 +38,7 @@ describe("Poseidon Smart contract test", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
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();
|
const res = await poseidon6.methods.poseidon([1,2, 0, 0, 0]).call();
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ describe("Poseidon Smart contract test", function () {
|
|||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
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();
|
const res = await poseidon3.methods.poseidon([1,2]).call();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user