personaelabs / spartan-ecdsa

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

The constraints on T in eff_ecdsa.circom are insufficient. #47

Open Subway2023 opened 6 days ago

Subway2023 commented 6 days ago

Bug audit report says input signal s is not constrained in eff_ecdsa.circom. Based on my tests, I believe there is insufficient constraint on T.

I set s to 0 and varied T, and ultimately found that sMultT is not 0, and the output pubKey does not equal U. This result contradicts the comments in the code.

When I set Tx and Ty to 0, regardless of the value of s, the outputs are pubKeyX = Ux and pubKeyY = Uy.

template EfficientECDSA() {
    var bits = 256;
    signal input s;
    signal input Tx; // T = r^-1 * R
    signal input Ty; 
    signal input Ux; // U = -(m * r^-1 * G)
    signal input Uy;

    signal output pubKeyX;
    signal output pubKeyY;

    // sMultT = s * T
    component sMultT = Secp256k1Mul();
    sMultT.scalar <== s;
    sMultT.xP <== Tx;
    sMultT.yP <== Ty;

    // pubKey = sMultT + U 
    component pubKey = Secp256k1AddComplete();
    pubKey.xP <== sMultT.outX;
    pubKey.yP <== sMultT.outY;
    pubKey.xQ <== Ux;
    pubKey.yQ <== Uy;

    log("the value of s: ",s);
    log("the value of sMultT.outX: ",sMultT.outX);
    log("the value of sMultT.outY: ",sMultT.outY);

    pubKeyX <== pubKey.outX;
    pubKeyY <== pubKey.outY;
}

Test for s

input0

input.json

{
    "s": 0,
    "Tx": 8,
    "Ty": 9,
    "Ux": 3,
    "Uy": 4
}

public.json

[
 "7805858560854569819918975737687721771085126966751833164347832040877563070443",
 "16988790562614459202550337482205732142865207045186758803081396539830677481293"
]

input1

input.json

{
    "s": 0,
    "Tx": 1,
    "Ty": 2,
    "Ux": 3,
    "Uy": 4
}

public.json

[
 "14105996747538665747038049000821378756510778545708046207861391876868245570302",
 "11208388174384675725594554820360477132639829119066243891901010234274989220235"
]

Analyse

I think the above two sets of inputs should yield the same output, but the results do not match.