/** * @param recId Which possible key to recover. * @param sig the R and S components of the signature, wrapped. * @param messageHash Hash of the data that was signed. * * @return 20-byte address */ @Nullable public static byte[] recoverAddressFromSignature(int recId, ECDSASignature sig, byte[] messageHash) { byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, messageHash); if (pubBytes == null) { return null; } else { return computeAddress(pubBytes); } }
/** * @param recId Which possible key to recover. * @param sig the R and S components of the signature, wrapped. * @param messageHash Hash of the data that was signed. * * @return ECKey */ @Nullable public static ECKey recoverFromSignature(int recId, ECDSASignature sig, byte[] messageHash) { byte[] pubBytes = recoverPubBytesFromSignature(recId, sig, messageHash); if (pubBytes == null) { return null; } else { return fromPublicOnly(pubBytes); } } /**
/** * Takes the keccak hash (32 bytes) of data and returns the ECDSA signature * * @param messageHash - * * @return - * * @throws IllegalStateException if this ECKey does not have the private part. */ public ECDSASignature sign(byte[] messageHash) { ECDSASignature sig = doSign(messageHash); // Now we have to work backwards to figure out the recId needed to recover the signature. int recId = -1; byte[] thisKey = this.pub.getEncoded(/* compressed */ false); for (int i = 0; i < 4; i++) { byte[] k = recoverPubBytesFromSignature(i, sig, messageHash); if (k != null && Arrays.equals(k, thisKey)) { recId = i; break; } } if (recId == -1) { throw new RuntimeException( "Could not construct a recoverable key. This should never happen."); } sig.v = (byte) (recId + 27); return sig; }
public static byte[] signatureToKeyBytes(byte[] messageHash, ECDSASignature sig) throws SignatureException { check(messageHash.length == 32, "messageHash argument has length " + messageHash.length); int header = sig.v; // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, // 0x1D = second key with even y, 0x1E = second key with odd y if (header < 27 || header > 34) { throw new SignatureException("Header byte out of range: " + header); } if (header >= 31) { header -= 4; } int recId = header - 27; byte[] key = recoverPubBytesFromSignature(recId, sig, messageHash); if (key == null) throw new SignatureException("Could not recover public key from signature"); return key; }