Beispiel #1
0
		public void EncryptedSecretNoECmultiply()
		{
			var tests = new[]
			{
				new {
				Passphrase= "TestingOneTwoThree",
				Encrypted = "6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg",
				Unencrypted = "5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR",
				Compressed = false
				},
				new {
				Passphrase= "Satoshi",
				Encrypted = "6PRNFFkZc2NZ6dJqFfhRoFNMR9Lnyj7dYGrzdgXXVMXcxoKTePPX1dWByq",
				Unencrypted = "5HtasZ6ofTHP6HCwTqTkLDuLQisYPah7aUnSKfC7h4hMUVw2gi5",
				Compressed = false
				},
				new {
				Passphrase= "TestingOneTwoThree",
				Encrypted = "6PYNKZ1EAgYgmQfmNVamxyXVWHzK5s6DGhwP4J5o44cvXdoY7sRzhtpUeo",
				Unencrypted = "L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP",
				Compressed = true
				},
				new {
				Passphrase= "Satoshi",
				Encrypted = "6PYLtMnXvfG3oJde97zRyLYFZCYizPU5T3LwgdYJz1fRhh16bU7u6PPmY7",
				Unencrypted = "KwYgW8gcxj1JWJXhPSu4Fqwzfhp5Yfi42mdYmMa4XqK7NJxXUSK7",
				Compressed = true
				}
			};

			//Slow test, run in parallel
			Parallel.ForEach(tests, test =>
			{
				var secret = new BitcoinSecret(test.Unencrypted, Network.Main);
				var encryptedKey = secret.PrivateKey.GetEncryptedBitcoinSecret(test.Passphrase, Network.Main);
				Assert.Equal(test.Encrypted, encryptedKey.ToString());

				var actualSecret = encryptedKey.GetKey(test.Passphrase);
				Assert.Equal(test.Unencrypted, actualSecret.GetBitcoinSecret(Network.Main).ToString());

				Assert.Equal(test.Compressed, actualSecret.IsCompressed);
			});
		}
Beispiel #2
0
		public void CanReadTestVectorPayments()
		{
			var tests = new[]
			{
				"data/payreq1_sha256_omitteddefault.paymentrequest",
				"data/payreq1_sha256.paymentrequest",
				"data/payreq2_sha256_omitteddefault.paymentrequest",
				"data/payreq2_sha256.paymentrequest",
				"data/payreq1_sha1_omitteddefault.paymentrequest",
				"data/payreq1_sha1.paymentrequest",
				"data/payreq2_sha1_omitteddefault.paymentrequest",
				"data/payreq2_sha1.paymentrequest",
			};

			foreach(var provider in new ICertificateServiceProvider[]
			{ 
#if WIN
				new WindowsCertificateServiceProvider(X509VerificationFlags.IgnoreNotTimeValid |
						X509VerificationFlags.AllowUnknownCertificateAuthority |
						X509VerificationFlags.IgnoreRootRevocationUnknown |
						X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown |
						X509VerificationFlags.IgnoreEndRevocationUnknown)
#endif
			})
			{
				PaymentRequest.DefaultCertificateServiceProvider = provider;
				foreach(var test in tests)
				{
					var bytes = File.ReadAllBytes(test);
					var request = PaymentRequest.Load(bytes);
					AssertEx.Equal(request.ToBytes(), bytes);

					Assert.True(request.VerifySignature());
					request = PaymentRequest.Load(PaymentRequest.Load(bytes).ToBytes());
					Assert.True(request.VerifySignature());
					Assert.True(request.VerifyChain());
				}
			}
		}
