예제 #1
0
        public void KeyPairTest()
        {
            //sr25519, schnorrkel, without psw or ///Substrate

            var mnemonic = "donor rocket find fan language damp yellow crouch attend meat hybrid pulse";
            var keyPair1 = Mnemonic.GetKeyPairFromMnemonic(mnemonic, "", BIP39Wordlist.English, ExpandMode.Ed25519);

            Assert.AreEqual("5CSFNKvSFchQd7TjuuvPca1RheLAqZfFKiqAM6Fv6us9QhvR", Utils.GetAddressFrom(keyPair1.Public.Key));

            var keyPair2 = Mnemonic.GetKeyPairFromMnemonic(mnemonic, "Substrate", BIP39Wordlist.English, ExpandMode.Ed25519);

            Assert.AreEqual("5FRbTVsuNAXFDq19gSnwihXUDMeEQKfhDnUWgYuUq6jFknVq", Utils.GetAddressFrom(keyPair2.Public.Key));

            Assert.AreEqual(32, keyPair2.Secret.key.GetBytes().Length);
            Assert.AreEqual("0x7CFF5CEAEEAF93EF4675DFCA17FF1383B66DF5141F491309D70A5C1087D3910D", Utils.Bytes2HexString(keyPair2.Secret.key.GetBytes()));
            Assert.AreEqual("0x767B646A4BEAD69074C77B69D142A21978D867357A2227D16370F8A675991011", Utils.Bytes2HexString(keyPair2.Secret.nonce));
            Assert.AreEqual("0x7CFF5CEAEEAF93EF4675DFCA17FF1383B66DF5141F491309D70A5C1087D3910D" +
                            "767B646A4BEAD69074C77B69D142A21978D867357A2227D16370F8A675991011", Utils.Bytes2HexString(keyPair2.Secret.ToBytes()));
            Assert.AreEqual("0x94A34FAF4D464F0404C41EFEAE6C476C21755492F77B5715CE5291CE601A8318", Utils.Bytes2HexString(keyPair2.Public.Key));

            var secret = Mnemonic.GetSecretKeyFromMnemonic(mnemonic, "Substrate", BIP39Wordlist.English);

            Assert.AreEqual("0x9AD12F46F904DA56073948B789F7FD8A5CD1A2E79480A5986DFB7C814E228586", Utils.Bytes2HexString(secret));

            var miniSecret = new MiniSecret(secret, ExpandMode.Ed25519);
            var keyPair3   = miniSecret.GetPair();

            Assert.AreEqual(keyPair2.Public.Key, keyPair3.Public.Key);
            Assert.AreEqual(keyPair2.Secret.ToBytes(), keyPair3.Secret.ToBytes());
        }
예제 #2
0
        public void Sr25519KeyPairTest()
        {
            // Secret Key URI `//Alice` is account:
            // Secret seed:      0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a
            // Public key(hex):  0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
            // Account ID:       0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
            // SS58 Address:     5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY

            var miniSecretAlice = new MiniSecret(Utils.HexToByteArray("0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a"), ExpandMode.Ed25519);
            var keyPairAlice    = miniSecretAlice.GetPair();

            Assert.AreEqual("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d", Utils.Bytes2HexString(keyPairAlice.Public.Key).ToLower());
            Assert.AreEqual("0x925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011", Utils.Bytes2HexString(keyPairAlice.Secret.nonce).ToLower());
            Assert.AreEqual("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", Utils.GetAddressFrom(keyPairAlice.Public.Key));

            // Secret Key URI `//Bob` is account:
            // Secret seed:      0x398f0c28f98885e046333d4a41c19cee4c37368a9832c6502f6cfd182e2aef89
            // Public key(hex):  0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48
            // Account ID:       0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48
            // SS58 Address:     5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty

            var miniSecretBob = new MiniSecret(Utils.HexToByteArray("0x398f0c28f98885e046333d4a41c19cee4c37368a9832c6502f6cfd182e2aef89"), ExpandMode.Ed25519);
            var keyPairBob    = miniSecretBob.GetPair();

            Assert.AreEqual("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", Utils.Bytes2HexString(keyPairBob.Public.Key).ToLower());
            Assert.AreEqual("0x41ae88f85d0c1bfc37be41c904e1dfc01de8c8067b0d6d5df25dd1ac0894a325", Utils.Bytes2HexString(keyPairBob.Secret.nonce).ToLower());
            Assert.AreEqual("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", Utils.GetAddressFrom(keyPairBob.Public.Key));
        }
예제 #3
0
        /// <summary>
        /// Get a key pair from mnemonic
        /// </summary>
        /// <param name="mnemonic"></param>
        /// <param name="password"></param>
        /// <param name="bIP39Wordlist"></param>
        /// <param name="expandMode"></param>
        /// <returns></returns>
        public static KeyPair GetKeyPairFromMnemonic(string mnemonic, string password, BIP39Wordlist bIP39Wordlist, ExpandMode expandMode)
        {
            var secretBytes = GetSecretKeyFromMnemonic(mnemonic, password, bIP39Wordlist);
            var miniSecret  = new MiniSecret(secretBytes, expandMode);

            return(new KeyPair(miniSecret.ExpandToPublic(), miniSecret.ExpandToSecret()));
        }
