public void TransactionGenerateSignAndVerify(bool useBouncyCastle) { // Generate a keypair EthereumEcdsa ecdsa; if (useBouncyCastle) { ecdsa = EthereumEcdsaBouncyCastle.Generate(new SystemRandomAccountDerivation()); } else { ecdsa = EthereumEcdsaNative.Generate(new SystemRandomAccountDerivation()); } // Obtain our sender address for our keypair. Address actualSender = new Address(ecdsa.GetPublicKeyHash()); // Define our chain IDs to test, including null to test pre-spurious dragon. EthereumChainID?[] chainIDs = new EthereumChainID?[] { null, EthereumChainID.Ethereum_MainNet }; // Define our transaction to test // Create a new transaction. Transaction transaction = new Transaction(21, 18000000000, 100000, new Address("0xa593094cebb06bf34df7311845c2a34996b52324"), 1000000000000, null); // Loop for each chain ID to test. foreach (EthereumChainID?chainID in chainIDs) { // Sign our data transaction.Sign(ecdsa, chainID); // Obtain our sender from our signed transaction, verify it matches our actual sender. Address transactionSender = transaction.GetSenderAddress(); Assert.Equal(actualSender.ToString(), transactionSender.ToString()); } }
public void ProvidedKeySigning(bool useBouncyCastle) { // Use a provided private key to sign two different transactions and verify the sender should be the same. string privateKeyStr = "e815acba8fcf085a0b4141060c13b8017a08da37f2eb1d6a5416adbb621560ef"; EthereumEcdsa provider; if (useBouncyCastle) { provider = new EthereumEcdsaBouncyCastle(privateKeyStr.HexToBytes(), EthereumEcdsaKeyType.Private); } else { provider = new EthereumEcdsaNative(privateKeyStr.HexToBytes(), EthereumEcdsaKeyType.Private); } // Signing two different transactions with or without a chain ID should yield the same sender. Transaction transaction1 = new Transaction(25, 77044660770, 100100, new Address("0xffff094cebb06bf34df7311845c2a34996b52324"), 2000055000000, null); Transaction transaction2 = new Transaction(21, 18000000000, 100000, new Address("0xa593094cebb06bf34df7311845c2a34996b52324"), 1000000000000, null); transaction1.Sign(provider); transaction2.Sign(provider, EthereumChainID.Ethereum_MainNet); Assert.Equal("0x75c8aa4b12bc52c1f1860bc4e8af981d6542cccd", transaction1.GetSenderAddress().ToString()); Assert.Equal("0x75c8aa4b12bc52c1f1860bc4e8af981d6542cccd", transaction2.GetSenderAddress().ToString()); Assert.Equal("0x75c8aa4b12bc52c1f1860bc4e8af981d6542cccd", new Address(provider.GetPublicKeyHash()).ToString()); }
public void GenerateSignRecoverVerify(bool useBouncyCastle) { // Generate ECDSA keypair, compute a hash, sign it, then recover the public key from the signature and verify it matches. EthereumEcdsa provider; if (useBouncyCastle) { provider = EthereumEcdsaBouncyCastle.Generate(new SystemRandomAccountDerivation()); } else { provider = EthereumEcdsaNative.Generate(new SystemRandomAccountDerivation()); } // Sign a hash. byte[] hash = KeccakHash.ComputeHashBytes(new byte[] { 11, 22, 33, 44 }); (byte RecoveryID, BigInteger r, BigInteger s)signature = provider.SignData(hash); // Recover the public key for the signature we just made and verify it. EthereumEcdsa recovered = null; if (useBouncyCastle) { recovered = EthereumEcdsaBouncyCastle.Recover(hash, signature.RecoveryID, signature.r, signature.s); } else { recovered = EthereumEcdsaNative.Recover(hash, signature.RecoveryID, signature.r, signature.s); } Assert.True(provider.GetPublicKeyHash().ValuesEqual(recovered.GetPublicKeyHash())); // Verify the signature we just made. Assert.True(recovered.VerifyData(hash, signature.r, signature.s)); // Generate a new ECDSA keypair (to verify other keypairs can't pass verification for signatures they didn't create). EthereumEcdsa provider2; if (useBouncyCastle) { provider2 = EthereumEcdsaBouncyCastle.Generate(new SystemRandomAccountDerivation()); } else { provider2 = EthereumEcdsaNative.Generate(new SystemRandomAccountDerivation()); } // Verify the prior signature cannot be verified with this new keypair. Assert.False(provider2.VerifyData(hash, signature.r, signature.s)); }
public void PublicKeyFormatTests(bool useBouncyCastle) { // Test compressed, uncompressed, ethereum format public keys and verify they all equal the same resulting key. string privateKeyStr = "e815acba8fcf085a0b4141060c13b8017a08da37f2eb1d6a5416adbb621560ef"; EthereumEcdsa provider; if (useBouncyCastle) { provider = new EthereumEcdsaBouncyCastle(privateKeyStr.HexToBytes(), EthereumEcdsaKeyType.Private); } else { provider = new EthereumEcdsaNative(privateKeyStr.HexToBytes(), EthereumEcdsaKeyType.Private); } // Obtain our public key in different formats. byte[] publicKeyCompressed = provider.ToPublicKeyArray(true, false); byte[] publicKeyUncompressed = provider.ToPublicKeyArray(false, false); byte[] publicKeyEthereum = provider.ToPublicKeyArray(false, true); // Put them into a singular array to test. byte[][] publicKeys = new byte[][] { publicKeyCompressed, publicKeyUncompressed, publicKeyEthereum }; // Loop for each format to test. for (int i = 0; i < publicKeys.Length; i++) { // Parse the public key that is indexed. EthereumEcdsa publicKeyProvider; if (useBouncyCastle) { publicKeyProvider = new EthereumEcdsaBouncyCastle(publicKeys[i], EthereumEcdsaKeyType.Public); } else { publicKeyProvider = new EthereumEcdsaNative(publicKeys[i], EthereumEcdsaKeyType.Public); } // Verify the public key hashes match Assert.Equal(provider.GetPublicKeyHash().ToHexString(), publicKeyProvider.GetPublicKeyHash().ToHexString()); } }
public void SignAndVerify(bool useBouncyCastle) { // Generate ECDSA keypair, compute a hash, sign it, then recover the public key from the signature and verify it matches. EthereumEcdsa provider; if (useBouncyCastle) { provider = EthereumEcdsaBouncyCastle.Generate(new SystemRandomAccountDerivation()); } else { provider = EthereumEcdsaNative.Generate(new SystemRandomAccountDerivation()); } byte[] hash = KeccakHash.ComputeHashBytes(new byte[] { 11, 22, 33, 44 }); (byte RecoveryID, BigInteger r, BigInteger s)signature = provider.SignData(hash); EthereumEcdsa recovered = EthereumEcdsa.Recover(hash, signature.RecoveryID, signature.r, signature.s); Assert.True(provider.GetPublicKeyHash().ValuesEqual(recovered.GetPublicKeyHash())); }
public void ComputeECDHKeyTest(bool useBouncyCastle, string privateKeyStr, string publicKeyStr, string expectedSecretStr) { // Generate ECDSA keypair EthereumEcdsa privateKey = null; EthereumEcdsa publicKey = null; if (useBouncyCastle) { privateKey = new EthereumEcdsaBouncyCastle(privateKeyStr.HexToBytes(), EthereumEcdsaKeyType.Private); publicKey = new EthereumEcdsaBouncyCastle(publicKeyStr.HexToBytes(), EthereumEcdsaKeyType.Public); } else { privateKey = new EthereumEcdsaNative(privateKeyStr.HexToBytes(), EthereumEcdsaKeyType.Private); publicKey = new EthereumEcdsaNative(publicKeyStr.HexToBytes(), EthereumEcdsaKeyType.Public); } // Compute a shared key. byte[] data = privateKey.ComputeECDHKey(publicKey); Assert.Equal(expectedSecretStr, data.ToHexString(false)); }