Beispiel #3
0
		public void EncryptedSecretECmultiplyNoLot()
		{
			var tests = new[]
			{
				new {
				Passphrase= "TestingOneTwoThree",
				PassphraseCode= "passphrasepxFy57B9v8HtUsszJYKReoNDV6VHjUSGt8EVJmux9n1J3Ltf1gRxyDGXqnf9qm",
				Encrypted = "6PfQu77ygVyJLZjfvMLyhLMQbYnu5uguoJJ4kMCLqWwPEdfpwANVS76gTX",
				Address = "1PE6TQi6HTVNz5DLwB1LcpMBALubfuN2z2",
				Unencrypted = "5K4caxezwjGCGfnoPTZ8tMcJBLB7Jvyjv4xxeacadhq8nLisLR2",
				Compressed = false
				},
				new {
				Passphrase= "Satoshi",
				PassphraseCode= "passphraseoRDGAXTWzbp72eVbtUDdn1rwpgPUGjNZEc6CGBo8i5EC1FPW8wcnLdq4ThKzAS",
				Encrypted = "6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd",
				Address = "1CqzrtZC6mXSAhoxtFwVjz8LtwLJjDYU3V",
				Unencrypted = "5KJ51SgxWaAYR13zd9ReMhJpwrcX47xTJh2D3fGPG9CM8vkv5sH",
				Compressed = false
				}
			};
			foreach(var test in tests)
			{
				//Can generate unencrypted key with password and encrypted key
				var encryptedKey = new BitcoinEncryptedSecretEC(test.Encrypted, Network.Main);
				Assert.Null(encryptedKey.LotSequence);
				var actualKey = encryptedKey.GetKey(test.Passphrase);
				Assert.Equal(test.Unencrypted, actualKey.GetBitcoinSecret(Network.Main).ToString());
				Assert.Equal(test.Address, actualKey.PubKey.GetAddress(Network.Main).ToString());
				Assert.Equal(test.Compressed, actualKey.IsCompressed);


				//Can generate same BitcoinPassphraseCode with by using same ownerentropy
				var passCode = new BitcoinPassphraseCode(test.PassphraseCode, Network.Main);
				Assert.Null(passCode.LotSequence);
				var actualPassCode = new BitcoinPassphraseCode(test.Passphrase, Network.Main, null, passCode.OwnerEntropy);
				Assert.Equal(passCode.ToString(), actualPassCode.ToString());

				//Can generate encrypted key from passcode
				var generatedEncryptedKey = passCode.GenerateEncryptedSecret(test.Compressed).EncryptedKey;
				AssertEx.CollectionEquals(passCode.OwnerEntropy, generatedEncryptedKey.OwnerEntropy);
				Assert.Equal(test.Compressed, generatedEncryptedKey.IsCompressed);
			}
		}
Beispiel #4
0
		public void EncryptedSecretECmultiplyNoLotSimple()
		{
			var compressedValues = new[] { false, true };
			foreach(var compressed in compressedValues)
			{
				var code = new BitcoinPassphraseCode("test", Network.Main, null);
				Assert.Null(code.LotSequence);
				var result = code.GenerateEncryptedSecret(compressed);
				Assert.True(result.ConfirmationCode.Check("test", result.GeneratedAddress));
				Assert.False(result.ConfirmationCode.Check("toto", result.GeneratedAddress));
				Assert.False(result.ConfirmationCode.Check("test", new Key().PubKey.GetAddress(Network.Main)));

				var decryptedKey = result.EncryptedKey.GetKey("test");
				Assert.Equal(result.GeneratedAddress.ToString(), decryptedKey.PubKey.GetAddress(Network.Main).ToString());

				Assert.Throws<SecurityException>(() => result.EncryptedKey.GetKey("wrong"));

				//Can regenerate same result with same seed
				var result2 = code.GenerateEncryptedSecret(compressed, seedb: result.Seed);
				var decryptedKey2 = result.EncryptedKey.GetKey("test");
				AssertEx.CollectionEquals(decryptedKey2.ToBytes(), decryptedKey.ToBytes());
			}
		}
