ethereum / js-ethereum-cryptography

Every cryptographic primitive needed to work on Ethereum, for the browser and Node.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error: recovery id invalid at Signature.recoverPublicKey

m-gunes opened this issue · comments

// Client

function signMessage(message, privateKey){
  const msgHash = keccak256(utf8ToBytes(message));
  const signature = secp256k1.sign(msgHash, privateKey); 
  console.log('signature', signature); // {r: 1234.., s:5677.., recovery: 1}
  return signature.toCompactHex();
}

The client sends the signature in hex format.

// Server

  const msgHash = keccak256(utf8ToBytes(String(amount)));
  const sig = secp256k1.Signature.fromCompact(signature);
  console.log("sig", sig); // {r: 1234.., s:5677.., recovery: undefined}
  const publicKey = sig.recoverPublicKey(msgHash).toRawBytes();

To recover the publicKey, after applying fromCompact function, the signature recovery property becomes undefined (expecting 1) and recoverPublicKey() throw error: recovery id invalid.

In this scenario I solved the problem in the server by adding the recovery bit.

 const sig = secp256k1.Signature.fromCompact(signature).addRecoveryBit(1);

I'm really not sure if this is a problem or if the way I'm sending signatures from client to server is correct. This is my first time using the library and I'm trying to learn more about it. Can someone tell me what's going on?

By the way, I would be happy if someone could share some documentations about the library. I couldn't find it.

The secp256k1 submodule provides a library for elliptic curve operations on
the curve secp256k1. For detailed documentation, follow README of noble-curves, which the module uses as a backend.

Here's the quote from README.

The recovery bit is not serialized by design, because it's not standard. So, you need to preserve recovery bit somewhere if you're transferring it with the signature. Ethereum usually has recovery bit specified in v value of transaction.