paulmillr / noble-curves

Audited & minimal JS implementation of elliptic curve cryptography.
https://paulmillr.com/noble
MIT License
621 stars 56 forks source link

Default bls12_381 is incompatible with Ethereum beacon chain #128

Closed xrchz closed 3 months ago

xrchz commented 3 months ago
import { bls12_381 } from '@noble/curves/bls12-381'
import { hexToBytes } from '@noble/curves/abstract/utils'
import bls from "@chainsafe/bls"

const pubkey = hexToBytes('93a2c542bd455386a15a0f1c39e0c49c35248938ab56a64f560c4233100e5ba821fef9fd43fcd0e2d591949ab7ff76fe')
const signature = hexToBytes('8ee17b62fb7a528774be685d9aa01e13167f14450fb5832a8003129291a739643c3362a033024a43c0ac6ef7476892a41438ac18ef2451ffa8679c0e7af6b88e64151b403149db0c9301648e0eb84a8b897b6659f0d8fb050ba8627c9c1c278a')
const message = hexToBytes('ae1738463cd0a4e2ce2289b338dd2c6f56bf7c576ae110b6f6315a297d4352cc')

console.log(`@noble says ${bls12_381.verify(signature, message, pubkey)}`)
console.log(`@chainsafe says ${bls.verify(pubkey, message, signature)}`)

outputs

@noble says true
@chainsafe says false

using

├── @chainsafe/bls@7.1.3
├── @noble/curves@1.3.0

Given that both are purporting to use BLS12-381, and the Chainsafe version is actually used on Ethereum, I suggest that the Noble version at least have a warning that the default configuration is not compatible with Ethereum (if indeed there is not a more nefarious bug).

xrchz commented 3 months ago

fwiw the same result occurs if I use the hexToBytes function from the Chainsafe repository

function hexToBytes(hex) {
    if (hex.startsWith("0x")) {
        hex = hex.slice(2);
    }
    if (hex.length & 1) {
        throw Error("hexToBytes:length must be even " + hex.length);
    }
    const n = hex.length / 2;
    const a = new Uint8Array(n);
    for (let i = 0; i < n; i++) {
        a[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
    }
    return a;
}
xrchz commented 3 months ago

Ethereum uses the following

The IETF BLS signature draft standard v4 with ciphersuite BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_ROPOP

Maybe the hash to curve algorithm is different in noble?

xrchz commented 3 months ago

I haven't had luck using BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_ as the DST option to noble's functions yet. But probably there's some other configuration needed?

paulmillr commented 3 months ago

They are compatible. Proof: https://github.com/paulmillr/bls12-381-keygen, readme example generates same keys.

For verification you need to specify DST or encodeDST correctly.

xrchz commented 3 months ago

So my claim is simply that the default configuration does not verify Ethereum signatures. I see now that the reason is the DST for Ethereum beacon chain differs from the noble curves default DST. My suggestion is to add this to the README and possibly include an example of using the Ethereum DST correctly.

The link you provided is about key generation, which is not precisely relevant to signature generation and verification.

paulmillr commented 3 months ago

I don’t know which DST is correct for eth. If you would like to clarify usage with eth, you can test it and add proper example to readme with pull request

xrchz commented 3 months ago

Thank you so much for your help. I created this https://github.com/paulmillr/noble-curves/pull/129.

paulmillr commented 3 months ago

1.4.0 is out