Java Code Examples for org.bitcoinj.core.ECKey#recoverFromSignature()

The following examples show how to use org.bitcoinj.core.ECKey#recoverFromSignature() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: EOSSign.java    From token-core-android with Apache License 2.0 6 votes vote down vote up
private static SignatureData signAsRecoverable(byte[] value, ECKey ecKey) {
  int recId = -1;
  ECKey.ECDSASignature sig = eosSign(value, ecKey.getPrivKey());
  for (int i = 0; i < 4; i++) {
    ECKey recoverKey = ECKey.recoverFromSignature(i, sig, Sha256Hash.wrap(value), false);
    if (recoverKey != null && recoverKey.getPubKeyPoint().equals(ecKey.getPubKeyPoint())) {
      recId = i;
      break;
    }
  }

  if (recId == -1) {
    throw new TokenException("Could not construct a recoverable key. This should never happen.");
  }
  int headerByte = recId + 27 + 4;
  // 1 header + 32 bytes for R + 32 bytes for S
  byte v = (byte) headerByte;
  byte[] r = NumericUtil.bigIntegerToBytesWithZeroPadded(sig.r, 32);
  byte[] s = NumericUtil.bigIntegerToBytesWithZeroPadded(sig.s, 32);

  return new SignatureData(v, r, s);

}
 
Example 2
Source File: Signature.java    From evt4j with MIT License 6 votes vote down vote up
public static int getRecId(Signature signature, byte[] hash, @NotNull PublicKey publicKey) {
    Sha256Hash dataHash = Sha256Hash.wrap(hash);

    String refPubKey = publicKey.getEncoded(true);

    int recId = -1;
    for (int i = 0; i < 4; i++) {
        ECKey k = ECKey.recoverFromSignature(i, signature.get(), dataHash, true);
        try {
            if (k != null && Utils.HEX.encode(k.getPubKey()).equals(refPubKey)) {
                return i;
            }
        } catch (Exception ex) {
            // no need to handle anything here
        }
    }

    return recId;
}
 
Example 3
Source File: HWWallet.java    From GreenBits with GNU General Public License v3.0 6 votes vote down vote up
@Override
public String[] signChallenge(final String challengeString, final String[] challengePath) {

    // Generate a path for the challenge.
    // We use "GA" + 0xB11E as the child path as this allows btchip to skip HID auth.
    final HWWallet child = derive(0x4741b11e); // 0x4741 = Ascii G << 8 + A

    // Generate a message to sign from the challenge
    final String challenge = "greenaddress.it      login " + challengeString;
    final byte[] rawHash = Wally.format_bitcoin_message(challenge.getBytes(),
                                                        Wally.BITCOIN_MESSAGE_FLAG_HASH);
    final Sha256Hash hash = Sha256Hash.wrap(rawHash);

    // Return the path to the caller for them to pass in the server RPC call
    challengePath[0] = "GA";

    // Compute and return the challenge signatures
    final ECKey.ECDSASignature signature = child.signMessage(challenge);
    int recId;
    for (recId = 0; recId < 4; ++recId) {
        final ECKey recovered = ECKey.recoverFromSignature(recId, signature, hash, true);
        if (recovered != null && recovered.equals(child.getPubKey()))
            break;
    }
    return new String[]{signature.r.toString(), signature.s.toString(), String.valueOf(recId)};
}
 
Example 4
Source File: EthereumSign.java    From token-core-android with Apache License 2.0 5 votes vote down vote up
/**
 * Given an arbitrary piece of text and an Ethereum message signature encoded in bytes,
 * returns the public key that was used to sign it. This can then be compared to the expected
 * public key to determine if the signature was correct.
 *
 * @param message       RLP encoded message.
 * @param signatureData The message signature components
 * @return the public key used to sign the message
 * @throws SignatureException If the public key could not be recovered or if there was a
 *                            signature format error.
 */
private static BigInteger signedMessageToKey(byte[] message, SignatureData signatureData) throws SignatureException {

  byte[] r = signatureData.getR();
  byte[] s = signatureData.getS();
  checkState(r != null && r.length == 32, "r must be 32 bytes");
  checkState(s != null && s.length == 32, "s must be 32 bytes");

  int header = signatureData.getV() & 0xFF;
  // 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);
  }

  ECKey.ECDSASignature sig = new ECKey.ECDSASignature(
      new BigInteger(1, signatureData.getR()),
      new BigInteger(1, signatureData.getS()));

  byte[] messageHash = Hash.keccak256(message);
  int recId = header - 27;
  ECKey key = ECKey.recoverFromSignature(recId, sig, Sha256Hash.wrap(messageHash), false);
  if (key == null) {
    throw new SignatureException("Could not recover public key from signature");
  }
  byte[] pubKeyBytes = key.getPubKeyPoint().getEncoded(false);
  return NumericUtil.bytesToBigInteger(Arrays.copyOfRange(pubKeyBytes, 1, pubKeyBytes.length));
}
 
Example 5
Source File: EthereumSign.java    From token-core-android with Apache License 2.0 5 votes vote down vote up
public static SignatureData signAsRecoverable(byte[] value, ECKey ecKey) {

    ECKey.ECDSASignature sig = ecKey.sign(Sha256Hash.wrap(value));

    // Now we have to work backwards to figure out the recId needed to recover the signature.
    int recId = -1;
    for (int i = 0; i < 4; i++) {
      ECKey recoverKey = ECKey.recoverFromSignature(i, sig, Sha256Hash.wrap(value), false);
      if (recoverKey != null && recoverKey.getPubKeyPoint().equals(ecKey.getPubKeyPoint())) {
        recId = i;
        break;
      }
    }
    if (recId == -1) {
      throw new RuntimeException(
          "Could not construct a recoverable key. This should never happen.");
    }

    int headerByte = recId + 27;

    // 1 header + 32 bytes for R + 32 bytes for S
    byte v = (byte) headerByte;
    byte[] r = NumericUtil.bigIntegerToBytesWithZeroPadded(sig.r, 32);
    byte[] s = NumericUtil.bigIntegerToBytesWithZeroPadded(sig.s, 32);

    return new SignatureData(v, r, s);
  }
 
Example 6
Source File: Signature.java    From evt4j with MIT License 5 votes vote down vote up
/**
 * Recover public key from signature and original data byte[]. Note: one always
 * need to compare the public key recovered from signature match with whe
 * reference public key
 *
 * @param data      original data signed by the private key
 * @param signature signature from sign method
 * @return {@link PublicKey}
 */
@NotNull
@Contract("_, _ -> new")
public static PublicKey recoverPublicKey(byte[] data, @NotNull Signature signature) {
    Sha256Hash dataHash = Sha256Hash.wrap(data);

    ECKey k = ECKey.recoverFromSignature(signature.getRecId(), signature.get(), dataHash, true);
    if (k == null) {
        throw new PublicKeyRecoverFailureException();
    }

    return new PublicKey(k.getPubKey());
}