예제 #4
0
        /// <summary>
        /// Unlocks the asynchronous.
        /// </summary>
        /// <param name="password">The password.</param>
        /// <param name="noCheck">if set to <c>true</c> [no check].</param>
        /// <returns></returns>
        /// <exception cref="Exception">Public key check failed!</exception>
        public async Task <bool> UnlockAsync(string password, bool noCheck = false)
        {
            if (IsUnlocked || !IsCreated)
            {
                Logger.Warn("Wallet is already unlocked or doesn't exist.");
                return(IsUnlocked && IsCreated);
            }

            Logger.Info("Unlock new wallet.");

            try
            {
                var pswBytes = Encoding.UTF8.GetBytes(password);

                pswBytes = SHA256.Create().ComputeHash(pswBytes);

                var seed = ManagedAes.DecryptStringFromBytes_Aes(_walletFile.EncryptedSeed, pswBytes, _walletFile.Salt);

                byte[] publicKey  = null;
                byte[] privateKey = null;
                switch (_walletFile.KeyType)
                {
                case KeyType.Ed25519:
                    Ed25519.KeyPairFromSeed(out publicKey, out privateKey, Utils.HexToByteArray(seed));
                    break;

                case KeyType.Sr25519:
                    var miniSecret = new MiniSecret(Utils.HexToByteArray(seed), ExpandMode.Ed25519);
                    var getPair    = miniSecret.GetPair();
                    privateKey = getPair.Secret.ToBytes();
                    publicKey  = getPair.Public.Key;
                    break;
                }

                if (noCheck || !publicKey.SequenceEqual(_walletFile.PublicKey))
                {
                    throw new Exception("Public key check failed!");
                }

                Account = Account.Build(_walletFile.KeyType, privateKey, publicKey);
            }
            catch (Exception exception)
            {
                Logger.Warn($"Couldn't unlock the wallet with this password. {exception}");
                return(false);
            }


            if (IsOnline)
            {
                _subscriptionAccountInfo = await SubscribeAccountInfoAsync();
            }

            return(true);
        }
예제 #5
0
        /// <summary>
        /// Creates the asynchronous.
        /// </summary>
        /// <param name="password">The password.</param>
        /// <param name="mnemonic">The mnemonic.</param>
        /// <param name="walletName">Name of the wallet.</param>
        /// <returns></returns>
        public async Task <bool> CreateAsync(string password, string mnemonic, string walletName = DefaultWalletName)
        {
            if (IsCreated)
            {
                Logger.Warn("Wallet already created.");
                return(true);
            }

            if (!IsValidPassword(password))
            {
                Logger.Warn(
                    "Password isn't is invalid, please provide a proper password. Minmimu eight size and must have upper, lower and digits.");
                return(false);
            }

            Logger.Info("Creating new wallet from mnemonic.");

            var seed = Mnemonic.GetSecretKeyFromMnemonic(mnemonic, "Substrate", BIP39Wordlist.English);

            var randomBytes = new byte[48];

            _random.NextBytes(randomBytes);

            var memoryBytes = randomBytes.AsMemory();

            var pswBytes = Encoding.UTF8.GetBytes(password);

            var salt = memoryBytes.Slice(0, 16).ToArray();

            pswBytes = SHA256.Create().ComputeHash(pswBytes);

            var encryptedSeed =
                ManagedAes.EncryptStringToBytes_Aes(Utils.Bytes2HexString(seed, Utils.HexStringFormat.Pure), pswBytes, salt);

            var miniSecret = new MiniSecret(seed, ExpandMode.Ed25519);
            var getPair    = miniSecret.GetPair();

            var keyType = KeyType.Sr25519;

            _walletFile = new WalletFile(keyType, getPair.Public.Key, encryptedSeed, salt);

            Caching.Persist(AddWalletFileType(walletName), _walletFile);

            Account = Account.Build(keyType, getPair.Secret.ToBytes(), getPair.Public.Key);

            if (IsOnline)
            {
                _subscriptionAccountInfo = await SubscribeAccountInfoAsync();
            }

            return(true);
        }
예제 #6
0
        public void Sr25519SignatureTest()
        {
            var miniSecretAlice = new MiniSecret(Utils.HexToByteArray("0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a"), ExpandMode.Ed25519);
            var keyPairAlice    = miniSecretAlice.GetPair();

            var messageLength = _random.Next(10, 200);
            var message       = new byte[messageLength];

            _random.NextBytes(message);

            var simpleSign = Schnorrkel.Sr25519v091.SignSimple(keyPairAlice, message);

            Assert.True(Schnorrkel.Sr25519v091.Verify(simpleSign, keyPairAlice.Public.Key, message));
        }