예제 #1
0
        private static Double GetAverageSpeed(HashInfo hashInfo, Int32 length, Int32 repetitions, Int32 align)
        {
            RandomXS r = new RandomXS();

            Byte[] key = new Byte[length + 512];

            unsafe
            {
                fixed(Byte *pin = key)
                {
                    UInt64 pinValue   = (UInt64)pin;
                    UInt64 alignValue = ((pinValue + 255ul) & 0xFFFFFFFFFFFFFF00ul) + (UInt64)align;
                    Int32  offset     = (Int32)(alignValue - pinValue);

                    List <Double> results = new List <Double>(repetitions);

                    for (Int32 i = 0; i < repetitions; ++i)
                    {
                        r.NextBytes(key, offset, length);

                        Hash hash = hashInfo.Initializer((UInt32)i);

                        Double start = NativeMethods.GetTime();
                        hash.ComputeHash(key, offset, length);
                        Double end = NativeMethods.GetTime();

                        Double ms  = ((end - start + 1.0d) * 1000.0d) / s_Frequency;
                        Double bps = (length * 1000.0d) / ms;

                        if (bps >= 0.0d)
                        {
                            results.Add(bps);
                        }
                    }

                    Double mean      = StatsUtilities.Mean(results);
                    Double threshold = 2.0d * StatsUtilities.StandardDeviation(results, mean);

                    for (Int32 i = results.Count - 1; i >= 0; --i)
                    {
                        if (Math.Abs(results[i] - mean) > threshold)
                        {
                            results.RemoveAt(i);
                        }
                    }

                    return(StatsUtilities.Mean(results));
                }
            }
        }
예제 #2
0
        public static void BitIndependenceCriterionTest(HashInfo hashInfo)
        {
            RandomXS r = new RandomXS(0x000000B1u);

            Hash  hash      = hashInfo.Initializer(r.NextValue());
            Int32 hashBytes = hashInfo.Length / 8;
            Int32 hashBits  = hashInfo.Length;
            Int32 pageSize  = hashBits * hashBits * 4;

            Int32 keyBytes = BICT_KEYSBYTES;
            Int32 keyBits  = keyBytes * 8;

            Byte[] key = new Byte[keyBytes];

            Double biasFactor = BICT_REPETITIONS / 2.0d;

            Int32 step = keyBits / 10;

            Console.WriteLine("[[ BIT INDEPENDENCE CRITERION TEST ]]");
            Console.Write("Result: ");

            Int32[] bins = new Int32[keyBits * pageSize];

            for (Int32 keyBit = 0; keyBit < keyBits; ++keyBit)
            {
                if ((keyBit % step) == 0)
                {
                    Console.Write(".");
                }

                Int32 pageOffset = keyBit * pageSize;

                for (Int32 irep = 0; irep < BICT_REPETITIONS; ++irep)
                {
                    r.NextBytes(key);

                    Byte[] h1 = hash.ComputeHash(key);
                    BitsUtilities.FlipBit(key, 0, keyBytes, keyBit);
                    Byte[] h2 = hash.ComputeHash(key);

                    Byte[] d = new Byte[hashBytes];

                    for (Int32 i = 0; i < hashBytes; ++i)
                    {
                        d[i] = (Byte)(h1[i] ^ h2[i]);
                    }

                    for (Int32 hashBit1 = 0; hashBit1 < hashBits - 1; ++hashBit1)
                    {
                        for (Int32 hashBit2 = hashBit1 + 1; hashBit2 < hashBits; ++hashBit2)
                        {
                            Int32 x = BitsUtilities.GetBit(d, 0, hashBytes, hashBit1) | (BitsUtilities.GetBit(d, 0, hashBytes, hashBit2) << 1);
                            ++bins[pageOffset + (((hashBit1 * hashBits) + hashBit2) * 4) + x];
                        }
                    }
                }
            }

            Double worstBias     = 0.0d;
            Int32  worstKeyBit   = -1;
            Int32  worstHashBit1 = -1;
            Int32  worstHashBit2 = -1;

            for (Int32 hashBit1 = 0; hashBit1 < hashBits - 1; ++hashBit1)
            {
                for (Int32 hashBit2 = hashBit1 + 1; hashBit2 < hashBits; ++hashBit2)
                {
                    for (Int32 keyBit = 0; keyBit < keyBits; ++keyBit)
                    {
                        Int32 binsOffset = (keyBit * pageSize) + ((hashBit1 * hashBits) + hashBit2) * 4;

                        for (Int32 b = 0; b < 4; ++b)
                        {
                            Double c    = bins[binsOffset + b] / biasFactor;
                            Double bias = Math.Abs((c * 2.0d) - 1.0d);

                            if (bias > worstBias)
                            {
                                worstBias     = bias;
                                worstKeyBit   = keyBit;
                                worstHashBit1 = hashBit1;
                                worstHashBit2 = hashBit2;
                            }
                        }
                    }
                }
            }

            Boolean result = (worstBias <= 0.05d);

            Console.WriteLine(result ? " PASSED" : " FAILED");
            Console.WriteLine($"  - Worst Bias: {(worstBias.Equals(0.0d) ? "Unbiased" : $"{(worstBias * 100.0d):F2}% (Key Bit: {worstKeyBit} | Hash Bit 1: {worstHashBit1} | Hash Bit 2: {worstHashBit2})")}");
        }
