示例#1
0
        private static PrivateKey GetPrivateKey(string msg)
        {
            while (true)
            {
                ConsoleMessage.Write(ConsoleColor.Yellow, msg);
                string input = Console.ReadLine();

                if (input.Length != 64)
                {
                    ConsoleMessage.WriteLine(ConsoleColor.Red, "Invalid private key, should be 64 characters long! Try again.\n");

                    continue;
                }

                if (!input.IsHex())
                {
                    ConsoleMessage.WriteLine(ConsoleColor.Red, "Invalid private key, is not a valid hexadecimal string!");

                    continue;
                }

                var p = new PrivateKey(Encoding.HexStringToByteArray(input));

                if (!KeyOps.IsValidKey(p))
                {
                    ConsoleMessage.WriteLine(ConsoleColor.Red, "Invalid private key, is not a valid ED25519 key!");
                }

                return(p);
            }
        }
        public void TestAddressesBothWays()
        {
            for (int i = 0; i < 10; i++)
            {
                WalletKeys w = KeyOps.GenerateWalletKeys();

                /* TRTL, Monero, random different lengths */
                ulong[] prefixes = new ulong[] { 0x3bbb1d, 0x12, 0x0, 0x11, 0x222, 0x3333, 0x44444, 0x555555, 0x6666666 };

                foreach (ulong prefix in prefixes)
                {
                    string derivedAddress1 = Addresses.AddressFromKeys(w.privateSpendKey, w.privateViewKey, prefix);

                    Addresses.KeysFromAddress(derivedAddress1, prefix).Do(
                        error => Assert.Fail($"Failed to parse keys from address: {error}"),
                        keys => {
                        Assert.AreEqual <PublicKey>(w.publicSpendKey, keys.spendKey);
                        Assert.AreEqual <PublicKey>(w.publicViewKey, keys.viewKey);
                    }
                        );

                    string derivedAddress2 = Addresses.AddressFromKeys(w.publicSpendKey, w.publicViewKey, prefix);

                    Addresses.KeysFromAddress(derivedAddress2, prefix).Do(
                        error => Assert.Fail($"Failed to parse keys from address: {error}"),
                        keys => {
                        Assert.AreEqual <PublicKey>(w.publicSpendKey, keys.spendKey);
                        Assert.AreEqual <PublicKey>(w.publicViewKey, keys.viewKey);
                    }
                        );
                }
            }
        }
示例#3
0
        /// <summary>
        /// Determines if the WebKey object is valid according to the rules for
        /// each of the possible WebKeyTypes. For more information, see WebKeyTypes.
        /// </summary>
        /// <returns>true if the WebKey is valid</returns>
        public virtual bool IsValid()
        {
            // MUST have kty
            if (string.IsNullOrEmpty(Kty))
            {
                return(false);
            }

            // Validate Key Operations
            if (KeyOps != null && KeyOps.Count() != 0)
            {
                if (!KeyOps.All((op) => { return(JsonWebKeyOperation.AllOperations.Contains(op)); }))
                {
                    return(false);
                }
            }

            // Per-kty validation
            switch (Kty)
            {
            case JsonWebKeyType.EllipticCurve:
                break;

            case JsonWebKeyType.Octet:
                return(IsValidOctet());

            case JsonWebKeyType.Rsa:
                return(IsValidRsa());

            case JsonWebKeyType.RsaHsm:
                return(IsValidRsaHsm());
            }

            return(false);
        }
