Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poseidon Solidity and JS produce different outputs given the same inputs #30

Open
Arinerron opened this issue Nov 22, 2024 · 2 comments

Comments

@Arinerron
Copy link

Arinerron commented Nov 22, 2024

In circomlibjs version 0.1.7, the generated Solidity code and JS functions for poseidon produce a different hash for the same input. Hardhat running with solc version 0.8.27 if that matters.

    async initialize() {
        // deploy hash contracts

        let poseidon2Factory = new ethers.ContractFactory(
            poseidonContract.generateABI(2),
            poseidonContract.createCode(2),
            this.owner
        );
        this.poseidon2 = await poseidon2Factory.deploy();


        // test it
        
        let onchainP2Result = ethers.toBigInt(await this.poseidon2['poseidon(uint256[2])']([1, 2]));
        let offchainP2Result = ethers.toBigInt((await buildPoseidon(2))([1, 2]));
        if (onchainP2Result !== offchainP2Result) {
            console.log(onchainP2Result, offchainP2Result);
            throw new Error('Poseidon2 test failed', {onchainP2Result, offchainP2Result});
        }
    }

I saw issue #13, but:

  • it's talking about circom vs JS (not Solidity vs JS)
  • for that bug, it seems to be outputting the same hashes, just with different return types. For this bug, the functions output entirely different bytes.

Please let me know if you need any help reproducing this. I actually can't get the two implementations to output the same hash at all.

@Arinerron
Copy link
Author

Arinerron commented Nov 23, 2024

Also tested with circomlibjs 0.1.6. Same result.

poseidon2 of [1, 2] is (bigint):

  • onchain (Solidity): 7853200120776062878684798364095072458815029376092732009249414926327459813530n
  • offchain (JS): 53742210201261010786651533977371650068498129444170938640721811794703579322377n

@Arinerron
Copy link
Author

It was a pain adapting the code, but downgrading to 0.0.8 worked for me. Here's my hacky code to temporarily adapt interfaces from 0.1.7 to 0.0.8.

Replace this:

const { buildPoseidon, buildMimcSponge } = require('circomlibjs');

With this:

const {
    poseidon_gencontract,
    mimcsponge_gencontract,
    poseidon,
    mimcsponge
} = require('circomlibjs');
let poseidonContract = poseidon_gencontract;
let mimcSpongecontract = mimcsponge_gencontract;
let buildPoseidon = async (nRounds) => {
    return poseidon;
}
let buildMimcSponge = async (nRounds, seed) => {
    return mimcsponge;
}
const Scalar = require("ffjavascript").Scalar
const ZqField = require("ffjavascript").ZqField;
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
mimcsponge.F = F;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant