I am currently signing with a the ECDSASignature spec in java however I noticed that getting a v value from the signature is a custom spec for ethereum.

My code:

public static void main(String[] args) throws Exception
    byte[] offer = {
            0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01

//TODO port to android
//TODO get v value
private static JSONObject getAgreementFromAdmin(byte[] offer) throws Exception
    //no need for address, from ecrecover you can take the token.
    System.out.println("offer: " +  offer.length);
    // sign() returns r, s but not v
    // org.web3j.crypto.ECDSASignature
    ECDSASignature signature = TransactionQueue.getAdminKeyPair().sign(offer);
    BigInteger r = signature.r;
    BigInteger s = signature.s;
    int v = 27; // minimum value of v, if not working try with 28
    JSONObject agreementJSON = new JSONObject();
    agreementJSON.put("offer", "0x" + bytesToHex(offer));
    agreementJSON.put("v", v);
    agreementJSON.put("r", r);
    agreementJSON.put("s", s);

    return agreementJSON;

The sign method is defined as:

public ECDSASignature sign(byte[] transactionHash) {
    ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));

    ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privateKey, Sign.CURVE);
    signer.init(true, privKey);
    BigInteger[] components = signer.generateSignature(transactionHash);

    return new ECDSASignature(components[0], components[1]).toCanonicalised();
  • Do you have a question? Might be more effective to state it clearly. – benjaminion Jan 8 '18 at 9:47
  • I am looking at the same thing. There is some code in the Nethereum signer sources that calculates v, I noticed, that might help, but that seems to 'guess' the v value by looking at 4 possible values. – Sentinel Jan 10 '18 at 12:27
  • Check out this answer ethereum.stackexchange.com/questions/35764/… – Sentinel Jan 10 '18 at 17:32

This is similar to this question. The calculation of v in the geth client can be found here. It's simply the combination of

  • parity of the y coordinate of "r".
  • overflow flag (which, as per the comment, won't happen in reality).

To calculate v, you need to know the y coordinate that corresponds to r. You may need access to the internals of your library to do this.

Please see this question R,S,V ECDSA packet signatures

r is a function of the x coordinate of the point on the curve. The x coordinate can correspond to 2 y coordinates on the elliptic curve, which is symmetrical over the x axis. v specifies which of the two y coordinates were used, to help with the public key verification.

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.