Beispiel #1
0
        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());
            }
        }
Beispiel #2
0
        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());
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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());
            }
        }
Beispiel #5
0
        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()));
        }
Beispiel #6
0
        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));
        }