Skip to content

Signature::fromHex wrong in 1.3.0 #124

@randombit

Description

@randombit

I think 2f1460a introduced a bug into Signature::fromHex, in this part of the change:

-       const z1 = bytesToNumberBE(hex.slice(0, half));
-       const z2 = bytesToNumberBE(hex.slice(half));
+       const z1 = bytesToNumberBE(value.slice(0, half));
+       const z2 = bytesToNumberBE(value.slice(half));

Here half is hex.length / 2, aka the number of bytes encoded in hex. This is the same as the full length of value, so the slices are wrong.

I repro'd using this test

    should(`this work`, () => {
      const pk = 'a7623a93cdb56c4d23d99c14216afaab3dfd6d4f9eb3db23d038280b6d5cb2caaee2a19dd92c9df7001dede23bf036bc0f33982dfb41e8fa9b8e96b5dc3e83d55ca4dd146c7eb2e8b6859cb5a5db815db86810b8d12cee1588b5dbf34a4dc9a5';

        const sig = 'b89e13a212c830586eaa9ad53946cd968718ebecc27eda849d9232673dcd4f440e8b5df39bf14a88048c15e16cbcaabe';
        const msg = '68656C6C6F';

        deepStrictEqual(bls.verifyShortSignature(sig, msg, pk), true);
    });

This is a valid signature (at least according to both zkcrypto/bls12_381 and MIRACL) but the public key is rejected as not being in the subgroup.

This seems to fix it

-        const z1 = bytesToNumberBE(value.slice(0, half));
-        const z2 = bytesToNumberBE(value.slice(half));
+        const z1 = bytesToNumberBE(value.slice(0, half/2));
+        const z2 = bytesToNumberBE(value.slice(half/2));

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions