I'm new to cryptography and I've recently been studying BLS signatures. Please forgive me if I make any mistakes while writing.
I've tried generating a BLS key pair and using the private key to derive an Ethereum account and sign on-chain transactions. I used the 'mattrglobal' library to generate the BLS keys, and then passed the private key to the 'ethereumjs-wallet' library to derive an account.
const {
generateBls12381G2KeyPair,
} = require("@mattrglobal/node-bbs-signatures");
const {
default: { fromPrivateKey },
} = require("ethereumjs-wallet");
const keyPairTest = (async function () {
const keyPair = await generateBls12381G2KeyPair();
const wallet = fromPrivateKey(Buffer.from(keyPair.secretKey));
console.log(`secretKey: ${Buffer.from(keyPair.secretKey).toString("hex")}`);
console.log(`ethereum address: ${wallet.getAddressString()}`);
})();
Even though I was able to derive an Ethereum public key, I didn't expect to be able to sign valid Ethereum transactions, because I thought that the different curve parameters would prevent me from generating valid signatures for the transactions.
However, by directly using the private key on MetaMask (on the Sepolia testnet), I was able to perform a simple fund transfer transaction and deploy a smart contract.
How is this possible? Am I overlooking something?
It seems to me that it is generally not recommended to use the same key for two different types of signatures, is that correct?
Best Answer
Short answer: yes.
Why is this possible? Because the space in which the private keys live for BLS signatures on BLS12-381 is smaller than that in which keys for ECDSA over secp256k1 live.
Breaking it down
If we follow the code from
generateBls12381G2KeyPair
function we see that it usesgen_sk
to generate the private key, which creates a random element of the fieldGF(r)
wherer
is the prime order of the groups in the pairing construction for BLS12-381 (the private key is essentially a random number in the range [0,r-1]).On the other hand, if we follow the code from
fromPrivateKey
we see that the private key for Ethereum must be in the range [0,n] where n is the order of the elliptic curve group for secp256k1.Comparing the 2 numbers we see that clearly
n>r
so the validation checks infromPrivateKey
will pass.I wouldn't recommend it because (AFAIK) there is no explicit security proof showing that one cannot use BLS & ECDSA signatures generated using the same private key to do things like forge new signatures or learn information about the private key. Having said that however, there is also no known way to do such attacks (again, AFAIK) so it's not publicly broken.