Problematic Digital Signature with SECP256K1

Problematic Digital Signature with SECP256K1

I am trying to test out TestNet3 and I have a keypair generated using Java crypto library.

The private key is 23F847360E1EB348A212F443C633058080A8EB9F05AD132F8B82D51FE672EADD and the public key is 044C8478229D9A139803AB0889617ECB6421191F3D891D0817D6A6CFD43BCBAA206FA9CE781E1C48764D8D1D0CE58DC6DE76C1B5F97CBCB5C9F01960DEAD3E192F with the compressed form as 024C8478229D9A139803AB0889617ECB6421191F3D891D0817D6A6CFD43BCBAA20.

I derive a TestNet address resulting in msmVKMjAz7UdJSfkpvv3z4RMbt7pxocqZw and decided to use it to sign a transaction hash of C46A8842187BB3642463B020D63462800FFB45791284404A965EF027D9F3B473 using SHA256withECDSA mode.

The following R and S is generated as the Signature:

Component R: 038646375A34E4DA028B44362D1745870D019782245EF094AA788D17FD69F1D3
Component S: 00F29287B9A8913A9D751ECB33B32EEEB5614BAA32CF714811E29AE07F0886D4E7

My signing code is using BouncyCastle as the Java JCE provider as shown below:

System.out.println("BC Sign Begin");
System.out.println("=============");
X9ECParameters CURVE_PARAMS = CustomNamedCurves.getByName("secp256k1");
ECDomainParameters CURVE = new ECDomainParameters(CURVE_PARAMS.getCurve(), CURVE_PARAMS.getG(), CURVE_PARAMS.getN(), CURVE_PARAMS.getH());
ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest()));
ECPrivateKeyParameters privKey1 = new ECPrivateKeyParameters(((ECPrivateKey) keys[0]).getS(), CURVE);
System.out.println("Curve A Coefficient (a): " + privKey1.getParameters().getCurve().getA().toBigInteger().toString(16));
System.out.println("Curve B Coefficient (b): " + privKey1.getParameters().getCurve().getB().toBigInteger().toString(16));
System.out.println("Curve G Generator X (Gx): " + privKey1.getParameters().getG().getAffineXCoord().toBigInteger().toString(16));
System.out.println("Curve G Generator Y (Gy): " + privKey1.getParameters().getG().getAffineYCoord().toBigInteger().toString(16));
System.out.println("Curve Order (n): " + privKey1.getParameters().getCurve().getOrder().toString(16));
System.out.println("Curve Cofactor (h): " + privKey1.getParameters().getCurve().getCofactor().toString(16));
System.out.println("Private Key In Use: " + ((ECPrivateKey) keys[0]).getS().toString(16));
signer.init(true, privKey1);
BigInteger[] components = signer.generateSignature(input1);
System.out.println("Component R: " + BinUtils.toHexString(components[0].toByteArray()));
System.out.println("Component S: " + BinUtils.toHexString(components[1].toByteArray()));
String compStrs = BinUtils.toHexString(components[0].toByteArray()) + "+" + BinUtils.toHexString(components[1].toByteArray());
System.out.println("Components String: " + compStrs);

The output:

BC Sign Begin
=============
Curve A Coefficient (a): 0
Curve B Coefficient (b): 7
Curve G Generator X (Gx): 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Curve G Generator Y (Gy): 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
Curve Order (n): fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
Curve Cofactor (h): 1
Private Key In Use: 23f847360e1eb348a212f443c633058080a8eb9f05ad132f8b82d51fe672eadd
Component R: 038646375A34E4DA028B44362D1745870D019782245EF094AA788D17FD69F1D3
Component S: 00F29287B9A8913A9D751ECB33B32EEEB5614BAA32CF714811E29AE07F0886D4E7
Components String: 038646375A34E4DA028B44362D1745870D019782245EF094AA788D17FD69F1D3+00F29287B9A8913A9D751ECB33B32EEEB5614BAA32CF714811E29AE07F0886D4E7
=============

When I use BitcoinJ to transmit my transaction to the TestNet, I am getting the following errors:

org.bitcoinj.core.ScriptException: Script resulted in a non-true stack: []
at org.bitcoinj.script.Script.correctlySpends(Script.java:1606)
at java.lang.Thread.run(Thread.java:744)
Hit an exception when trying to approve: 
java.util.concurrent.ExecutionException: org.bitcoinj.core.RejectedTransactionException: Reject: tx e374f230fe59b91ff88cc81768c10cb0d3b651079383da4dcfa4ef54372dcbd7 for reason 'mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)' (16)
at com.google.common.util.concurrent.AbstractFuture$Sync.getValue(AbstractFuture.java:299)
at com.google.common.util.concurrent.AbstractFuture$Sync.get(AbstractFuture.java:286)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:116)
Caused by: org.bitcoinj.core.RejectedTransactionException: Reject: tx e374f230fe59b91ff88cc81768c10cb0d3b651079383da4dcfa4ef54372dcbd7 for reason 'mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)' (16)
at org.bitcoinj.core.TransactionBroadcast$2.onPreMessageReceived(TransactionBroadcast.java:102)
at org.bitcoinj.core.Peer.processMessage(Peer.java:461)
at org.bitcoinj.core.PeerSocketHandler.receiveBytes(PeerSocketHandler.java:184)
at org.bitcoinj.net.ConnectionHandler.handleKey(ConnectionHandler.java:223)
at org.bitcoinj.net.NioClientManager.handleKey(NioClientManager.java:86)
at org.bitcoinj.net.NioClientManager.run(NioClientManager.java:122)
at com.google.common.util.concurrent.AbstractExecutionThreadService$1$2.run(AbstractExecutionThreadService.java:60)
at com.google.common.util.concurrent.Callables$3.run(Callables.java:95)
at org.bitcoinj.utils.ContextPropagatingThreadFactory$1.run(ContextPropagatingThreadFactory.java:49)
... 1 more
https://ift.tt/2KdnjCe

Comments

Popular posts from this blog

bitcoin node: what is the difference between simnet and regtest?

How to check if Electrum is masking my IP with the Tor proxy?

Need help to recover blpckchain.info wallet, my wife forgot her password and the brute force with btcrecover is not catching the password