示例#1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Argon2TestVector"/> class.
 /// </summary>
 /// <param name="name">
 /// name of the vector
 /// </param>
 /// <param name="type">
 /// Data-driven or independent.
 /// </param>
 /// <param name="version">
 /// The Argon2 version.
 /// </param>
 /// <param name="iterations">
 /// The number of iterations.
 /// </param>
 /// <param name="memoryKBytes">
 /// The memory to use.
 /// </param>
 /// <param name="parallelism">
 /// The number of threads to use.
 /// </param>
 /// <param name="tagLength">
 /// How many bytes to output.
 /// </param>
 /// <param name="password">
 /// The password to hash.
 /// </param>
 /// <param name="salt">
 /// The salt to use in the hash. Minimum of 8 bytes. 16 recommended.
 /// </param>
 /// <param name="secret">
 /// The secret to use in the hash.
 /// </param>
 /// <param name="associatedData">
 /// The associated data to use in the hash (like a salt but can be shorter).
 /// </param>
 /// <param name="tag">
 /// The expected hash created from the above parameters.
 /// </param>
 public Argon2TestVector(
     string name,
     Argon2Type type,
     Argon2Version version,
     int iterations,
     int memoryKBytes,
     int parallelism,
     int tagLength,
     string password,
     string salt,
     string secret,
     string associatedData,
     string tag)
 {
     this.Name           = name;
     this.Type           = type;
     this.Version        = version;
     this.Iterations     = iterations;
     this.MemoryKBytes   = memoryKBytes;
     this.Parallelism    = parallelism;
     this.TagLength      = tagLength;
     this.Password       = ToBytes(password);
     this.Salt           = ToBytes(salt);
     this.Secret         = ToBytes(secret);
     this.AssociatedData = ToBytes(associatedData);
     this.Tag            = ToBytes(tag);
 }
        private void HashTestOthers(IArgon2ParametersBuilder a_Argon2ParametersBuilder,
                                    Argon2Version a_Version, Int32 a_Iterations, Int32 a_Memory, Int32 a_Parallelism,
                                    string a_Password, string a_Salt, string a_PasswordRef, Int32 a_OutputLength)
        {
            IPBKDF_Argon2 LGenerator;

            byte[]            LSalt, LPassword;
            string            LActual;
            IArgon2Parameters LArgon2Parameter;

            LSalt     = Converters.ConvertStringToBytes(a_Salt, Encoding.ASCII);
            LPassword = Converters.ConvertStringToBytes(a_Password, Encoding.ASCII);

            a_Argon2ParametersBuilder.WithVersion(a_Version).WithIterations(a_Iterations)
            .WithMemoryPowOfTwo(a_Memory).WithParallelism(a_Parallelism).WithSalt(LSalt);

            //
            // Set the password.
            //
            LArgon2Parameter = a_Argon2ParametersBuilder.Build();
            a_Argon2ParametersBuilder.Clear();

            LGenerator = HashFactory.KDF.PBKDF_Argon2.CreatePBKDF_Argon2(LPassword, LArgon2Parameter);

            LActual = Converters.ConvertBytesToHexString(LGenerator.GetBytes(a_OutputLength), false);

            LArgon2Parameter.Clear();
            LGenerator.Clear();

            Assert.AreEqual(a_PasswordRef, LActual,
                            String.Format("Expected {0} but got {1}.", a_PasswordRef, LActual));
        } //
示例#3
0
        public Argon2Parameters(Argon2Type type, byte[] salt, byte[] secret, byte[] additional,
                                int iterations, int memory, int lanes, Argon2Version version)
        {
            if (salt == null)
            {
                throw new ArgumentNullException(nameof(salt));
            }
            if (secret == null)
            {
                throw new ArgumentNullException(nameof(secret));
            }
            if (additional == null)
            {
                throw new ArgumentNullException(nameof(additional));
            }

            _salt       = ArrayUtils.Clone(salt);
            _secret     = ArrayUtils.Clone(secret);
            _additional = ArrayUtils.Clone(additional);

            Iterations = iterations;
            Memory     = memory;
            Lanes      = lanes;
            Type       = type;
            Version    = version;
        }
示例#4
0
        } // end cctr

        protected Argon2ParametersBuilder(Argon2Type a_Type)
        {
            Lanes      = DEFAULT_LANES;
            Memory     = 1 << DEFAULT_MEMORY_COST;
            Iterations = DEFAULT_ITERATIONS;
            Type       = a_Type;
            Version    = DEFAULT_VERSION;
        } //
示例#5
0
 private Argon2ParametersBuilder()
 {
     _salt       = new byte[0];
     _secret     = new byte[0];
     _additional = new byte[0];
     _type       = DEFAULT_TYPE;
     _version    = DEFAULT_VERSION;
     _iterations = DEFAULT_ITERATIONS;
     _memory     = 1 << DEFAULT_MEMORY_COST;
     _lanes      = DEFAULT_LANES;
 }
