22

The question of signing and verifying signatures with Solidity has been asked in these questions, both of which I have tried to study:

How can I sign a piece of data with the private key of an Ethereum address?

How can I verify a cryptographic signature that was produced by an Ethereum address key pair

However, there are still pieces of information that I appear to be missing.

First off, I would like to start with the question about signing. In the example, the string Schoolbus is signed by the address 0xd1ade25ccd3d550a7eb532ac759cac7be09c2719, and the resulting signature is 0x2ac19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601.

So far, so good. Now, what I'd like to do is verify using ecrecover that the signature is indeed correct for the given address and datum. The thing is, ecrecover takes four arguments: ecrecover(h, v, r, s). Aside from h being the hash, and {v, r, s} somehow comprising the signature, what exactly do v, r, and s stand for? And how do I obtain all the values necessary from the single string 0x2ac19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601?

What I know is that ecrecover returns an address, and verifying a signature is essentially a matter of comparing the resulting address with the expected one. Yet the whole procedure seems unnecessarily complicated.

Aside from this, I was also wondering how I could produce a signature, either like this 0x2ac19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601 or a set of {h, v, r, s} using Solidity alone, without the RPC-JSON detour as is the case in the question – provided I know a private key?

  • Check out ethereum.stackexchange.com/questions/1777/… Here I also list the procedure for extracting r, v, and s from the signature string. I agree that this procedure is a bit too complicated, and I expressed this issue here: github.com/ethereum/EIPs/issues/79 – MrChico Mar 23 '16 at 0:47
  • I'm afraid that the question in question is not in Solidity. What I am trying to accomplish has to be executed within a contract. – arik Mar 23 '16 at 0:53
  • Can you expand a bit on why you would want to sign something inside a contract? As has been mentioned this will expose the private key of the signer to everyone – MrChico Mar 23 '16 at 0:54
  • I merely want to verify a signature in the format specified above within a contract. The signing part would be just for unit testing. – arik Mar 23 '16 at 0:55
  • The verification procedure is done in a solidity contract in the question I linked to – MrChico Mar 23 '16 at 0:57
15

v, r, and s are parameters that can be parsed from the signature. Here's a good example from the ethereumjs utils library:

  var sig = secp256k1.sign(msgHash, privateKey)
  var ret = {}
  ret.r = sig.signature.slice(0, 32)
  ret.s = sig.signature.slice(32, 64)
  ret.v = sig.recovery + 27

Note how you can parse each value from a given signature.

Even though you may sign two different msgs with the same private key, the signing process (internally) generates a random nonce value (k) that is used as part of the calculation and must be different for each generated signature.

r and s along with the associated public key help to validate if the signature is legit.

Note: I'm no cryptographer. This is what I've dug up trying to answer the same questions you have. I'd suggest looking at some of the online resources for elliptic curves.

Aside from this, I was also wondering how I could produce a signature, either like this 0x2ac19db245478a06032e69cdbd2b54e648b78431d0a47bd1fbab18f79f820ba407466e37adbe9e84541cab97ab7d290f4a64a5825c876d22109f3bf813254e8601 or a set of {h, v, r, s} using Solidity alone, without the RPC-JSON detour as is the case in the question – provided I know a private key?

The problem you'd have generating a signature from within Solidity is you'd have to expose the private key. Alternatively, you could generate a signature outside of the normal Ethereum transaction process using one of the many elliptic curve libraries and send that resulting signature to a contract.

  • Thanks for the response! Now, if I have just the signature string, how do I get the signature object from it? The signature string itself does not contain a recovery property, I'm afraid. Also, just making sure: Is the hash necessary for ecrecover sha256? – arik Mar 22 '16 at 22:55
  • Is there any way v can be recalculated? I'm afraid ecrecover won't work without passing in the right value. – arik Mar 22 '16 at 23:20
  • IIUC when a signature is DER encoded, it only stores the r and s points, and throws away "v". When I want to supply a "v" value I just try them both. So where pubkey_decompressed is the public key that created the ethereum address: v_but_not_really, r, s = bitcoin.der_decode_sig(sig) for possible_v in [27, 28]: possible_pub = bitcoin.encode_pubkey(bitcoin.ecdsa_raw_recover(msg_hash, (possible_v, r, s)), 'hex') if pubkey_decompressed == possible_pub: return possible_v – Edmund Edgar Mar 22 '16 at 23:21
  • 2
    In the string that is returned when using eth.sign, v is included. The last two hex characters represent v. More on this here: ethereum.stackexchange.com/questions/1777/… – MrChico Mar 23 '16 at 0:53
  • to accomplish this signing process, what client or what environment do I need? " var sig = secp256k1.sign(msgHash, privateKey) var ret = {} ret.r = sig.signature.slice(0, 32) ret.s = sig.signature.slice(32, 64) ret.v = sig.recovery + 27" – Wang May 10 '16 at 5:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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