Проблемная цифровая подпись с SECP256K1

Я пытаюсь протестировать TestNet3, и у меня есть пара ключей, сгенерированная с использованием криптобиблиотеки Java.

Закрытый ключ 23F847360E1EB348A212F443C633058080A8EB9F05AD132F8B82D51FE672EADDи открытый ключ имеют 044C8478229D9A139803AB0889617ECB6421191F3D891D0817D6A6CFD43BCBAA206FA9CE781E1C48764D8D1D0CE58DC6DE76C1B5F97CBCB5C9F01960DEAD3E192Fсжатую форму как 024C8478229D9A139803AB0889617ECB6421191F3D891D0817D6A6CFD43BCBAA20.

Я получил адрес TestNet msmVKMjAz7UdJSfkpvv3z4RMbt7pxocqZwи решил использовать его для подписи хэша транзакции в режиме C46A8842187BB3642463B020D63462800FFB45791284404A965EF027D9F3B473использования SHA256withECDSA.

Следующие R и S генерируются в качестве подписи:

Component R: 038646375A34E4DA028B44362D1745870D019782245EF094AA788D17FD69F1D3
Component S: 00F29287B9A8913A9D751ECB33B32EEEB5614BAA32CF714811E29AE07F0886D4E7

Мой код подписи использует BouncyCastle в качестве провайдера Java JCE, как показано ниже:

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);

Выход:

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
=============

Когда я использую BitcoinJ для передачи своей транзакции в TestNet, я получаю следующие ошибки:

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

Ответы (1)

Ваш сжатый открытый ключ неверен. Это должно быть 034c8478229d9a139803ab0889617ecb6421191f3d891d0817d6a6cfd43bcbaa20. Как вы его построили?