示例#1
0
        /// <summary>
        /// Gets an array of round constants (known as rcon in literature) used by the key schedule.
        /// </summary>
        /// <param name="maxRound">The maximum number of rounds needed.</param>
        /// <returns>An array of round constants (known as rcon in literature) used by the key schedule.</returns>
        public static byte[] GetRoundConstants(int maxRound)
        {
            byte[] result = new byte[maxRound];
            result[0] = 0;
            result[1] = 0x01;
            for (int i = 2; i < maxRound; i++)
            {
                result[i] = FiniteFieldMath.XTime(result[i - 1]);
            }

            return(result);
        }
        private static byte[] CalculateSBox(out byte[] invSBox)
        {
            byte[] result = new byte[256];
            invSBox = new byte[256];

            // We use an int since a byte would cause this to loop forever due to overflow
            for (int i = 0; i < 256; i++)
            {
                byte currentByte = (byte)i;
                result[i]          = FiniteFieldMath.F(FiniteFieldMath.G(currentByte));
                invSBox[result[i]] = currentByte;
            }

            return(result);
        }
示例#3
0
        protected override void InverseLayer(State state)
        {
            byte[] tempVector = new byte[4];

            for (int col = 0; col < state.Columns; col++)
            {
                ByteMatrixColumn currentColumn = state.GetColumn(col);

                // Multiply each column by d(x) which is the inverse of c(x). This means:
                // c(x) * d(x) ≡ 1, which expanded is
                // (03*x^3 ⊕ 01*x^2 ⊕ 01*x ⊕ 02) * d(x) ≡ 1

                // After some derivation, we can calculate that
                // d(x) = 0B*x^3 ⊕ 0D*x^2 ⊕ 09*x ⊕ 0E;

                // This is the same as multiplication by this matrix:
                // | 0E 0B 0D 09 |   | x0 |
                // | 09 0E 0B 0D |   | x1 |
                // | 0D 09 0E 0B | * | x2 |
                // | 0B 0D 09 0E |   | x3 |

                // We can perform this multiply by starting with the top row of the matrix:
                // [0E 0B 0D 09] and keep rotating it by 1 each column. Note that the multiply
                // is in the Rijndael field.

                for (int row = 0; row < 4; row++)
                {
                    tempVector[row] = (byte)(
                        FiniteFieldMath.Multiply(0x0E, currentColumn[row]) ^
                        FiniteFieldMath.Multiply(0x0B, currentColumn[(row + 1) % 4]) ^
                        FiniteFieldMath.Multiply(0x0D, currentColumn[(row + 2) % 4]) ^
                        FiniteFieldMath.Multiply(0x09, currentColumn[(row + 3) % 4]));
                }

                // Now that we have the result of the multiply in tempVector, we
                // copy it back to the state matrix:
                for (int row = 0; row < 4; row++)
                {
                    currentColumn[row] = tempVector[row];
                }
            }
        }
示例#4
0
        protected override void ApplyLayer(State state)
        {
            byte[] tempVector = new byte[4];

            for (int col = 0; col < state.Columns; col++)
            {
                ByteMatrixColumn currentColumn = state.GetColumn(col);

                // Multiply each column by c(x) which is defined as
                // c(x) = 03*x^3 ⊕ 01*x^2 ⊕ 01*x ⊕ 02;

                // This is the same as multiplication by this matrix:
                // | 02 03 01 01 |   | x0 |
                // | 01 02 03 01 |   | x1 |
                // | 01 01 02 03 | * | x2 |
                // | 03 01 01 02 |   | x3 |

                // We can perform this multiply by starting with the top row of the matrix:
                // [02 03 01 01] and keep rotating it by 1 each column. Note that the multiply
                // is in the Rijndael field.
                for (int row = 0; row < 4; row++)
                {
                    tempVector[row] = (byte)(
                        FiniteFieldMath.Multiply(0x02, currentColumn[row]) ^
                        FiniteFieldMath.Multiply(0x03, currentColumn[(row + 1) % 4]) ^
                        FiniteFieldMath.Multiply(0x01, currentColumn[(row + 2) % 4]) ^
                        FiniteFieldMath.Multiply(0x01, currentColumn[(row + 3) % 4]));
                }

                // Now that we have the result of the multiply in tempVector, we
                // copy it back to the state matrix:
                for (int row = 0; row < 4; row++)
                {
                    currentColumn[row] = tempVector[row];
                }
            }
        }
