I am hoping to write a very simple program that accepts an ETH signature, ETH public key, and message --> determines if the signature is valid.

I found the following repo that looks to do what I want it to do, but I don't understand how it works... https://github.com/GuidoDipietro/solana-ed25519-secp256k1-sig-verification/tree/master

I am getting the ETH signature in the following format

  "input": {
    "keyNo": 1,
    "digest": "bcf83051a4d206c6e43d7eaa4c75429737ac0d5ee08ee68430443bd815e6ac05",
    "message": "010203"
  "signature": {
    "raw": {
      "r": "93137bc7bfeaa86e26c6a9bbd6fb8acdf73ed5fd232cc2be1a0714f583f04d2e",
      "s": "7f5d7c2461daf8649587c3c510fce05a74146cbe79341427065d0d878d154a1b",
      "v": 27
    "der": "304602210093137bc7bfeaa86e26c6a9bbd6fb8acdf73ed5fd232cc2be1a0714f583f04d2e02210080a283db9e25079b6a783c3aef031fa4469a702836148c14b97551054320f726",
    "ether": "0x93137bc7bfeaa86e26c6a9bbd6fb8acdf73ed5fd232cc2be1a0714f583f04d2e7f5d7c2461daf8649587c3c510fce05a74146cbe79341427065d0d878d154a1b1b"
  "publicKey": "046ca7458b4c8c4f9a196094bda5f01ac1e588f6604bc2f7a58ba4d1fa3c3cb9102720bdb43f73972ea3dfc1c6ab8a6cb7d14114765eb76ff0fb2df34a5f7cab56",
  "etherAddress": "0x1aaBF638eC3c4A5C2D5cD14fd460Fee2c364c579"

and will pass some or all of these values to the program.

I found these two native program which could be helpful, but I don't understand how to use them: https://docs.solana.com/developing/runtime-facilities/programs#ed25519-program https://docs.solana.com/developing/runtime-facilities/programs#secp256k1-program

Any and all guidance will be hugely appreciated.

1 Answer 1


All of the information you need should be provided at the source code for the instruction: https://github.com/solana-labs/solana/blob/a099c7a0b8ac4281dbc6dd422d697e700c28a7d1/sdk/program/src/secp256k1_recover.rs#L399

With the signature and message, you can run:

     let recovered_pubkey = secp256k1_recover(
         // input.digest as bytes here
         // "v" here
         // concatenated bytes of "r" and "s" here
     .map_err(|_| ProgramError::InvalidArgument)?;

And then compare the recovered_pubkey to the expected pubkey.

  • Thanks for the explanation help! follow up question... how do I compare the inputted public key (publicKey or etherAddress) to the recovered_pubkey? They all have different byte lengths... I assume I need to figure out how to convert the publicKey or etherAddress from input to a 64 byte array to match the recovered_pubkey
    – larry 8
    Commented Oct 29, 2023 at 22:34
  • through some trial an error + a lot of google + peppering chat GPT... i can validate a the signature provided in the input by removing the first two chars of the publicKey
    – larry 8
    Commented Oct 30, 2023 at 12:43

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.