示例#6
0
        protected Argon2ParametersBuilder(Argon2Type a_Type, byte[] a_Salt, byte[] a_Secret, byte[] a_Additional,
                                          Int32 a_Iterations, Int32 a_Memory, Int32 a_Lanes, Argon2Version a_Version)
        {
            Salt       = a_Salt.DeepCopy();
            Secret     = a_Secret.DeepCopy();
            Additional = a_Additional.DeepCopy();

            Iterations = a_Iterations;
            Memory     = a_Memory;
            Lanes      = a_Lanes;
            Type       = a_Type;
            Version    = a_Version;
        } // end cctr
示例#7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Argon2HashAlgorithm"/> class with the specified parameters.
        /// </summary>
        /// <param name="type">The Argon2 algorithm type to use.</param>
        /// <param name="version">The Argon2 version to use.</param>
        /// <param name="parallelism">The number of lanes to use while processing the hash.</param>
        /// <param name="memorySize">The amount of memory (in MB) to use while processing the hash.</param>
        /// <param name="hashLength">The size of the output hash (in bytes). 16 bytes is recommended for password hashing.</param>
        public Argon2HashAlgorithm(Argon2Type type, Argon2Version version, int parallelism, int memorySize, int hashLength = 16)
            : base($"{type}V{(int)version}-{hashLength * 8}-{parallelism}P-{memorySize}MB")
        {
            // Inputs:
            //    password (P):       Bytes (0..2^32-1)    Password (or message) to be hashed
            //    salt (S):           Bytes (8..2^32-1)    Salt (16 bytes recommended for password hashing)
            //    parallelism (p):    Number (1..2^24-1)   Degree of parallelism (i.e. number of threads)
            //    tagLength (T):      Number (4..2^32-1)   Desired number of returned bytes
            //    memorySizeKB (m):   Number (8p..2^32-1)  Amount of memory (in kibibytes) to use
            //    iterations (t):     Number (1..2^32-1)   Number of iterations to perform
            //    version (v):        Number (0x13)       The current version is 0x13 (19 decimal)
            //    key (K):            Bytes (0..2^32-1)    Optional key (Errata: PDF says 0..32 bytes, RFC says 0..232 bytes)
            //    associatedData (X): Bytes (0..2^32-1)    Optional arbitrary extra data
            //    hashType (y):       Number (0=Argon2d, 1=Argon2i, 2=Argon2id)
            // Output:
            //    tag:                Bytes (tagLength)   The resulting generated bytes, tagLength bytes long

            if (!Enum.IsDefined(typeof(Argon2Type), type))
            {
                throw new ArgumentOutOfRangeException(nameof(type));
            }

            if (!Enum.IsDefined(typeof(Argon2Version), version))
            {
                throw new ArgumentOutOfRangeException(nameof(version));
            }

            if (parallelism < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(parallelism));
            }

            if (memorySize * 1024 < parallelism * 8 || memorySize > 4194303)
            {
                throw new ArgumentOutOfRangeException(nameof(memorySize));
            }

            if (hashLength < 4)
            {
                throw new ArgumentOutOfRangeException(nameof(hashLength));
            }

            Parallelism = parallelism;
            MemorySize  = memorySize;
            HashLength  = hashLength;
        }
        private void HashTestFromInternetDraft(IArgon2ParametersBuilder a_Argon2ParametersBuilder,
                                               Argon2Version a_Version, Int32 a_Iterations, Int32 a_MemoryAsKB, Int32 a_Parallelism,
                                               string a_Additional, string a_Secret, string a_Salt, string a_Password, string a_PasswordRef,
                                               Int32 a_OutputLength)
        {
            IPBKDF_Argon2 LGenerator;
            string        LActual;

            byte[]            LAdditional, LSecret, LSalt, LPassword;
            IArgon2Parameters LArgon2Parameter;

            LAdditional = Converters.ConvertHexStringToBytes(a_Additional);
            LSecret     = Converters.ConvertHexStringToBytes(a_Secret);
            LSalt       = Converters.ConvertHexStringToBytes(a_Salt);
            LPassword   = Converters.ConvertHexStringToBytes(a_Password);

            a_Argon2ParametersBuilder.WithVersion(a_Version).WithIterations(a_Iterations)
            .WithMemoryAsKB(a_MemoryAsKB).WithParallelism(a_Parallelism)
            .WithAdditional(LAdditional).WithSecret(LSecret).WithSalt(LSalt);

            //
            // Set the password.
            //
            LArgon2Parameter = (IArgon2Parameters)a_Argon2ParametersBuilder.Build();
            a_Argon2ParametersBuilder.Clear();

            LGenerator = HashFactory.KDF.PBKDF_Argon2.CreatePBKDF_Argon2(LPassword, LArgon2Parameter);

            LActual = Converters.ConvertBytesToHexString(LGenerator.GetBytes(a_OutputLength), false);

            LArgon2Parameter.Clear();
            LGenerator.Clear();

            Assert.AreEqual(a_PasswordRef, LActual,
                            String.Format("Expected {0} but got {1}.", a_PasswordRef, LActual));
        } //