예제 #3
0
        public static void DifferentialTest(HashInfo hashInfo)
        {
            RandomXS r         = new RandomXS(0x000000B2u);
            Int32    hashBytes = hashInfo.Length / 8;
            Int32    hashBits  = hashInfo.Length;

            Console.WriteLine("[[ DIFFERENTIAL TEST ]]");
            Console.WriteLine($"Maximum Errors: {DT_MAXIMUMERRORS}");

            Boolean resultOverall = true;

            for (Int32 i = 0; i < s_ParametersDT.Length; ++i)
            {
                dynamic p = s_ParametersDT[i];

                Int32  keysBytes = p.KeysBytes;
                Int32  keysBits  = keysBytes * 8;
                Byte[] key1      = new Byte[keysBytes];
                Byte[] key2      = new Byte[keysBytes];

                Int32 bits        = p.Bits;
                Int32 repetitions = p.Repetitions;
                Int32 steps       = repetitions / 10;

                Double tests = StatsUtilities.ChooseUpToK(keysBits, p.Bits) * repetitions;
                Double expectedCollisions = Math.Round(tests / Math.Pow(2.0d, hashBits));

                Console.WriteLine($"> Bits: 1-{bits}");
                Console.WriteLine($"  Repetitions: {repetitions}");
                Console.WriteLine($"  Tests: {tests:F0}");
                Console.WriteLine($"  Expected Collisions: {expectedCollisions:F0}");
                Console.Write("  Result: ");

                Byte[]        h2      = new Byte[hashBytes];
                UInt64        skipped = 0;
                List <Byte[]> diffs   = new List <Byte[]>(DT_MAXIMUMERRORS);

                for (Int32 j = 0; j < repetitions; ++j)
                {
                    if ((j % steps) == 0)
                    {
                        Console.Write((skipped > 0) ? "!" : ".");
                    }

                    r.NextBytes(key1);
                    UnsafeBuffer.BlockCopy(key1, 0, key2, 0, keysBytes);

                    Hash   hash = hashInfo.Initializer(r.NextValue());
                    Byte[] h1   = hash.ComputeHash(key1);

                    skipped += DifferentialTestRecursion(diffs, hash, keysBytes, key1, key2, hashBytes, h1, h2, 0, p.Bits);
                }

                Boolean result = true;

                if (skipped > 0)
                {
                    result = false;

                    Console.WriteLine(" FAILED");
                    Console.WriteLine("   - Errors Threshold Exceeded");
                }
                else
                {
                    Int32 ignoredCollisions = DifferentialTestIgnored(diffs, ref result);

                    Console.WriteLine(result ? " PASSED" : " FAILED");
                    Console.WriteLine($"   - Observed Collisions: {diffs.Count} ({ignoredCollisions} Ignored)");
                }

                resultOverall &= result;
            }

            Console.WriteLine($"Test Result: {(resultOverall ? "PASSED" : "FAILED")}");
        }
예제 #4
0
        public static void AvalancheTest(HashInfo hashInfo)
        {
            RandomXS r         = new RandomXS(0x000000B0u);
            Hash     hash      = hashInfo.Initializer(r.NextValue());
            Int32    hashBytes = hashInfo.Length / 8;
            Int32    hashBits  = hashInfo.Length;

            Console.WriteLine("[[ AVALANCHE TEST ]]");

            Boolean resultOverall = true;

            for (Int32 i = 0; i < s_ParametersAT.Length; ++i)
            {
                dynamic p = s_ParametersAT[i];

                Int32  keyBytes = p.KeysBytes;
                Int32  keyBits  = keyBytes * 8;
                Byte[] key      = new Byte[p.KeysBytes];

                Int32 repetitions = p.Repetitions;
                Int32 step        = repetitions / 10;

                Console.WriteLine($"> Keys Length: {keyBytes} Bytes");
                Console.WriteLine($"  Repetitions: {repetitions}");
                Console.Write("  Result: ");

                Int32   binsCount = keyBits * hashBits;
                Int32[] bins      = new Int32[keyBits * hashBits];

                for (Int32 j = 0; j < repetitions; ++j)
                {
                    if ((j % step) == 0)
                    {
                        Console.Write(".");
                    }

                    r.NextBytes(key);

                    Byte[] h0 = hash.ComputeHash(key);

                    Int32 binsIndex = 0;

                    for (Int32 keyBit = 0; keyBit < keyBits; ++keyBit)
                    {
                        BitsUtilities.FlipBit(key, 0, keyBytes, keyBit);
                        Byte[] hi = hash.ComputeHash(key);
                        BitsUtilities.FlipBit(key, 0, keyBytes, keyBit);

                        for (Int32 hashBit = 0; hashBit < hashBits; ++hashBit)
                        {
                            Byte a = BitsUtilities.GetBit(h0, 0, hashBytes, hashBit);
                            Byte b = BitsUtilities.GetBit(hi, 0, hashBytes, hashBit);

                            bins[binsIndex++] += a ^ b;
                        }
                    }
                }

                Double worstBias = 0.0d;

                for (Int32 j = 0; j < binsCount; ++j)
                {
                    Double c    = (Double)bins[j] / repetitions;
                    Double bias = Math.Abs((c * 2.0d) - 1.0d);

                    if (bias > worstBias)
                    {
                        worstBias = bias;
                    }
                }

                Boolean result = (worstBias <= 0.01d);
                Console.WriteLine(result ? " PASSED" : " FAILED");
                Console.WriteLine($"   - Worst Bias: {(worstBias.Equals(0.0d) ? "Unbiased" : $"{(worstBias * 100.0d):F2}%")}");

                resultOverall &= result;
            }

            Console.WriteLine($"Test Result: {(resultOverall ? "PASSED" : "FAILED")}");
        }