示例#5
0
        public Polynomial Sqrt(Polynomial sqr, Polynomial mod, Polynomial modDerivative, BigInteger sqrtNorm)
        {
            BigInteger max = 0;

            for (int i = 0; i <= sqr.Deg; i++)
            {
                if (BigInteger.Abs(sqr[i]) > max)
                {
                    max = BigInteger.Abs(sqr[i]);
                }
            }
            var        nextPrime     = new NextPrime();
            var        bound         = max * 10;
            var        primes        = new List <BigInteger>();
            var        sieve         = new EratosthenesSieve();
            var        primesToCheck = sieve.GetPrimes(100000000, 110000000);
            BigInteger bigMod        = 1;

            foreach (var primeToCheck in primesToCheck)
            {
                var irreducibilityTest = new IrreducibilityTest();
                if (!irreducibilityTest.IsIrreducible(mod, primeToCheck))
                {
                    continue;
                }
                bigMod *= primeToCheck;
                primes.Add(primeToCheck);
                if (bigMod > bound)
                {
                    break;
                }
            }
            var prime = 2 * primes[primes.Count - 1];

            while (bigMod < bound)
            {
                prime = nextPrime.GetNext(prime);
                var irreducibilityTest = new IrreducibilityTest();
                while (!irreducibilityTest.IsIrreducible(mod, prime))
                {
                    prime = nextPrime.GetNext(prime + 1);
                }
                bigMod *= prime;
                primes.Add(prime);
            }
            var sqrts = new List <Polynomial>();

            foreach (var fieldChar in primes)
            {
                var        polyMath = new PolynomialMath(fieldChar);
                var        four     = new Polynomial(new BigInteger[] { 4 });
                Polynomial b;
                var        isSqr = false;
                for (int i = 0; true; i++)
                {
                    b = new Polynomial(new BigInteger[] { i });
                    var tmp = polyMath.ModPow(polyMath.Sub(polyMath.Mul(b, b), polyMath.Mul(four, sqr)),
                                              (BigInteger.Pow(fieldChar, mod.Deg) - 1) / 2, mod);
                    isSqr = (tmp[0] == 1 || tmp[0] == -(fieldChar - 1)) && (tmp.Deg == 0);
                    if (!isSqr)
                    {
                        break;
                    }
                }
                var gfMath      = new FiniteFieldMath(mod, fieldChar);
                var modPoly     = new PolynomialOverFiniteField(new Polynomial[] { sqr, b, new Polynomial(new BigInteger[] { 1 }) });
                var y           = new PolynomialOverFiniteField(new Polynomial[] { new Polynomial(new BigInteger[] { 0 }), new Polynomial(new BigInteger[] { 1 }) });
                var sqrt        = gfMath.ModPow(y, (BigInteger.Pow(fieldChar, mod.Deg) + 1) / 2, modPoly)[0];
                var sqrtNormMod = sqrtNorm * polyMath.ModPow(modDerivative, (BigInteger.Pow(fieldChar, mod.Deg) - 1) / (fieldChar - 1), mod)[0];
                var norm        = polyMath.ModPow(sqrt, (BigInteger.Pow(fieldChar, mod.Deg) - 1) / (fieldChar - 1), mod)[0];
                sqrtNormMod %= fieldChar;
                if (sqrtNormMod < 0)
                {
                    sqrtNormMod = sqrtNormMod + fieldChar;
                }
                if (norm < 0)
                {
                    norm = norm + fieldChar;
                }
                if (norm != sqrtNormMod)
                {
                    sqrt = polyMath.ConstMul(-1, sqrt);
                }
                sqrts.Add(sqrt);
            }
            BigInteger[] result = new BigInteger[mod.Deg];
            var          crt    = new GarnerCrt();

            for (int i = 0; i < mod.Deg; i++)
            {
                var coefficients = new List <BigInteger>();
                for (int j = 0; j < primes.Count; j++)
                {
                    coefficients.Add(sqrts[j][i]);
                }
                result[i] = crt.Calculate(coefficients, primes);
            }
            var resultPoly = new Polynomial(result);

            for (int i = 0; i <= resultPoly.Deg; i++)
            {
                var coeff = BigInteger.Abs(resultPoly[i]);
                if (coeff > max)
                {
                    if (resultPoly[i] < 0)
                    {
                        resultPoly[i] += bigMod;
                    }
                    else
                    {
                        resultPoly[i] -= bigMod;
                    }
                }
            }
            return(resultPoly);
        }