示例#4
0
        private static PrivateKeys GetPrivateKeysFromSeed()
        {
            while (true)
            {
                ConsoleMessage.Write(ConsoleColor.Yellow, "Mnemonic seed (25 words): ");
                string input = Console.ReadLine();

                switch (Mnemonics.MnemonicToPrivateKey(input))
                {
                case ILeft <Error> error:
                {
                    ConsoleMessage.WriteLine(ConsoleColor.Red, error.Value.errorMessage);
                    ConsoleMessage.WriteLine("Try again.\n");
                    continue;
                }

                case IRight <PrivateKey> key:
                {
                    var privateSpendKey = key.Value;

                    var privateViewKey
                        = KeyOps.GenerateDeterministicKeys(privateSpendKey)
                          .privateKey;

                    return(new PrivateKeys(privateSpendKey, privateViewKey));
                }
                }
            }
        }
        NewWallet(string filename, string password,
                  PrivateKey privateViewKey, string address)
        {
            if (!KeyOps.IsValidKey(privateViewKey))
            {
                return(Either.Left <Error, WalletBackend>(
                           Error.InvalidPrivateKey()
                           ));
            }

            if (File.Exists(filename))
            {
                return(Either.Left <Error, WalletBackend>(
                           Error.FileAlreadyExists()
                           ));
            }

            /* If we can get the keys from the address, make a new view wallet,
             * save it, and return it. Else, return the error */
            return(Addresses.KeysFromAddress(address).Fmap(
                       publicKeys => {
                WalletBackend wallet = new WalletBackend(
                    filename, password, privateViewKey, publicKeys
                    );

                wallet.Save();

                return Either.Right <Error, WalletBackend>(wallet);
            }
                       ));
        }
        /* Make a new wallet with the given filename and password, returning
         * either the wallet or an error */
        public static IEither <Error, WalletBackend> NewWallet(string filename,
                                                               string password)
        {
            WalletKeys keys = KeyOps.GenerateWalletKeys();

            return(NewWallet(filename, password, keys.GetPrivateKeys()));
        }
        NewWallet(string filename, string password,
                  PrivateKeys privateKeys)
        {
            if (!KeyOps.IsValidKey(privateKeys.spendKey) ||
                !KeyOps.IsValidKey(privateKeys.viewKey))
            {
                return(Either.Left <Error, WalletBackend>(
                           Error.InvalidPrivateKey()
                           ));
            }

            if (File.Exists(filename))
            {
                return(Either.Left <Error, WalletBackend>(
                           Error.FileAlreadyExists()
                           ));
            }

            /* Create the wallet instance */
            WalletBackend wallet = new WalletBackend(
                filename, password, privateKeys
                );

            /* Save it */
            wallet.Save();

            /* Return it */
            return(Either.Right <Error, WalletBackend>(wallet));
        }
示例#8
0
        public JObject GetPublicJwt()
        {
            var result = new JObject
            {
                { "kty", MAPPING_KEYTYPEENUM_TO_STR[Kty] },
                { "use", MAPPING_USAGESENUM_TO_STR[Use] },
                { "alg", Alg },
                { "kid", Kid }
            };

            if (KeyOps.Any())
            {
                result.Add("key_ops", JArray.FromObject(KeyOps.Where(k => PUBLIC_KEY_OPERATIONS.Contains(k)).Select(s => MAPPING_KEYOPERATIONENUM_TO_STR[s])));
            }

            var publicFields = MAPPING_KEYTYPE_TO_PUBLIC_KEYS[Kty];

            foreach (var kvp in Content)
            {
                if (!publicFields.Contains(kvp.Key))
                {
                    continue;
                }

                result.Add(kvp.Key, kvp.Value);
            }

            return(result);
        }
示例#9
0
        public void TestAreKeysDeterministic()
        {
            /* A private spend key and private view key derived pair */
            PrivateKey a1 = new PrivateKey(Encoding.HexStringToByteArray(
                                               "a235851985a974aeafa6db9ed4bd8cd523d3f43048bb69df5dff4dfcc445b107"
                                               ));

            PrivateKey a2 = new PrivateKey(Encoding.HexStringToByteArray(
                                               "b7636ec1e84039dbb6d93ddbcf0f8e39e418ce13516fa1d8c40717f81e8d370e"
                                               ));

            /* a2 is derived from a1 */
            Assert.IsTrue(KeyOps.AreKeysDeterministic(a1, a2));

            /* Derivation is only one way */
            Assert.IsFalse(KeyOps.AreKeysDeterministic(a2, a1));

            /* Two completely unrelated keys */
            PrivateKey b1 = new PrivateKey(Encoding.HexStringToByteArray(
                                               "ee87e28220156cde3b901beb74bd089bdb512a3f6cef39fca66f900d4009fb08"
                                               ));

            PrivateKey b2 = new PrivateKey(Encoding.HexStringToByteArray(
                                               "677e019be0351443ea8904a6d6786056f7390eb74ba05ec327bccf2d318ca809"
                                               ));

            Assert.IsFalse(KeyOps.AreKeysDeterministic(b1, b2));
            Assert.IsFalse(KeyOps.AreKeysDeterministic(b2, b1));
        }