Beispiel #5
0
		public void EncryptedSecretECmultiplyLotSequence()
		{
			var tests = new[]
			{
				new {
				Passphrase= "ΜΟΛΩΝ ΛΑΒΕ",
				PassphraseCode= "passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK",
				Encrypted = "6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH",
				Address = "1Lurmih3KruL4xDB5FmHof38yawNtP9oGf",
				Unencrypted = "5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D",
				ConfirmationCode = "cfrm38V8G4qq2ywYEFfWLD5Cc6msj9UwsG2Mj4Z6QdGJAFQpdatZLavkgRd1i4iBMdRngDqDs51",
				LotSequence = new LotSequence(806938,1),
				Compressed = false
				}
				,new {
				Passphrase= "MOLON LABE",
				PassphraseCode= "passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX",
				Encrypted = "6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j",
				Address = "1Jscj8ALrYu2y9TD8NrpvDBugPedmbj4Yh",
				Unencrypted = "5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8",
				ConfirmationCode = "cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD",
				LotSequence = new LotSequence(263183,1),
				Compressed = false
				}
			};

			foreach(var test in tests)
			{
				//Can generate unencrypted key with password and encrypted key
				var encryptedKey = new BitcoinEncryptedSecretEC(test.Encrypted, Network.Main);
				AssertSequenceEquals(test.LotSequence, encryptedKey.LotSequence);
				var actualKey = encryptedKey.GetKey(test.Passphrase);
				Assert.Equal(test.Unencrypted, actualKey.GetBitcoinSecret(Network.Main).ToString());
				Assert.Equal(test.Address, actualKey.PubKey.GetAddress(Network.Main).ToString());
				Assert.Equal(test.Compressed, actualKey.IsCompressed);


				//Can generate same BitcoinPassphraseCode with by using same ownerentropy
				var passCode = new BitcoinPassphraseCode(test.PassphraseCode, Network.Main);
				AssertSequenceEquals(test.LotSequence, passCode.LotSequence);
				var actualPassCode = new BitcoinPassphraseCode(test.Passphrase, Network.Main, test.LotSequence, passCode.OwnerEntropy);
				Assert.Equal(passCode.ToString(), actualPassCode.ToString());

				//Can verify confirmation
				var confirmation = new BitcoinConfirmationCode(test.ConfirmationCode, Network.Main);
				AssertSequenceEquals(confirmation.LotSequence, test.LotSequence);
				Assert.True(confirmation.Check(test.Passphrase, new BitcoinAddress(test.Address, Network.Main)));

				//Can generate encrypted key from passcode
				var generatedEncryptedKey = passCode.GenerateEncryptedSecret(test.Compressed).EncryptedKey;
				AssertEx.CollectionEquals(passCode.OwnerEntropy, generatedEncryptedKey.OwnerEntropy);
				Assert.Equal(test.Compressed, generatedEncryptedKey.IsCompressed);
			}
		}
Beispiel #6
0
		public void CanUseCompactVarInt()
		{
			var tests = new[]{
				new object[]{0UL, new byte[]{0}},
				new object[]{1UL, new byte[]{1}},
				new object[]{127UL, new byte[]{0x7F}},
				new object[]{128UL, new byte[]{0x80, 0x00}},
				new object[]{255UL, new byte[]{0x80, 0x7F}},
				new object[]{256UL, new byte[]{0x81, 0x00}},
				new object[]{16383UL, new byte[]{0xFE, 0x7F}},
				//new object[]{16384UL, new byte[]{0xFF, 0x00}},
				//new object[]{16511UL, new byte[]{0x80, 0xFF, 0x7F}},
				//new object[]{65535UL, new byte[]{0x82, 0xFD, 0x7F}},
				new object[]{(ulong)1 << 32, new byte[]{0x8E, 0xFE, 0xFE, 0xFF, 0x00}},
			};
			foreach(var test in tests)
			{
				ulong val = (ulong)test[0];
				byte[] expectedBytes = (byte[])test[1];

				AssertEx.CollectionEquals(new CompactVarInt(val, sizeof(ulong)).ToBytes(), expectedBytes);
				AssertEx.CollectionEquals(new CompactVarInt(val, sizeof(uint)).ToBytes(), expectedBytes);

				var compact = new CompactVarInt(sizeof(ulong));
				compact.ReadWrite(expectedBytes);
				Assert.Equal(val, compact.ToLong());

				compact = new CompactVarInt(sizeof(uint));
				compact.ReadWrite(expectedBytes);
				Assert.Equal(val, compact.ToLong());
			}

			foreach(var i in Enumerable.Range(0, 65535 * 4))
			{
				var compact = new CompactVarInt((ulong)i, sizeof(ulong));
				var bytes = compact.ToBytes();
				compact = new CompactVarInt(sizeof(ulong));
				compact.ReadWrite(bytes);
				Assert.Equal((ulong)i, compact.ToLong());
			}
		}
