public void testSignAndVerify1_NB() { //Single hash string fullURL = "https://btcpaytest.indiesquare.net/tokens"; byte[] data = Encoding.UTF8.GetBytes(fullURL); byte[] singleHash = null; using (var hash256 = SHA256.Create()) { var bytes = Encoding.UTF8.GetBytes(fullURL); singleHash = hash256.ComputeHash(bytes); } //string sig = _nbKey.SignMessage(fullURL);//Double hashed and base64 but NOT DER //byte[] doubleHashedSig = Convert.FromBase64String(sig); ECDSASignature eCDSA = _nbKey.Sign(new uint256(singleHash)); string sigDERStr = KeyUtils.bytesToHex(eCDSA.ToDER()); // bitpay verify Assert.IsTrue(_ecKey.Verify(singleHash, eCDSA.ToDER())); //NBitcoin verify PubKey pubk = _nbKey.PubKey; Assert.IsTrue(pubk.Verify(new uint256(singleHash), new ECDSASignature(eCDSA.ToDER()))); //Assert.IsTrue(pubk.Verify(doubleHash, new ECDSASignature(doubleHashedSig)));//NOT DER }
public void ToFromDer() { var signature = new ECDSASignature( TestUtils.HexToBigInteger("657912a72d3ac8169fe8eaecd5ab401c94fc9981717e3e6dd4971889f785790c"), TestUtils.HexToBigInteger("00ed3bf3456eb76677fd899c8ccd1cc6d1ebc631b94c42f7c4578f28590d651c6e")); var expected = Encoders.Hex.GetBytes("30450220657912a72d3ac8169fe8eaecd5ab401c94fc9981717e3e6dd4971889f785790c022100ed3bf3456eb76677fd899c8ccd1cc6d1ebc631b94c42f7c4578f28590d651c6e"); CollectionAssert.AreEqual(expected, signature.ToDER()); var signature1 = ECDSASignature.FromDER(signature.ToDER()); Assert.AreEqual(signature.R, signature1.R); Assert.AreEqual(signature.S, signature1.S); }
public void RunAsync_ProofOfStakeBlock_PayToPubKeyScriptPassesBlockSignatureValidation_DoesNotThrowException() { Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock(); block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction()); Transaction transaction = KnownNetworks.StratisMain.CreateTransaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); var scriptPubKeyOut = new Script(Op.GetPushOp(this.key.PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG); transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut)); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.ValidationContext.BlockToValidate = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate)); this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext); }
public async Task RunAsync_ProofOfStakeBlock_OpCountBelowTwo_ThrowsBadBlockSignatureConsensusErrorExceptionAsync() { var block = new Block(); block.Transactions.Add(new Transaction()); var transaction = new Transaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); transaction.Outputs.Add(new TxOut(Money.Zero, new Script(new Op() { Code = OpcodeType.OP_RETURN }))); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); block.BlockSignatur = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.BlockValidationContext.Block = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block)); var exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); }
public void CanSerializeInJson() { var k = new Key(); CanSerializeInJsonCore(DateTimeOffset.UtcNow); CanSerializeInJsonCore(new byte[] { 1, 2, 3 }); CanSerializeInJsonCore(k); CanSerializeInJsonCore(Money.Coins(5.0m)); CanSerializeInJsonCore(k.PubKey.GetAddress(KnownNetworks.Main)); CanSerializeInJsonCore(new KeyPath("1/2")); CanSerializeInJsonCore(KnownNetworks.Main); CanSerializeInJsonCore(new uint256(RandomUtils.GetBytes(32))); CanSerializeInJsonCore(new uint160(RandomUtils.GetBytes(20))); CanSerializeInJsonCore(new AssetId(k.PubKey)); CanSerializeInJsonCore(k.PubKey.ScriptPubKey); CanSerializeInJsonCore(new Key().PubKey.WitHash.GetAddress(KnownNetworks.Main)); CanSerializeInJsonCore(new Key().PubKey.WitHash.ScriptPubKey.GetWitScriptAddress(KnownNetworks.Main)); ECDSASignature sig = k.Sign(new uint256(RandomUtils.GetBytes(32))); CanSerializeInJsonCore(sig); CanSerializeInJsonCore(new TransactionSignature(sig, SigHash.All)); CanSerializeInJsonCore(k.PubKey.Hash); CanSerializeInJsonCore(k.PubKey.ScriptPubKey.Hash); CanSerializeInJsonCore(k.PubKey.WitHash); CanSerializeInJsonCore(k); CanSerializeInJsonCore(k.PubKey); CanSerializeInJsonCore(new WitScript(new Script(Op.GetPushOp(sig.ToDER()), Op.GetPushOp(sig.ToDER())))); CanSerializeInJsonCore(new LockTime(1)); CanSerializeInJsonCore(new LockTime(DateTime.UtcNow)); }
public async Task RunAsync_ProofOfStakeBlock_PayToPubKeyScriptPassesBlockSignatureValidation_DoesNotThrowExceptionAsync() { var block = new Block(); block.Transactions.Add(new Transaction()); var transaction = new Transaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); Script scriptPubKeyOut = new Script(Op.GetPushOp(this.key.PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG); transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut)); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); block.BlockSignatur = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.BlockValidationContext.Block = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block)); await this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext); }
public async Task RunAsync_ProofOfStakeBlock_ScriptKeyPassesBlockSignatureValidation_DoesNotThrowExceptionAsync() { var block = Network.StratisMain.Consensus.ConsensusFactory.CreateBlock(); block.Transactions.Add(Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction()); var transaction = Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); // push op_return to note external dependancy in front of pay to pubkey script so it does not match pay to pubkey template. Script scriptPubKeyOut = new Script(OpcodeType.OP_RETURN, Op.GetPushOp(this.key.PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG); transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut)); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.BlockValidationContext.Block = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block)); await this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext); }
public async Task RunAsync_ProofOfStakeBlock_FirstOpInScriptPubKeyNotOP_Return_ThrowsBadBlockSignatureConsensusErrorExceptionAsync() { var block = Network.StratisMain.Consensus.ConsensusFactory.CreateBlock(); block.Transactions.Add(Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction()); var transaction = Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); transaction.Outputs.Add(new TxOut(Money.Zero, new Script(new Op() { Code = OpcodeType.OP_CHECKSIG }))); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.BlockValidationContext.Block = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block)); var exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); }
public async Task RunAsync_ProofOfStakeBlock_CoinStakePayToPubScriptKeyInvalid_ThrowsBadBlockSignatureConsensusErrorExceptionAsync() { var block = new Block(); block.Transactions.Add(new Transaction()); var transaction = new Transaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); // use different key with PayToPubKey script transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); Script scriptPubKeyOut = new Script(Op.GetPushOp(new Key().PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG); transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut)); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); block.BlockSignatur = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.BlockValidationContext.Block = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block)); var exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); }
public void SerializeDeserializeCompact(ECDSASignature signature) { var b = signature.ToCompact(); ECDSASignature.TryParseFromCompact(b, out var signature2); Assert.True(signature.ToDER().SequenceEqual(signature2.ToDER())); }
public void can_always_recover_pubkey_from_signature_when_stopping_at_null() { var rand = new Random(); for (int i = 0; i < 1000; i++) { var key = new Key(); PosBlock block = new PosBlock(new BlockHeader() { Time = (uint)rand.Next() }); ECDSASignature signature = key.Sign(block.GetHash()); block.BlockSignature = new BlockSignature { Signature = signature.ToDER() }; Assert.True(key.PubKey.Verify(block.GetHash(), new ECDSASignature(block.BlockSignature.Signature))); signature = ECDSASignature.FromDER(block.BlockSignature.Signature); bool match = false; for (int recId = 0; !match; recId++) { PubKey pubKeyForSig = PubKey.RecoverFromSignature(recId, signature, block.GetHash(), true); if (pubKeyForSig == null) { break; } match = pubKeyForSig == key.PubKey; } Assert.True(match); } }
public void RunAsync_ProofOfStakeBlock_NoOpsInScriptPubKey_ThrowsBadBlockSignatureConsensusErrorException() { Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock(); block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction()); Transaction transaction = KnownNetworks.StratisMain.CreateTransaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); transaction.Outputs.Add(new TxOut(Money.Zero, new Script())); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.ValidationContext.BlockToValidate = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate)); ConsensusErrorException exception = Assert.Throws <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); }
public void RunAsync_ProofOfStakeBlock_CoinStakePayToPubScriptKeyInvalid_ThrowsBadBlockSignatureConsensusErrorException() { Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock(); block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction()); Transaction transaction = KnownNetworks.StratisMain.CreateTransaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); // use different key with PayToPubKey script transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); var scriptPubKeyOut = new Script(Op.GetPushOp(new Key().PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG); transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut)); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.ValidationContext.BlockToValidate = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate)); ConsensusErrorException exception = Assert.Throws <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); }
//private IEnumerator postWithSignature(String uri, String json) //{ // Debug.Log(" postWithSignature() is called."); // yield return this.post(uri, json, true); //} private IEnumerator post(String uri, String json, bool signatureRequired = false) { Debug.Log(" post() is called URI:" + uri); Debug.Log(" post() is called signatureRequired: " + signatureRequired); Debug.Log(" post() is called json before: " + json); json = unicodeToAscii(json); Debug.Log(" post() is called json after : " + json); using (UnityWebRequest httpClient = new UnityWebRequest(_baseUrl + uri, UnityWebRequest.kHttpVerbPOST)) { httpClient.SetRequestHeader("x-accept-version", BITPAY_API_VERSION); httpClient.SetRequestHeader("x-bitpay-plugin-info", BITPAY_PLUGIN_INFO); httpClient.SetRequestHeader("Content-Type", "application/json"); if (signatureRequired) { //String signature = KeyUtils.sign(_ecKey, _baseUrl + uri + json); string text = _baseUrl + uri + json; byte[] singleHash = null; using (var hash256 = SHA256.Create()) { var bytes = Encoding.UTF8.GetBytes(text); singleHash = hash256.ComputeHash(bytes); } ECDSASignature eCDSA = _ecKey.Sign(new uint256(singleHash)); string newsig = KeyUtils.bytesToHex(eCDSA.ToDER()); httpClient.SetRequestHeader("x-signature", newsig); // byte[] pubkBytes = _ecKey.PubKey; byte[] pubkBytes = _ecKey.PubKey.Decompress().ToBytes(); httpClient.SetRequestHeader("x-identity", KeyUtils.bytesToHex(pubkBytes)); Debug.Log("POST HEADER:data:" + _baseUrl + uri + json); Debug.Log("POST HEADER:x-signature:" + newsig); Debug.Log("POST HEADER:x-identity(hex pubk):" + KeyUtils.bytesToHex(pubkBytes)); } UploadHandlerRaw uH = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(json)); httpClient.uploadHandler = uH; httpClient.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer(); UnityWebRequestAsyncOperation uwr = httpClient.SendWebRequest();// send request while (!uwr.isDone) { // Debug.Log(uwr.progress); yield return(null); } if (httpClient.isNetworkError || httpClient.isHttpError) { Debug.Log("post Error:" + httpClient.error); Debug.Log("post Status:" + httpClient.responseCode); yield return(httpClient.downloadHandler.text); // return donwloadhandler.text } else { // Debug.Log("postWithSignature(): Ready to download"); yield return(httpClient.downloadHandler.text); // return donwloadhandler.text } } }
public void Sign(Key key, PoABlockHeader header) { ECDSASignature signature = key.Sign(header.GetHash()); header.BlockSignature = new BlockSignature { Signature = signature.ToDER() }; }
public byte[] ToBytes() { var sig = _Signature.ToDER(); var result = new byte[sig.Length + 1]; Array.Copy(sig, 0, result, 0, sig.Length); result[result.Length - 1] = (byte)_SigHash; return(result); }
public void MultipleSignatureWays() { var privKeyStr = Encoders.Hex.DecodeData("8e812436a0e3323166e1f0e8ba79e19e217b2c4a53c970d4cca0cfb1078979df"); Key key = new Key(privKeyStr); Assert.AreEqual("04a5bb3b28466f578e6e93fbfd5f75cee1ae86033aa4bbea690e3312c087181eb366f9a1d1d6a437a9bf9fc65ec853b9fd60fa322be3997c47144eb20da658b3d1", key.PubKey.Decompress().ToHex()); var messageToSign = "159817a085f113d099d3d93c051410e9bfe043cc5c20e43aa9a083bf73660145"; var messageBytes = Encoders.Hex.DecodeData(messageToSign); ECDSASignature signature = key.Sign(new uint256(messageBytes), true); SecpECDSASignature.TryCreateFromDer(signature.ToDER(), out SecpECDSASignature sig); var(r, s) = sig; var R = r.ToBytes(); var S = s.ToBytes(); Assert.AreEqual("38b7dac5ee932ac1bf2bc62c05b792cd93c3b4af61dc02dbb4b93dacb758123f", R.ToHexString()); Assert.AreEqual("08bf123eabe77480787d664ca280dc1f20d9205725320658c39c6c143fd5642d", S.ToHexString()); // Compact signature byte[] signatureCompact = key.SignCompact(new uint256(messageBytes), true); if (signatureCompact.Length != 65) { throw new ArgumentException(paramName: nameof(signatureCompact), message: "Signature truncated, expected 65"); } var ss = signatureCompact.AsSpan(); int recid = (ss[0] - 27) & 3; if (!( SecpRecoverableECDSASignature.TryCreateFromCompact(ss.Slice(1), recid, out SecpRecoverableECDSASignature sigR) && sigR is SecpRecoverableECDSASignature ) ) { throw new InvalidOperationException("Impossible to recover the public key"); } // V from comapct signature var(r1, s1, v1) = sigR; Assert.AreEqual(v1, 0); // Recoverable signature with Secp256k1 lib NBitcoin.Secp256k1.ECPrivKey privKey = Context.Instance.CreateECPrivKey(new Scalar(key.ToBytes())); Assert.AreEqual(key.PubKey.ToBytes(), privKey.CreatePubKey().ToBytes()); privKey.TrySignRecoverable(messageBytes, out SecpRecoverableECDSASignature sigRec); var(r2, s2, v2) = sigRec; Assert.AreEqual(r2, r); Assert.AreEqual(s2, s); Assert.AreEqual(v2, v1); }
/// <summary> /// This helper creates a coin staking block containing a coin staking transaction built according to /// the parameters and with valid first input and output. The block signature is created correctly with the /// private key corresponding to the public key. /// </summary> /// <param name="useCompressedKey">Determines whether the second transaction output will include a compressed /// (versus uncompressed) public key.</param> /// <param name="includeSecondPush">Determines whether the second transaction output will include a small integer /// after the public key.</param> /// <param name="expectFailure">Determines whether we expect failure (versus success).</param> private void ProofOfStakeBlock_CoinStakeTestHelper(bool useCompressedKey, bool includeSecondPush, bool expectFailure) { Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock(); // Add a dummy coinbase transaction. block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction()); // Build a coinstake transaction. Transaction coinStakeTransaction = KnownNetworks.StratisMain.CreateTransaction(); coinStakeTransaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); // First output of coinstake transaction is a special marker. coinStakeTransaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); // Second (unspendable) output. // Depending on the test case use either a compressed public key or an uncompressed public key. var pubKey = useCompressedKey ? this.key.PubKey.Compress() : this.key.PubKey.Decompress(); var opCodes = new List <Op> { OpcodeType.OP_RETURN, Op.GetPushOp(pubKey.ToBytes(true)) }; // Depending on the test case add a second push of some small integer. if (includeSecondPush) { opCodes.Add(Op.GetPushOp(new byte[] { 123 })); } coinStakeTransaction.Outputs.Add(new TxOut(Money.Zero, new Script(opCodes))); // Add the coinstake transaction. block.Transactions.Add(coinStakeTransaction); // Add a signature to the block. ECDSASignature signature = this.key.Sign(block.GetHash()); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; // Execute the PosBlockSignatureRule. this.ruleContext.ValidationContext.BlockToValidate = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate)); if (expectFailure) { ConsensusErrorException exception = Assert.Throws <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); return; } this.consensusRules.RegisterRule <PosBlockSignatureRule>().Run(this.ruleContext); }
static byte[] GetSignature(uint256 hashToSign, Key key) { var signature = key.Sign(hashToSign, SigHash.All); ECDSASignature ecdsaSig = signature.Signature; byte[] derSig = ecdsaSig.ToDER(); byte[] finalSig = new byte[derSig.Length + 1]; Array.Copy(derSig, 0, finalSig, 0, derSig.Length); finalSig[finalSig.Length - 1] = (byte)SigHash.All; return(finalSig); }
private IEnumerator get(String uri, Dictionary <string, string> parameters = null) { String fullURL = _baseUrl + uri; Debug.Log("get() is called with " + fullURL); Debug.Log("get() is called parameters:" + parameters.Count); if (parameters != null) { fullURL += "?"; foreach (KeyValuePair <string, string> entry in parameters) { Debug.Log("get(): getting URL parameter :" + entry.Key + "=" + entry.Value); fullURL += entry.Key + "=" + entry.Value + "&"; } fullURL = fullURL.Substring(0, fullURL.Length - 1); } using (UnityWebRequest httpClient = UnityWebRequest.Get(fullURL)) { httpClient.SetRequestHeader("x-accept-version", BITPAY_API_VERSION); httpClient.SetRequestHeader("x-bitpay-plugin-info", BITPAY_PLUGIN_INFO); // httpClient.SetRequestHeader("Content-Type", "application/json"); // String signature = KeyUtils.sign(_ecKey, fullURL); //string signature = _ecKey.SignMessage(fullURL); string text = fullURL; byte[] singleHash = null; using (var hash256 = SHA256.Create()) { var bytes = Encoding.UTF8.GetBytes(text); singleHash = hash256.ComputeHash(bytes); } ECDSASignature eCDSA = _ecKey.Sign(new uint256(singleHash)); string newsig = KeyUtils.bytesToHex(eCDSA.ToDER()); httpClient.SetRequestHeader("x-signature", newsig); // httpClient.SetRequestHeader("x-signature", signature); // byte[] pubkBytes = _ecKey.PubKey; byte[] pubkBytes = _ecKey.PubKey.Decompress().ToBytes(); httpClient.SetRequestHeader("x-identity", KeyUtils.bytesToHex(pubkBytes)); Debug.Log("GET HEADER:URL+data =" + fullURL); Debug.Log("GET HEADER:x-signature:" + newsig); Debug.Log("GET HEADER:x-identity(hex pubk):" + KeyUtils.bytesToHex(pubkBytes)); yield return(httpClient.SendWebRequest()); // send request yield return(httpClient.downloadHandler.text); // return donwloadhandler } }
public static void SignBlock(this SlimBlock slimBlock, Key blockSignatureKey) { if (slimBlock.IsProofOfStake) { var headerBytes = slimBlock.SlimBlockHeader.SerializeTo80Bytes(); slimBlock.SlimBlockHeader.Data = headerBytes; // the Data field is used in serialization var headerHash = Hashes.DoubleSHA256(headerBytes); ECDSASignature signature = blockSignatureKey.Sign(headerHash); var blockSignature = new NBitcoin.Altcoins.X1Crypto.X1BlockSignature { Signature = signature.ToDER() }; slimBlock.SignatureBytes = blockSignature.ToBytes(); } else { slimBlock.SignatureBytes = new[] { (byte)0 }; // VarString with length of zero, zero encoded as as VarInt } }
public void ECDSASignatureIsOnlyBip66DER() { var invalidBIP66DER = HexToByteArray("302402107777777777777777777777777777777702108777777777777777777777777777777701"); // Encodes: // SEQUENCE { // INTEGER 0x77777777777777777777777777777777, // INTEGER 0x87777777777777777777777777777777 // -1 exponent :( // } // BOOLEAN FALSE var coercedSignature = new ECDSASignature(invalidBIP66DER); var validBIP66DER = HexToByteArray("302502107777777777777777777777777777777702110087777777777777777777777777777777"); // Should coerce to this valid DER encoding: // SEQUENCE { // INTEGER 0x77777777777777777777777777777777, // INTEGER 0x0087777777777777777777777777777777 // +1 exponent :) // } Assert.True(coercedSignature.ToDER().SequenceEqual(validBIP66DER)); }
public void testSignAndVerify2_NB() { //Double Hash string fullURL = "https://btcpaytest.indiesquare.net/tokens"; byte[] data = Encoding.UTF8.GetBytes(fullURL); uint256 doubleHash = Hashes.Hash256(data); //Sign ECDSASignature eCDSA = _nbKey.Sign(doubleHash); string sigDERStr = KeyUtils.bytesToHex(eCDSA.ToDER()); // bitpay verify Assert.IsTrue(_ecKey.Verify(doubleHash.ToBytes(), Encoders.Hex.DecodeData(sigDERStr))); //NBitcoin verify PubKey pubk = _nbKey.PubKey; Assert.IsTrue(pubk.Verify(doubleHash, new ECDSASignature(Encoders.Hex.DecodeData(sigDERStr)))); //Assert.IsTrue(pubk.Verify(doubleHash, new ECDSASignature(doubleHashedSig)));//NOT DER }
public void Run_IsNotCanonicalBlockSignature_ThrowsBadBlockSignatureConsensusErrorException() { Block block = KnownNetworks.StratisMain.Consensus.ConsensusFactory.CreateBlock(); block.Transactions.Add(KnownNetworks.StratisMain.CreateTransaction()); Transaction transaction = KnownNetworks.StratisMain.CreateTransaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); var scriptPubKeyOut = new Script(Op.GetPushOp(this.key.PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG); transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut)); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); signature = signature.MakeNonCanonical(); // Ensure the non-canonical signature is still a valid signature for the block, just in the wrong format. Assert.True(this.key.PubKey.Verify(block.GetHash(), signature)); Assert.False(signature.IsLowS); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.ValidationContext.BlockToValidate = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.BlockToValidate)); ConsensusErrorException exception = Assert.Throws <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRepresentationRule>().Run(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); }
public PosBlockBuilder(Network network, Key privateKey = null) { if (privateKey == null) { var mnemonic = new Mnemonic(Wordlist.English, WordCount.Twelve); privateKey = mnemonic.DeriveExtKey().PrivateKey; } // Create coinstake Tx. Transaction previousTx = network.CreateTransaction(); previousTx.AddOutput(new TxOut()); Transaction coinstakeTx = network.CreateTransaction(); coinstakeTx.AddOutput(new TxOut(0, Script.Empty)); coinstakeTx.AddOutput(new TxOut(50, new Script())); coinstakeTx.AddInput(previousTx, 0); // Create coinbase Tx. Transaction coinBaseTx = network.CreateTransaction(); coinBaseTx.AddOutput(100, new Script()); coinBaseTx.AddInput(new TxIn()); var block = (PosBlock)network.CreateBlock(); block.AddTransaction(coinBaseTx); block.AddTransaction(coinstakeTx); ECDSASignature signature = privateKey.Sign(block.Header.GetHash()); block.BlockSignature = new BlockSignature { Signature = signature.ToDER() }; this.posBlock = block; }
public async Task RunAsync_ProofOfStakeBlock_ScriptKeyDoesNotPassCompressedUncompresedKeyValidation_ThrowsBadBlockSignatureConsensusErrorExceptionAsync() { Block block = Network.StratisMain.Consensus.ConsensusFactory.CreateBlock(); block.Transactions.Add(Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction()); Transaction transaction = Network.StratisMain.Consensus.ConsensusFactory.CreateTransaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); transaction.Outputs.Add(new TxOut(Money.Zero, new Script(new Op() { Code = OpcodeType.OP_RETURN }, new Op() { PushData = new byte[] { 0x11 } }))); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.ValidationContext.Block = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.ValidationContext.Block)); ConsensusErrorException exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); }
public async Task RunAsync_ProofOfStakeBlock_ScriptKeyDoesNotPassBlockSignatureValidation_ThrowsBadBlockSignatureConsensusErrorExceptionAsync() { var block = new Block(); block.Transactions.Add(new Transaction()); var transaction = new Transaction(); transaction.Inputs.Add(new TxIn() { PrevOut = new OutPoint(new uint256(15), 1), ScriptSig = new Script() }); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); // push op_return to note external dependancy in front of pay to pubkey script so it does not match pay to pubkey template. // use a different key to generate the script so it does not pass validation. Script scriptPubKeyOut = new Script(OpcodeType.OP_RETURN, Op.GetPushOp(new Key().PubKey.ToBytes(true)), OpcodeType.OP_CHECKSIG); transaction.Outputs.Add(new TxOut(Money.Zero, scriptPubKeyOut)); block.Transactions.Add(transaction); ECDSASignature signature = this.key.Sign(block.GetHash()); block.BlockSignatur = new BlockSignature { Signature = signature.ToDER() }; this.ruleContext.BlockValidationContext.Block = block; Assert.True(BlockStake.IsProofOfStake(this.ruleContext.BlockValidationContext.Block)); var exception = await Assert.ThrowsAsync <ConsensusErrorException>(() => this.consensusRules.RegisterRule <PosBlockSignatureRule>().RunAsync(this.ruleContext)); Assert.Equal(ConsensusErrors.BadBlockSignature, exception.ConsensusError); }
public byte[] ToDER() { return(ECDSASignature.ToDER()); }
public async Task StraxCoinViewRuleFailsAsync() { var unspentOutputs = new Dictionary <OutPoint, UnspentOutput>(); ConsensusManager consensusManager = await this.CreateConsensusManagerAsync(unspentOutputs); // The keys used by miner 1 and miner 2. var minerKey1 = new Key(); var minerKey2 = new Key(); // The scriptPubKeys (P2PK) of the miners. Script scriptPubKey1 = minerKey1.PubKey.ScriptPubKey; Script scriptPubKey2 = minerKey2.PubKey.ScriptPubKey; // Create the block that we want to validate. Block block = this.network.Consensus.ConsensusFactory.CreateBlock(); // Add dummy first transaction. Transaction transaction = this.network.CreateTransaction(); transaction.Inputs.Add(TxIn.CreateCoinbase(this.ChainIndexer.Tip.Height + 1)); transaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); Assert.True(transaction.IsCoinBase); // Add first transaction to block. block.Transactions.Add(transaction); // Create a previous transaction with scriptPubKey outputs. Transaction prevTransaction = this.network.CreateTransaction(); uint blockTime = (this.ChainIndexer.Tip.Header.Time + 60) & ~PosConsensusOptions.StakeTimestampMask; // Coins sent to miner 2. prevTransaction.Outputs.Add(new TxOut(Money.COIN * 5_000_000, scriptPubKey2)); // Coins sent to miner 1. prevTransaction.Outputs.Add(new TxOut(Money.COIN * 10_000_000, scriptPubKey1)); // Record the spendable outputs. unspentOutputs.Add(new OutPoint(prevTransaction, 0), new UnspentOutput(new OutPoint(prevTransaction, 0), new Coins(1, prevTransaction.Outputs[0], prevTransaction.IsCoinBase))); unspentOutputs.Add(new OutPoint(prevTransaction, 1), new UnspentOutput(new OutPoint(prevTransaction, 1), new Coins(1, prevTransaction.Outputs[1], prevTransaction.IsCoinBase))); // Create coin stake transaction. Transaction coinstakeTransaction = this.network.CreateTransaction(); coinstakeTransaction.Inputs.Add(new TxIn(new OutPoint(prevTransaction, 0))); coinstakeTransaction.Inputs.Add(new TxIn(new OutPoint(prevTransaction, 1))); // Coinstake marker. coinstakeTransaction.Outputs.Add(new TxOut(Money.Zero, (IDestination)null)); // Cirrus reward output coinstakeTransaction.Outputs.Add(new TxOut(this.network.Consensus.ProofOfStakeReward * StraxCoinviewRule.CirrusRewardPercentage / 100, StraxCoinstakeRule.CirrusRewardScript)); // Normal pay to public key that belongs to the second miner with value that // equals to the sum of the inputs. coinstakeTransaction.Outputs.Add(new TxOut(Money.COIN * 15_000_000, scriptPubKey2)); // The second miner signs the first transaction input which requires minerKey2. // Miner 2 will not have minerKey1 so we leave the second ScriptSig empty/invalid. new TransactionBuilder(this.network) .AddKeys(minerKey2) .AddCoins(new Coin(new OutPoint(prevTransaction, 0), prevTransaction.Outputs[0])) .SignTransactionInPlace(coinstakeTransaction); Assert.True(coinstakeTransaction.IsCoinStake); // Add second transaction to block. block.Transactions.Add(coinstakeTransaction); // Finalize the block and add it to the chain. block.Header.HashPrevBlock = this.ChainIndexer.Tip.HashBlock; block.Header.Time = blockTime; block.Header.Bits = block.Header.GetWorkRequired(this.network, this.ChainIndexer.Tip); block.SetPrivatePropertyValue("BlockSize", 1L); block.UpdateMerkleRoot(); Assert.True(BlockStake.IsProofOfStake(block)); // Add a signature to the block. ECDSASignature signature = minerKey2.Sign(block.GetHash()); (block as PosBlock).BlockSignature = new BlockSignature { Signature = signature.ToDER() }; // Execute the rule and check the outcome against what is expected. ConsensusException error = await Assert.ThrowsAsync <ConsensusException>(async() => await consensusManager.BlockMinedAsync(block)); Assert.Equal(ConsensusErrors.BadTransactionScriptError.Message, error.Message); }
public void key_test1() { BitcoinSecret bsecret1 = Network.Main.CreateBitcoinSecret(strSecret1); BitcoinSecret bsecret2 = Network.Main.CreateBitcoinSecret(strSecret2); BitcoinSecret bsecret1C = Network.Main.CreateBitcoinSecret(strSecret1C); BitcoinSecret bsecret2C = Network.Main.CreateBitcoinSecret(strSecret2C); Assert.Throws <FormatException>(() => Network.Main.CreateBitcoinSecret(strAddressBad)); Key key1 = bsecret1.PrivateKey; Assert.True(key1.IsCompressed == false); Assert.True(bsecret1.Copy(true).PrivateKey.IsCompressed == true); Assert.True(bsecret1.Copy(true).Copy(false).IsCompressed == false); Assert.True(bsecret1.Copy(true).Copy(false).ToString() == bsecret1.ToString()); Key key2 = bsecret2.PrivateKey; Assert.True(key2.IsCompressed == false); Key key1C = bsecret1C.PrivateKey; Assert.True(key1C.IsCompressed == true); Key key2C = bsecret2C.PrivateKey; Assert.True(key1C.IsCompressed == true); PubKey pubkey1 = key1.PubKey; PubKey pubkey2 = key2.PubKey; PubKey pubkey1C = key1C.PubKey; PubKey pubkey2C = key2C.PubKey; Assert.True(addr1.Hash == pubkey1.Hash); Assert.True(addr2.Hash == pubkey2.Hash); Assert.True(addr1C.Hash == pubkey1C.Hash); Assert.True(addr2C.Hash == pubkey2C.Hash); for (int n = 0; n < 16; n++) { string strMsg = String.Format("Very secret message {0}: 11", n); if (n == 10) { //Test one long message strMsg = String.Join(",", Enumerable.Range(0, 2000).Select(i => i.ToString()).ToArray()); } uint256 hashMsg = Hashes.Hash256(TestUtils.ToBytes(strMsg)); // normal signatures ECDSASignature sign1 = null, sign2 = null, sign1C = null, sign2C = null; List <Task> tasks = new List <Task>(); tasks.Add(Task.Run(() => sign1 = key1.Sign(hashMsg))); tasks.Add(Task.Run(() => sign2 = key2.Sign(hashMsg))); tasks.Add(Task.Run(() => sign1C = key1C.Sign(hashMsg))); tasks.Add(Task.Run(() => sign2C = key2C.Sign(hashMsg))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2C)))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(!pubkey1.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(pubkey1.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(!pubkey1.Verify(hashMsg, sign2C)))); tasks.Add(Task.Run(() => Assert.True(!pubkey2.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(!pubkey2.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(pubkey2.Verify(hashMsg, sign2C)))); tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(!pubkey1C.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(pubkey1C.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(!pubkey1C.Verify(hashMsg, sign2C)))); tasks.Add(Task.Run(() => Assert.True(!pubkey2C.Verify(hashMsg, sign1)))); tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2)))); tasks.Add(Task.Run(() => Assert.True(!pubkey2C.Verify(hashMsg, sign1C)))); tasks.Add(Task.Run(() => Assert.True(pubkey2C.Verify(hashMsg, sign2C)))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); // compact signatures (with key recovery) byte[] csign1 = null, csign2 = null, csign1C = null, csign2C = null; tasks.Add(Task.Run(() => csign1 = key1.SignCompact(hashMsg))); tasks.Add(Task.Run(() => csign2 = key2.SignCompact(hashMsg))); tasks.Add(Task.Run(() => csign1C = key1C.SignCompact(hashMsg))); tasks.Add(Task.Run(() => csign2C = key2C.SignCompact(hashMsg))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); PubKey rkey1 = null, rkey2 = null, rkey1C = null, rkey2C = null; tasks.Add(Task.Run(() => rkey1 = PubKey.RecoverCompact(hashMsg, csign1))); tasks.Add(Task.Run(() => rkey2 = PubKey.RecoverCompact(hashMsg, csign2))); tasks.Add(Task.Run(() => rkey1C = PubKey.RecoverCompact(hashMsg, csign1C))); tasks.Add(Task.Run(() => rkey2C = PubKey.RecoverCompact(hashMsg, csign2C))); Task.WaitAll(tasks.ToArray()); tasks.Clear(); Assert.True(rkey1.ToHex() == pubkey1.ToHex()); Assert.True(rkey2.ToHex() == pubkey2.ToHex()); Assert.True(rkey1C.ToHex() == pubkey1C.ToHex()); Assert.True(rkey2C.ToHex() == pubkey2C.ToHex()); Assert.True(sign1.IsLowR && sign1.ToDER().Length <= 70); Assert.True(sign2.IsLowR && sign2.ToDER().Length <= 70); Assert.True(sign1C.IsLowR && sign1C.ToDER().Length <= 70); Assert.True(sign2C.IsLowR && sign2C.ToDER().Length <= 70); } }