Often the problem is the Signature Verification algorithm used. Bitcoin makes use of double SHA-256 because the hashing algorithm for ECDSA, thus the Z worth is the Double SHA-256 hash of the unsigned transaction. Trying on the Signature Hash Algorithm you are utilizing:
Signature algorithm ALG_ECDSA_SHA_256 generates a 32-byte SHA-256 digest and indicators/verifies the digest utilizing ECDSA with the curve outlined within the ECKey parameters
You’re taking within the Z worth already however then hashing it once more with only one spherical of SHA-256. You might attempt to go in a preimage of only one SHA-256 hash then let the Signature object deal with the second spherical, however I wouldn’t have a lot luck with this technique utilizing normal Java Safety libraries. So as to accomplish Bitcoin Transaction signing/verification in Java, you will have to both (1) implement your personal ECDSA signing/verification, or (2) use a library reminiscent of BitcoinJ. The next is the code I exploit in my very own undertaking(s) inside my ECPubKey class (word that I’m utilizing a ton of different customized code that you will note technique calls from, but are usually not included right here, however you’ll get the gist):
/**
* @param preimage the Preimage to confirm
* @param signature An ECDSA Signature (R/S Worth pair)
* @return whether or not this Public Key was used to generate the signature for the given preimage
*/
public boolean confirm(String preimage, ECSignature signature) {
String sigHash = HashUtil.doubleSha256(preimage);
BigInteger z = new BigInteger(1, ByteUtil.hex2bytes(sigHash));
BigInteger r = signature.getR();
BigInteger s = signature.getS();
BigInteger sInv = s.modInverse(CurveParams.n);
BigInteger u1 = z.multiply(sInv).mod(CurveParams.n);
BigInteger u2 = r.multiply(sInv).mod(CurveParams.n);
ECPoint u1Point = ScalarMultiply.scalmult(CurveParams.G, u1);
ECPoint u2Point = ScalarMultiply.scalmult(this.getPoint(), u2);
ECPoint sigPoint = ScalarMultiply.addPoint(u1Point, u2Point);
return r.compareTo(sigPoint.getAffineX().mod(CurveParams.n)) == 0;
}
The methodology was basically copied instantly from the ECDSA Wikipedia Web page and translated into Java.