Beispiel #7
0
		public void script_combineSigs()
		{
			Key[] keys = new[] { new Key(), new Key(), new Key() };
			var txFrom = CreateCreditingTransaction(keys[0].PubKey.Hash.ScriptPubKey);
			var txTo = CreateSpendingTransaction(new Script(), txFrom);

			Script scriptPubKey = txFrom.Outputs[0].ScriptPubKey;
			Script scriptSig = txTo.Inputs[0].ScriptSig;

			Script empty = new Script();
			Script combined = Script.CombineSignatures(scriptPubKey, txTo, 0, empty, empty);
			Assert.True(combined.ToBytes().Length == 0);

			// Single signature case:
			SignSignature(keys, txFrom, txTo, 0); // changes scriptSig
			scriptSig = txTo.Inputs[0].ScriptSig;
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
			Assert.True(combined == scriptSig);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
			Assert.True(combined == scriptSig);
			Script scriptSigCopy = scriptSig.Clone();
			// Signing again will give a different, valid signature:
			SignSignature(keys, txFrom, txTo, 0);
			scriptSig = txTo.Inputs[0].ScriptSig;

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
			Assert.True(combined == scriptSigCopy || combined == scriptSig);


			// P2SH, single-signature case:
			Script pkSingle = PayToPubkeyTemplate.Instance.GenerateScriptPubKey(keys[0].PubKey);
			scriptPubKey = pkSingle.Hash.ScriptPubKey;
			txFrom.Outputs[0].ScriptPubKey = scriptPubKey;
			txTo.Inputs[0].PrevOut = new OutPoint(txFrom, 0);

			SignSignature(keys, txFrom, txTo, 0, pkSingle);
			scriptSig = txTo.Inputs[0].ScriptSig;

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
			Assert.True(combined == scriptSig);

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
			scriptSig = txTo.Inputs[0].ScriptSig;
			Assert.True(combined == scriptSig);
			scriptSigCopy = scriptSig.Clone();

			SignSignature(keys, txFrom, txTo, 0);
			scriptSig = txTo.Inputs[0].ScriptSig;

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
			Assert.True(combined == scriptSigCopy || combined == scriptSig);
			// dummy scriptSigCopy with placeholder, should always choose non-placeholder:
			scriptSigCopy = new Script(OpcodeType.OP_0, Op.GetPushOp(pkSingle.ToBytes()));
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig);
			Assert.True(combined == scriptSig);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy);
			Assert.True(combined == scriptSig);

			// Hardest case:  Multisig 2-of-3
			scriptPubKey = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(2, keys.Select(k => k.PubKey).ToArray());
			txFrom.Outputs[0].ScriptPubKey = scriptPubKey;
			txTo.Inputs[0].PrevOut = new OutPoint(txFrom, 0);

			SignSignature(keys, txFrom, txTo, 0);
			scriptSig = txTo.Inputs[0].ScriptSig;

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
			Assert.True(combined == scriptSig);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig);
			Assert.True(combined == scriptSig);

			// A couple of partially-signed versions:
			uint256 hash1 = scriptPubKey.SignatureHash(txTo, 0, SigHash.All);
			var sig1 = new TransactionSignature(keys[0].Sign(hash1), SigHash.All);

			uint256 hash2 = scriptPubKey.SignatureHash(txTo, 0, SigHash.None);
			var sig2 = new TransactionSignature(keys[1].Sign(hash2), SigHash.None);


			uint256 hash3 = scriptPubKey.SignatureHash(txTo, 0, SigHash.Single);
			var sig3 = new TransactionSignature(keys[2].Sign(hash3), SigHash.Single);


			// Not fussy about order (or even existence) of placeholders or signatures:
			Script partial1a = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig1.ToBytes()) + OpcodeType.OP_0;
			Script partial1b = new Script() + OpcodeType.OP_0 + OpcodeType.OP_0 + Op.GetPushOp(sig1.ToBytes());
			Script partial2a = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig2.ToBytes());
			Script partial2b = new Script() + Op.GetPushOp(sig2.ToBytes()) + OpcodeType.OP_0;
			Script partial3a = new Script() + Op.GetPushOp(sig3.ToBytes());
			Script partial3b = new Script() + OpcodeType.OP_0 + OpcodeType.OP_0 + Op.GetPushOp(sig3.ToBytes());
			Script partial3c = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig3.ToBytes()) + OpcodeType.OP_0;
			Script complete12 = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig1.ToBytes()) + Op.GetPushOp(sig2.ToBytes());
			Script complete13 = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig1.ToBytes()) + Op.GetPushOp(sig3.ToBytes());
			Script complete23 = new Script() + OpcodeType.OP_0 + Op.GetPushOp(sig2.ToBytes()) + Op.GetPushOp(sig3.ToBytes());

			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b);
			Assert.True(combined == partial1a);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a);
			Assert.True(combined == complete12);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial1a);
			Assert.True(combined == complete12);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial1b, partial2b);
			Assert.True(combined == complete12);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial1b);
			Assert.True(combined == complete13);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial3a);
			Assert.True(combined == complete23);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial2b);
			Assert.True(combined == complete23);
			combined = Script.CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial3a);
			Assert.True(combined == partial3c);
		}