示例#10
0
 /* Makes a new wallet with the given private keys */
 private WalletBackend(string filename, string password,
                       PrivateKeys privateKeys) : this(
         filename, password, privateKeys.spendKey, privateKeys.viewKey,
         KeyOps.PrivateKeyToPublicKey(privateKeys.spendKey),
         KeyOps.PrivateKeyToPublicKey(privateKeys.viewKey), false
         )
 {
 }
示例#11
0
        public bool CheckSignature(string PrefixHash, string PublicKey, string Signature)
        {
            byte[] ph  = HexStringToByteArray(PrefixHash);
            byte[] pbk = HexStringToByteArray(PublicKey);
            byte[] sig = HexStringToByteArray(Signature);

            return(KeyOps.CheckSignature(ph, pbk, sig));
        }
示例#12
0
        public string GenerateKeyImage(string PublicKey, string PrivateKey)
        {
            byte[] pbk = HexStringToByteArray(PublicKey);
            byte[] pvk = HexStringToByteArray(PrivateKey);

            byte[] output = KeyOps.GenerateKeyImage(pbk, pvk);

            return(ByteArrayToHexString(output));
        }
示例#13
0
        public string ScalarmultKey(string KeyImageA, string KeyImageB)
        {
            byte[] kia = HexStringToByteArray(KeyImageA);
            byte[] kib = HexStringToByteArray(KeyImageB);

            byte[] output = KeyOps.ScalarmultKey(kia, kib);

            return(ByteArrayToHexString(output));
        }
示例#14
0
        public string GenerateSignature(string PrefixHash, string PublicKey, string PrivateKey)
        {
            byte[] ph  = HexStringToByteArray(PrefixHash);
            byte[] pbk = HexStringToByteArray(PublicKey);
            byte[] pvk = HexStringToByteArray(PrivateKey);

            byte[] sig = KeyOps.GenerateSignature(ph, pbk, pvk);

            return(ByteArrayToHexString(sig));
        }
示例#15
0
        public void TestGenerateKeys()
        {
            KeyPair pair = KeyOps.GenerateKeys();

            PublicKey pub = KeyOps.PrivateKeyToPublicKey(pair.privateKey);

            /* The public key should be the same one as we get get from
             * manual derivation of the private key */
            Assert.AreEqual <PublicKey>(pair.publicKey, pub);
        }
 private void ValidateKeyExchangeKey()
 {
     if (KeyOps != null && KeyOps.Contains(Constants.KeyOpsImport))
     {
         // "import" is exclusive, it cannot be combined with any other value(s).
         if (KeyOps.Length > 1)
         {
             throw new ArgumentException(Resources.KeyOpsImportIsExclusive);
         }
     }
 }
示例#17
0
        public string HashToScalar(string Hash)
        {
            if (Hash.Length % 2 != 0)
            {
                return(null);
            }

            byte[] tmp = HexStringToByteArray(Hash);

            KeyOps.HashToScalar(ref tmp, tmp);

            return(ByteArrayToHexString(tmp));
        }
示例#18
0
 public object Clone()
 {
     return(new JsonWebKey
     {
         Alg = Alg,
         KeyOps = KeyOps.ToArray(),
         Use = Use,
         Kid = Kid,
         Kty = Kty,
         SerializedKey = SerializedKey,
         Content = Content == null ? new Dictionary <string, string>() : Content.ToDictionary(s => s.Key, s => s.Value)
     });
 }
示例#19
0
        public void TestGenerateDeterministicKeys()
        {
            PrivateKey p = new PrivateKey("677e019be0351443ea8904a6d6786056f7390eb74ba05ec327bccf2d318ca809");

            PublicKey pubViewKey = new PublicKey("09e9c339bd1d751bf88d4d2301daa75576297e2e6b1a133cc0b9f03355421f69");

            PrivateKey privViewKey = new PrivateKey("508ba238625600b2ddec49eef1f114002c76c1436d4a144c3588069c3f72ae02");

            /* Generate view keys from a private spend key seed */
            KeyPair pair = KeyOps.GenerateDeterministicKeys(p);

            Assert.AreEqual <PublicKey>(pubViewKey, pair.publicKey);
            Assert.AreEqual <PrivateKey>(privViewKey, pair.privateKey);
        }