示例#9
0
        } //

        public IArgon2ParametersBuilder WithVersion(Argon2Version a_Version)
        {
            Version = a_Version;
            return(this as IArgon2ParametersBuilder);
        } //
示例#10
0
 public Argon2ParametersBuilder WithVersion(Argon2Version version)
 {
     _version = version;
     return(this);
 }
示例#11
0
        private static string TestFromDraft()
        {
            // from draft-irtf-cfrg-argon2-03
            // They have this code in version 3 of the draft but it is gone in version 4.
            var                 testPwd                 = Encoding.ASCII.GetBytes("pasword");
            var                 testSalt                = Encoding.ASCII.GetBytes("somesalt");
            const int           testTimeCost            = 3;
            const int           testMemoryCost          = 1 << 12;
            const int           testParallelism         = 1;
            const Argon2Version testArgon2VersionNumber = Argon2Version.Nineteen;

            bool Run(byte[] pwd, byte[] salt, int timeCost, int memoryCost, int threads,
                     Argon2Type argon2Type, Argon2Version version, byte[] expectedHash)
            {
                using (var hash = new Argon2(
                           new Argon2Config
                {
                    HashLength = expectedHash.Length,
                    TimeCost = timeCost,
                    MemoryCost = memoryCost,
                    Lanes = threads,
                    Threads = threads,
                    Password = pwd,
                    Salt = salt,
                    Version = version,
                    Type = argon2Type,
                }).Hash())
                {
                    Console.WriteLine($"     Actual Hash:   {BitConverter.ToString(hash.Buffer)}");
                    Console.WriteLine($"     Expected Hash: {BitConverter.ToString(expectedHash)}");
                    return(!hash.Buffer.Where((b, i) => b != expectedHash[i]).Any());
                }
            }

            bool Argon2ISelftest()
            {
                byte[] expectedHash =
                {
                    0x95, 0x7f, 0xc0, 0x72, 0x7d, 0x83, 0xf4, 0x06,
                    0x0b, 0xb0, 0xf1, 0x07, 0x1e, 0xb5, 0x90, 0xa1,
                    0x9a, 0x8c, 0x44, 0x8f, 0xc0, 0x20, 0x94, 0x97,
                    0xee, 0x4f, 0x54, 0xca, 0x24, 0x1f, 0x3c, 0x90,
                };
                return(Run(
                           testPwd,
                           testSalt,
                           testTimeCost,
                           testMemoryCost,
                           testParallelism,
                           Argon2Type.DataIndependentAddressing,
                           testArgon2VersionNumber,
                           expectedHash));
            }

            bool Argon2DSelftest()
            {
                byte[] expectedHash =
                {
                    0x0b, 0x3f, 0x09, 0xe7, 0xb8, 0xd0, 0x36, 0xe5,
                    0x8c, 0xcd, 0x08, 0xf0, 0x8c, 0xb6, 0xba, 0xbf,
                    0x7e, 0x5e, 0x24, 0x63, 0xc2, 0x6b, 0xcf, 0x2a,
                    0x9e, 0x4e, 0xa7, 0x0d, 0x74, 0x7c, 0x40, 0x98,
                };
                return(Run(
                           testPwd,
                           testSalt,
                           testTimeCost,
                           testMemoryCost,
                           testParallelism,
                           Argon2Type.DataDependentAddressing,
                           testArgon2VersionNumber,
                           expectedHash));
            }

            bool Argon2IdSelftest()
            {
                byte[] expectedHash =
                {
                    0xf5, 0x55, 0x35, 0xbf, 0xe9, 0x48, 0x71, 0x00,
                    0x51, 0x42, 0x4c, 0x74, 0x24, 0xb1, 0x1b, 0xa9,
                    0xa1, 0x3a, 0x50, 0x23, 0x9b, 0x04, 0x59, 0xf5,
                    0x6c, 0xa6, 0x95, 0xea, 0x14, 0xbc, 0x19, 0x5e,
                };
                return(Run(
                           testPwd,
                           testSalt,
                           testTimeCost,
                           testMemoryCost,
                           testParallelism,
                           Argon2Type.HybridAddressing,
                           testArgon2VersionNumber,
                           expectedHash));
            }

            var argon2IResult = $"draft-irtf-cfrg-argon2-03 Argon2i  - {(Argon2ISelftest() ? "Passed" : "FAIL")}";

            Console.WriteLine(argon2IResult);
            var argon2DResult = $"draft-irtf-cfrg-argon2-03 Argon2d  - {(Argon2DSelftest() ? "Passed" : "FAIL")}";

            Console.WriteLine(argon2DResult);
            var argon2IdResult = $"draft-irtf-cfrg-argon2-03 Argon2id - {(Argon2IdSelftest() ? "Passed" : "FAIL")}";

            Console.WriteLine(argon2IdResult);
            return(string.Join($"{Environment.NewLine}  ", argon2IResult, argon2DResult, argon2IdResult));
        }