Beispiel #8
0
		public void CanConvertText()
		{
			string testPhrase = "é ^ç hello \"12345\"  wooorld";
			var tests = new[]
			{
				new 
				{
					Encoder = Encoders.Hex,	
					Input = testPhrase,
					Expected = "c3a9205ec3a72068656c6c6f20223132333435222020776f6f6f726c64",
				},
				new 
				{
					Encoder = Encoders.Base58,
					Input = testPhrase,
					Expected = "9tBRc991GhmZNsV5qSyynUsnRCNvxdvvWDmj3nAP"
				},
				new 
				{
					Encoder = Encoders.Base58Check,
					Input = testPhrase,
					//Different from brainwallet, because brainwallet code convert the data to bitcoin address instead of directely formating in base58check (ie : the data followed be the 4 hash bytes)
					Expected = "2189xoVGsHC6VbVPUrKeH3fhT429VDruzdgUJFk37PNskG"
				},
				new 
				{
					Encoder = Encoders.Base64,
					Input = testPhrase,
					Expected = "w6kgXsOnIGhlbGxvICIxMjM0NSIgIHdvb29ybGQ="
				},
				//Not yet implemented
				//new 
				//{
				//	Encoder = Encoders.Bin,
				//	Input = testPhrase,
				//	Expected = "11000011 10101001 00100000 01011110 11000011 10100111 00100000 01101000 01100101 01101100 01101100 01101111 00100000 00100010 00110001 00110010 00110011 00110100 00110101 00100010 00100000 00100000 01110111 01101111 01101111 01101111 01110010 01101100 01100100"
				//},
				//Not yet implemented
				//new 
				//{
				//	Encoder = Encoders.Dec,
				//	Input = testPhrase,
				//	Expected = "5275000693703128425041367611933003709099386868005962673424426230508644"
				//},
				//Useless for bitcoin
				//new 
				//{
				//	Encoder = Encoders.RFC1751,
				//	Input = testPhrase,
				//	Expected = "A A OWE BANG BAN BUST KITE ARK HAT SEEN OBOE GRIM KIN GASH GLOB COAT BANE DUN JO MILL SIGH SLID MAD PAR"
				//},
				//Useless for bitcoin
				//new 
				//{
				//	Encoder = Encoders.Poetry,
				//	Input = testPhrase,
				//	Expected = "perfect perfect perfect soul stone royal fault companion sharp cross build leap possess possibly yet bone magic beam illuminate moonlight foul juice darkness universe"
				//},
				//Useless for bitcoin
				//new 
				//{
				//	Encoder = Encoders.Rot13,
				//	Input = testPhrase,
				//	Expected = "é ^ç uryyb \"12345\"  jbbbeyq"
				//},
				//Useless for bitcoin
				//new 
				//{
				//	Encoder = Encoders.Easy16,
				//	Input = testPhrase,
				//	Expected = "aaaa aauf reda houf rkda jwjh juju jnda eriu\r\nddfs fdff fgfh ddda dakk jnjn jnkd jujg euhs"
				//},
			};

			foreach(var test in tests)
			{
				var input = Encoding.UTF8.GetBytes(test.Input);
				var encoded = test.Encoder.EncodeData(input);
				Assert.Equal(test.Expected, encoded);

				try
				{
					var decoded = test.Encoder.DecodeData(encoded);
					AssertEx.CollectionEquals(input, decoded);
				}
				catch(NotSupportedException)
				{
				}
			}

			var expectedText = "2189xoVGsHC6VbVPUrKeH3fhT429VDruzdgUJFk37PNskG";
			var input1 = Encoding.UTF8.GetBytes("---é ^ç hello \"12345\"  wooorld---");
			var encoded1 = Encoders.Base58Check.EncodeData(input1, 3, input1.Length-6);
			Assert.Equal(expectedText, encoded1);

			var decoded1 = Encoders.Base58Check.DecodeData(encoded1);
			AssertEx.CollectionEquals(input1.SafeSubarray(3, input1.Length-6), decoded1);
		}