示例#20
0
        public KeyPair GenerateKeys()
        {
            KeyPair k = new KeyPair();

            byte[] pbk = new byte[32];
            byte[] pvk = new byte[32];

            KeyOps.GenerateKeys(ref pbk, ref pvk);

            k.PublicKey  = ByteArrayToHexString(pbk);
            k.PrivateKey = ByteArrayToHexString(pvk);

            return(k);
        }
示例#21
0
        public void TestAddressesBothWays()
        {
            for (int i = 0; i < 10; i++)
            {
                WalletKeys w = KeyOps.GenerateWalletKeys();

                /* TRTL, Monero, random different lengths */
                ulong[] prefixes = new ulong[] { 0x3bbb1d, 0x12, 0x0, 0x11, 0x222, 0x3333, 0x44444, 0x555555, 0x6666666 };

                foreach (ulong prefix in prefixes)
                {
                    string derivedAddress1 = Addresses.AddressFromKeys(w.spendKeys.privateKey, w.viewKeys.privateKey, prefix);

                    switch (Addresses.KeysFromAddress(derivedAddress1, prefix))
                    {
                    case ILeft <string> error:
                    {
                        Assert.Fail($"Failed to parse keys from address: {error.Value}");
                        break;
                    }

                    case IRight <PublicKeys> keys:
                    {
                        Assert.AreEqual <PublicKey>(keys.Value.spendKey, w.spendKeys.publicKey);
                        Assert.AreEqual <PublicKey>(keys.Value.viewKey, w.viewKeys.publicKey);
                        break;
                    }
                    }

                    string derivedAddress2 = Addresses.AddressFromKeys(w.spendKeys.publicKey, w.viewKeys.publicKey, prefix);

                    switch (Addresses.KeysFromAddress(derivedAddress2, prefix))
                    {
                    case ILeft <string> error:
                    {
                        Assert.Fail($"Failed to parse keys from address: {error.Value}");
                        break;
                    }

                    case IRight <PublicKeys> keys:
                    {
                        Assert.AreEqual <PublicKey>(keys.Value.spendKey, w.spendKeys.publicKey);
                        Assert.AreEqual <PublicKey>(keys.Value.viewKey, w.viewKeys.publicKey);
                        break;
                    }
                    }
                }
            }
        }
示例#22
0
        // Test key generation
        static void TestKeyGeneration()
        {
            // Generate a set of wallet keys
            WalletKeys Keys = KeyOps.GenerateWalletKeys();

            // Get an address string from the generated wallet keys
            string Address = Addresses.AddressFromKeys(Keys.publicSpendKey, Keys.publicViewKey);

            // Output generated keys to console
            Console.WriteLine($"Private spend key: {Keys.privateSpendKey.ToString()}");
            Console.WriteLine($"Private view key: {Keys.privateViewKey.ToString()}");

            // Output address to console
            Console.WriteLine($"Public address: {Address}");
            Console.WriteLine();
        }
 private void ValidateKeyExchangeKey()
 {
     if (KeyOps != null && KeyOps.Contains(Constants.KeyOpsImport))
     {
         // "import" is exclusive, it cannot be combined with any other value(s).
         if (KeyOps.Length > 1)
         {
             throw new ArgumentException(Resources.KeyOpsImportIsExclusive);
         }
         // When KeyOps is 'import', KeyType MUST be RSA-HSM
         if (Destination != HsmDestination)
         {
             throw new ArgumentException(Resources.KEKMustBeHSM);
         }
     }
 }
示例#24
0
        public void TestPrivateKeyToPublicKey()
        {
            /* A private key and public key pair */
            PrivateKey a1 = new PrivateKey("3a8441fa686f3d0c01b60264a79153c41fdd925ae4a31ffab215648f00758101");

            PublicKey a2 = new PublicKey("8464c6ff818fb7f502e4533c23f6ddb615b3568dbbfe954d07f8dd8fd23aefb3");

            Assert.AreEqual <PublicKey>(a2, KeyOps.PrivateKeyToPublicKey(a1));

            /* Two completely unrelated keys */
            PrivateKey b1 = new PrivateKey("a8219da64ddb1974292a19b6f2a3d3ef411a592191590d21ac59961c8af0c50e");

            PublicKey b2 = new PublicKey("45266e9d6259817e6c38cdd7f774fc38c9596d7400b1728546cf111e342941a5");

            Assert.AreNotEqual <PublicKey>(b2, KeyOps.PrivateKeyToPublicKey(b1));
        }
示例#25
0
        NewWallet(string filename, string password,
                  string mnemonicSeed)
        {
            /* Derive the mnemonic into a private spend key if possible */
            return(Mnemonics.MnemonicToPrivateKey(mnemonicSeed)
                   .Fmap(privateSpendKey => {
                /* Derive the private view key from the private spend key */
                var privateKeys = new PrivateKeys(
                    privateSpendKey,
                    KeyOps.GenerateDeterministicKeys(privateSpendKey).privateKey
                    );

                /* Try and create the new wallet from the private keys */
                return NewWallet(filename, password, privateKeys);
            }));
        }
示例#26
0
        public bool CheckRingSignatures(string PrefixHash, string KeyImage, string[] PublicKeys, string[] Signatures)
        {
            byte[]   ph  = HexStringToByteArray(PrefixHash);
            byte[]   ki  = HexStringToByteArray(KeyImage);
            byte[][] pks = new byte[PublicKeys.Length][];
            for (int i = 0; i < PublicKeys.Length; i++)
            {
                pks[i] = HexStringToByteArray(PublicKeys[i]);
            }
            byte[][] sigs = new byte[Signatures.Length][];
            for (int i = 0; i < Signatures.Length; i++)
            {
                sigs[i] = HexStringToByteArray(Signatures[i]);
            }

            return(KeyOps.CheckRingSignatures(ph, ki, pks, sigs));
        }
示例#27
0
        public void TestGenerateWalletKeys()
        {
            WalletKeys keys = KeyOps.GenerateWalletKeys();

            var privateSpendKey = keys.spendKeys.privateKey;
            var privateViewKey  = keys.viewKeys.privateKey;

            /* All newly generated keys should be a deterministic pair */
            Assert.IsTrue(KeyOps.AreKeysDeterministic(privateSpendKey, privateViewKey));

            var publicSpendKey = KeyOps.PrivateKeyToPublicKey(privateSpendKey);
            var publicViewKey  = KeyOps.PrivateKeyToPublicKey(privateViewKey);

            /* We should derive the same public keys from the private keys
             * as the ones returned from GenerateWalletKeys() */
            Assert.AreEqual <PublicKey>(publicSpendKey, keys.spendKeys.publicKey);
            Assert.AreEqual <PublicKey>(publicViewKey, keys.viewKeys.publicKey);
        }
示例#28
0
        public void TestMnemonicBothWays()
        {
            for (int i = 0; i < 1000; i++)
            {
                /* Generate a random private key */
                PrivateKey p = KeyOps.GenerateKeys().privateKey;

                /* Convert to mnemonic */
                string m = Mnemonics.PrivateKeyToMnemonic(p);

                /* Convert back to a private key */
                Mnemonics.MnemonicToPrivateKey(m).Do(
                    err => Assert.Fail($"Failed to parse mnemonic seed: {err}"),
                    /* Should be the same as the original private key */
                    key => Assert.AreEqual <PrivateKey>(p, key)
                    );
            }
        }
示例#29
0
        public string HashToEllipticCurve(string Hash)
        {
            if (!IsKey(Hash))
            {
                return(null);
            }

            byte[] tmp = HexStringToByteArray(Hash);

            ge_p3 tmp3 = new ge_p3();

            KeyOps.HashToEllipticCurve(tmp3, tmp);

            byte[] output = new byte[32];
            ED25519.ge_p3_tobytes(ref output, tmp3);

            return(ByteArrayToHexString(output));
        }
示例#30
0
        public string[] GenerateRingSignatures(string PrefixHash, string KeyImage, string[] PublicKeys, string TransactionSecretKey, ulong realOutput)
        {
            byte[]   ph  = HexStringToByteArray(PrefixHash);
            byte[]   ki  = HexStringToByteArray(KeyImage);
            byte[][] pks = new byte[PublicKeys.Length][];
            for (int i = 0; i < PublicKeys.Length; i++)
            {
                pks[i] = HexStringToByteArray(PublicKeys[i]);
            }
            byte[] tsk = HexStringToByteArray(TransactionSecretKey);

            byte[][] sigs = KeyOps.GenerateRingSignatures(ph, ki, pks, tsk, realOutput);

            string[] output = new string[sigs.Length];
            for (int i = 0; i < sigs.Length; i++)
            {
                output[i] = ByteArrayToHexString(sigs[i]);
            }

            return(output);
        }