Based on the following from ethereum-cryptography documentation:

Upgrading from 1.0 to 2.0:

secp256k1 module was changed massively: before, it was using noble-secp256k1 1.7; now it uses safer noble-curves. Please refer to upgrading section from curves README. Main changes to keep in mind: a) sign now returns Signature instance b) recoverPublicKey got moved onto a Signature instance

Although the signature is verified, I can't convert the returned object from sig.recoverPublicKey(msg) to the original publicKey hex format:

import { secp256k1 as secp } from 'ethereum-cryptography/secp256k1'
import { keccak256 as keccak } from 'ethereum-cryptography/keccak.js'
import { toHex, hexToBytes, utf8ToBytes } from 'ethereum-cryptography/utils'

const privateKey =
const publicKey =
const msg = 'Hello world!'
const msgByteArr = utf8ToBytes(msg)

const signature = secp.sign(keccak(msgByteArr), hexToBytes(privateKey))

const derivedPublicKey = signature.recoverPublicKey(toHex(msgByteArr))

console.log(secp.verify(signature, keccak(msgByteArr), publicKey)) //true
console.log(derivedPublicKey.toHex() === publicKey) //false!!!


3 Answers 3


below is how i retrieve the public key using secp256k1 module on version 2.0

    function hashMessage(message) {
      return keccak256(utf8ToBytes(message));

    async function signMessage(msg, privateKey) {
      return secp256k1.sign(msg, privateKey);

    async function tst() {
      let msg = "test";
      const privateKey = <PRIVATE_KEY>; 
      let sign = await signMessage(hashMessage(msg), privateKey);

      console.log("publicKey: ",sign.recoverPublicKey(hashMessage(msg)).toHex());

hope that works


Same question here.

I started Alchemy University, and the first project should consist of receiving the signature from the user and, with that recovering the public key to be able to move funds for a particular address.

However, having the following signature, I am not able to retrieve the public key:

signature Signature {
  r: 47280888384242497109439486996523476252709515294379363283793036907373634667272n,
  s: 14094496101796106978990081669744084584839684113670443481146858170562046119959n,
  recovery: 1

Hopefully, someone can help with this newbie question :)

You have forgotten to hash your message before passing it into the recoverPublicKey() method. Modify to:

const derivedPublicKey = signature.recoverPublicKey(toHex(keccak(msgByteArr)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.