Skip to content

bn128's Fr.mul gives unexpected result #98

@dezhic

Description

@dezhic

Hi! The library returns a seemingly wrong value for the multiplication in bn128 Fr.

Here's an example: (I assumed that it's using little endian)
It gives 21005330981446606953608831075862683397340720297895507971069995954406343750754 while I'm expecting 19138581828712882593908706925461583697567205063300498062599267069621213248340.

Both the online calculator and the circom's * operation give the expected result.

const ffjavascript = require("ffjavascript");

async function checkBn128() {
        const a =
                5299619240641551281634865583518297030282874472190772894086521144482721001553n;
        const b =
                16950150798460657717958625567821834550301663161624707787222815936182638968203n;

        const bn128 = await ffjavascript.getCurveFromName("bn128", true);
        const cBuf = bn128.Fr.mul(
                newBufferFromBigUInt256LE(a),
                newBufferFromBigUInt256LE(b)
        );
        const c = readBigUInt256LE(cBuf);
        // WRONG RESULT FOR c
        // Expecting 19138581828712882593908706925461583697567205063300498062599267069621213248340
        // reference: https://planetcalc.com/8326/
        //   circomlib BabyAdd also gives the same result.
        console.log("c:");
        console.log(c);
}

checkBn128();

/* util functions */
function readBigUInt256LE(buffer) {
        var value = 0n;
        for (var i = 0; i < 32; i++) {
                value += BigInt(buffer[i]) << BigInt(i * 8);
        }
        return value;
};

function newBufferFromBigUInt256LE(value) {
        var buffer = Buffer.alloc(32);
        for (var i = 0; i < 32; i++) {
                buffer[i] = Number(value & 0xffn);
                value = value >> 8n;
        }
        return buffer;
};

/* util function tests */
function testNewBufferFromBigUInt256LE() {
        const a =
                5299619240641551281634865583518297030282874472190772894086521144482721001553n;
        const aBuf = newBufferFromBigUInt256LE(a);
        console.log('a buffer');
        console.log(aBuf);
        // expecting 51, 70, 95, BB, F6, F3, 93, 28, B6, E0, 34, 05, 01, D8, B8, 2A, C1, 77, 62, 9D, E0, B2, AC, 4E, 9B, 73, 3E, D6, 6A, 7A, B7, 0B
        // reference: https://www.rapidtables.com/convert/number/decimal-to-hex.html
        return aBuf;
}

function testReadBigUInt256LE() {
        const aPrime = readBigUInt256LE(testNewBufferFromBigUInt256LE());
        console.log("aPrime:");
        console.log(aPrime);
}

// testNewBufferFromBigUInt256LE();
// testReadBigUInt256LE();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions