Ejemplo n.º 1
0
        /// <summary>
        ///     Encode a publicKey into miniLock format.
        /// </summary>
        /// <param name="publicKey">A 32 byte publicKey.</param>
        /// <exception cref="Sodium.Exceptions.KeyOutOfRangeException"></exception>
        /// <returns>A Base58 encoded publicKey.</returns>
        public static string EncodeMiniLockPublicKey(byte[] publicKey)
        {
            if (publicKey == null || publicKey.Length != PublicKeyBytes)
            {
                throw new KeyOutOfRangeException("publicKey", (publicKey == null) ? 0 : publicKey.Length,
                                                 string.Format("key must be {0} bytes in length.", PublicKeyBytes));
            }

            var final = ArrayHelper.ConcatArrays(publicKey, Blake2S.Hash(publicKey, (byte[])null, 1));

            return(Base58CheckEncoding.EncodePlain(final));
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Decode a miniLock ID into a byte array.
        /// </summary>
        /// <param name="encodedPublicKey">The miniLock ID.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="CorruptIdentityException"></exception>
        /// <returns>A 32 byte array.</returns>
        public static byte[] DecodeMiniLockPublicKey(string encodedPublicKey)
        {
            if (encodedPublicKey == null)
            {
                throw new ArgumentNullException("encodedPublicKey", "encodedPublicKey cannot be null");
            }

            var raw       = Base58CheckEncoding.DecodePlain(encodedPublicKey);
            var publicKey = ArrayHelper.SubArray(raw, 0, 32);
            var checksum  = ArrayHelper.SubArray(raw, 32);

            // validate the checksum
            if (!checksum.SequenceEqual(Blake2S.Hash(publicKey, (byte[])null, 1)))
            {
                throw new CorruptIdentityException("the given identity seems to be an invalid miniLock ID");
            }

            return(publicKey);
        }
Ejemplo n.º 3
0
        public void Test()
        {
            var vectors = new List <TestVector>
            {
                new TestVector
                {
                    Id        = 1,
                    InputHex  = "",
                    KeyHex    = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
                    ResultHex = "48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49"
                },
                new TestVector
                {
                    Id        = 2,
                    InputHex  = "00",
                    KeyHex    = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
                    ResultHex = "40d15fee7c328830166ac3f918650f807e7e01e177258cdc0a39b11f598066f1"
                },
                new TestVector
                {
                    Id        = 3,
                    InputHex  = "0001",
                    KeyHex    = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
                    ResultHex = "6bb71300644cd3991b26ccd4d274acd1adeab8b1d7914546c1198bbe9fc9d803"
                }
            };


            foreach (var vector in vectors)
            {
                var result = TestHelper.StringToByteArray(vector.ResultHex);
                var hash   = Blake2S.Hash(TestHelper.StringToByteArray(vector.InputHex),
                                          TestHelper.StringToByteArray(vector.KeyHex), result.Length);
                CollectionAssert.AreEqual(result, hash);
                Console.WriteLine("Test Vector " + vector.Id + ": passed");
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        ///     Generate a MiniLock Keypair from an email and a password.
        /// </summary>
        /// <param name="email">A valid (format) email address.</param>
        /// <param name="password">A password with a minimal entropy of 100.</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidMailException"></exception>
        /// <exception cref="LowEntropyException"></exception>
        /// <returns>A libsodium compatible KeyPair.</returns>
        public static KeyPair GenerateMiniLockKeyPair(string email, string password)
        {
            const int minPasswordEntropy = 100;

            if (email == null)
            {
                throw new ArgumentNullException("email", "email cannot be null");
            }

            // perform a simple email check
            if (!StringHelper.IsValidEmail(email))
            {
                throw new InvalidMailException("the given email address seems to be invalid");
            }

            if (password == null)
            {
                throw new ArgumentNullException("password", "password cannot be null");
            }

            var passwordEntropy = Zxcvbn.Zxcvbn.MatchPassword(password).Entropy;

            // check the entropy
            if (passwordEntropy < 100)
            {
                throw new LowEntropyException(
                          string.Format(
                              "miniLock needs at least an entropy of {0}, the given password only has an entropy of {1}.",
                              minPasswordEntropy, passwordEntropy));
            }

            var passwordHash = Blake2S.Hash(Encoding.UTF8.GetBytes(password), (byte[])null, 32);
            var seed         = SCrypt.ComputeDerivedKey(passwordHash, Encoding.UTF8.GetBytes(email), 131072, 8, 1, 1, 32);
            var keyPair      = PublicKeyBox.GenerateKeyPair(seed);

            return(keyPair);
        }