personaelabs / spartan-ecdsa

The fastest in-browser verification of ECDSA signatures in ZK, using Spartan on the secq256k1 curve
203 stars 28 forks source link

Prime field convert #43

Closed Yiheng-Liu closed 12 months ago

Yiheng-Liu commented 12 months ago

Hi, currently, I use circom-secq to compile the circom file, and use snarkjs to generate witness, prove, and the verify contract. However, I found the data in public.json is different from the public data in my input.json. I think it might be the issue from secp256k1 field to bn254 field. I have tried mod bn254 field prime number directly from my input, the result shows the leading bits are the same, the diverge from some bits after. Could you please give me some suggestion, like a new tool instead of snarkjs, or add some new curve on snarkjs?

Yiheng-Liu commented 12 months ago

Cause the incompatiblity with snarkjs, I am now stuck right after generate witness, I have no idea how to setup zkey, how to generate proof, generate solidity code. I found in snarkjs there is a curve.js file, I think it might be work if I can add the secq256k1 curve in that file, if you can kindly give me the param for the curve should work as well. Below is the build function from snarkjs/curve.js:

async function buildBn128(singleThread, plugins) {

    const moduleBuilder = new wasmbuilder.ModuleBuilder();
    moduleBuilder.setMemory(25);
    wasmcurves.buildBn128(moduleBuilder);

    if (plugins) plugins(moduleBuilder);

    const bn128wasm = {};

    bn128wasm.code = moduleBuilder.build();
    bn128wasm.pq = moduleBuilder.modules.f1m.pq;
    bn128wasm.pr = moduleBuilder.modules.frm.pq;
    bn128wasm.pG1gen = moduleBuilder.modules.bn128.pG1gen;
    bn128wasm.pG1zero = moduleBuilder.modules.bn128.pG1zero;
    bn128wasm.pG1b = moduleBuilder.modules.bn128.pG1b;
    bn128wasm.pG2gen = moduleBuilder.modules.bn128.pG2gen;
    bn128wasm.pG2zero = moduleBuilder.modules.bn128.pG2zero;
    bn128wasm.pG2b = moduleBuilder.modules.bn128.pG2b;
    bn128wasm.pOneT = moduleBuilder.modules.bn128.pOneT;
    bn128wasm.prePSize = moduleBuilder.modules.bn128.prePSize;
    bn128wasm.preQSize = moduleBuilder.modules.bn128.preQSize;
    bn128wasm.n8q = 32;
    bn128wasm.n8r = 32;
    bn128wasm.q = moduleBuilder.modules.bn128.q;
    bn128wasm.r = moduleBuilder.modules.bn128.r;

    if ((!singleThread) && (globalThis.curve_bn128)) return globalThis.curve_bn128;
    const params = {
        name: "bn128",
        wasm: bn128wasm,
        q: e("21888242871839275222246405745257275088696311157297823662689037894645226208583"),
        r: e("21888242871839275222246405745257275088548364400416034343698204186575808495617"),
        n8q: 32,
        n8r: 32,
        cofactorG2: e("30644e72e131a029b85045b68181585e06ceecda572a2489345f2299c0f9fa8d", 16),
        singleThread: singleThread ? true : false
    };

    const curve = await buildEngine(params);
    curve.terminate = async function () {
        if (!params.singleThread) {
            globalThis.curve_bn128 = null;
            await this.tm.terminate();
        }
    };

    if (!singleThread) {
        globalThis.curve_bn128 = curve;
    }

    return curve;
}
Yiheng-Liu commented 12 months ago

Now I use snarkjs bn128 to generate tau power, generate solidity code, generate proof and so on, the only thing I need to modify is mod 21888242871839275222246405745257275088548364400416034343698204186575808495617 when pass in the public input.