Ejemplo n.º 1
0
 public BigInteger GetNonce(BigInteger privateD, BigInteger hashedMessage, BigInteger orderN)
 {
     return(_entropyProvider.GetEntropy(1, orderN - 1));
 }
Ejemplo n.º 2
0
        private PrimeGeneratorResult GeneratePrimes(PrimeGeneratorParameters param)
        {
            BigInteger p, p1, p2, q, q1, q2, xp, xq, xp1, xp2, xq1, xq2;

            // 1, 2, 3 covered by guards

            // 4
            xp1 = _entropyProvider.GetEntropy(param.BitLens[0]).ToPositiveBigInteger();
            if (xp1.IsEven)
            {
                xp1++;
            }

            xp2 = _entropyProvider.GetEntropy(param.BitLens[1]).ToPositiveBigInteger();
            if (xp2.IsEven)
            {
                xp2++;
            }

            p1 = xp1;
            while (!PrimeGeneratorHelper.MillerRabin(_primeTestMode, param.Modulus, p1, true))
            {
                p1 += 2;
            }

            p2 = xp2;
            while (!PrimeGeneratorHelper.MillerRabin(_primeTestMode, param.Modulus, p2, true))
            {
                p2 += 2;
            }

            var pResult = PrimeGeneratorHelper.ProbablePrimeFactor(_primeTestMode, _entropyProvider, _pBound, param.A, p1, p2, param.Modulus, param.PublicE);

            if (!pResult.Success)
            {
                return(new PrimeGeneratorResult($"Failed to generate p: {pResult.ErrorMessage}"));
            }
            p  = pResult.Prime;
            xp = pResult.XPrime;

            // 5
            do
            {
                xq1 = _entropyProvider.GetEntropy(param.BitLens[2]).ToPositiveBigInteger();
                if (xq1.IsEven)
                {
                    xq1++;
                }

                xq2 = _entropyProvider.GetEntropy(param.BitLens[3]).ToPositiveBigInteger();
                if (xq2.IsEven)
                {
                    xq2++;
                }

                q1 = xq1;
                while (!PrimeGeneratorHelper.MillerRabin(_primeTestMode, param.Modulus, q1, true))
                {
                    q1 += 2;
                }

                q2 = xq2;
                while (!PrimeGeneratorHelper.MillerRabin(_primeTestMode, param.Modulus, q2, true))
                {
                    q2 += 2;
                }

                var qResult = PrimeGeneratorHelper.ProbablePrimeFactor(_primeTestMode, _entropyProvider, _pBound, param.B, q1, q2, param.Modulus, param.PublicE);
                if (!qResult.Success)
                {
                    return(new PrimeGeneratorResult($"Failed to generate q: {qResult.ErrorMessage}"));
                }
                q  = qResult.Prime;
                xq = qResult.XPrime;

                // 6
            } while (BigInteger.Abs(xp - xq) <= NumberTheory.Pow2(param.Modulus / 2 - 100) ||
                     BigInteger.Abs(p - q) <= NumberTheory.Pow2(param.Modulus / 2 - 100));

            var auxValues = new AuxiliaryResult {
                XP1 = xp1, XP2 = xp2, XP = xp, XQ1 = xq1, XQ2 = xq2, XQ = xq
            };
            var primePair = new PrimePair {
                P = p, Q = q
            };

            return(new PrimeGeneratorResult(primePair, auxValues));
        }
        public BitString RandomizeMessage(BitString message, int randomizationSecurityStrength)
        {
            var       rv      = _entropyProvider.GetEntropy(randomizationSecurityStrength);
            BitString padding = BitString.One();

            // from https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-106.pdf

            /*
             * 1. If(| Ms | ≥ (| rv | -1))
             * {
             *  1.1 padding = 1.
             * }
             * Else
             * {
             *  1.2 padding = 1 || 0(| rv | - | Ms | -1).
             * }
             */
            if (message.BitLength < rv.BitLength - 1)
            {
                padding = padding.ConcatenateBits(BitString.Zeroes(rv.BitLength - message.BitLength - 1));
            }

            // 2. m = Ms || padding.
            var m = message.ConcatenateBits(padding);

            // 3. n is a positive integer, and n = | rv |.
            var n = rv.BitLength;

            // 4. If(n > 1024) then stop and output an error indicator(see Section 3.3).
            if (n < 80 || n > 1024)
            {
                throw new ArgumentOutOfRangeException(nameof(n));
            }

            // 5. counter = ⎣| m | / n⎦.
            var counter = (int)System.Math.Floor((double)m.BitLength / n);

            // 6. remainder = (| m | mod n).
            var remainder = m.BitLength % n;

            /*
             * 7. Concatenate counter copies of the rv to the remainder left - most bits of the rv to get Rv,
             *  such that | Rv | = | m |.
             */
            var Rv = new BitString(0);

            for (var i = 0; i < counter; i++)
            {
                Rv = Rv.ConcatenateBits(rv);
            }
            Rv = Rv.ConcatenateBits(rv.GetLeastSignificantBits(remainder));

            // Sanity check
            if (Rv.BitLength != m.BitLength)
            {
                throw new ArgumentOutOfRangeException(nameof(Rv));
            }

            /*
             * 8. Convert n to a 16 - bit binary string rv_length_indicator using the
             *  rv_length_indicator_generation function specified in the Appendix.
             *  rv_length_indicator = rv_length_indicator_generation(n).
             */
            // this cast should be safe as we're ensuring n <= 1024
            var nBitString = BitString.To16BitString((short)n);

            //9. M = rv || (m ⊕ Rv) || rv_length_indicator(Figure 1).
            return(rv
                   .ConcatenateBits(m.XOR(Rv))
                   .ConcatenateBits(nBitString));
        }
Ejemplo n.º 4
0
        public SharedSecretResponse Encrypt(PublicKey rsaPublicKey, BitString keyingMaterial, BitString additionalInput)
        {
            if (additionalInput == null)
            {
                additionalInput = new BitString(0);
            }

            // 1. nLen = len(n)/8, the byte length of n
            var nLenBits = rsaPublicKey.N.ExactBitLength().ValueToMod(BitString.BITSINBYTE);
            var nLen     = nLenBits.CeilingDivide(BitString.BITSINBYTE);

            // 2. Length checking:
            // a. KLen = len(K)/8, the byte length of K.
            var KLen = keyingMaterial.BitLength.CeilingDivide(BitString.BITSINBYTE);

            // b. If KLen > nLen – 2HLen – 2, then output an indication that the keying material is
            // too long, and exit without further processing.
            var HLen = _sha.HashFunction.OutputLen.CeilingDivide(BitString.BITSINBYTE);

            if (KLen > nLen - 2 * HLen - 2)
            {
                throw new ArgumentException($"{nameof(KLen)} length too large.");
            }

            // 3. OAEP encoding:
            // a. Apply the selected hash function to compute: HA = H(A).
            var HA = _sha.HashMessage(additionalInput).Digest;

            // b. Construct a byte string PS consisting of nLen – KLen – 2HLen – 2 zero bytes. The
            // length of PS may be zero.
            var PS = new BitString(new byte[nLen - KLen - 2 * HLen - 2]);

            // c. Concatenate HA, PS, a single byte with a hexadecimal value of 01, and the keying
            // material K to form data DB of nLen – HLen – 1 bytes as follows:
            // DB = HA || PS || 00000001 || K
            var DB = HA.ConcatenateBits(PS).ConcatenateBits(BitString.To8BitString(0x01)).ConcatenateBits(keyingMaterial);

            // d. Using the RBG (see Section 5.3), generate a random byte string mgfSeed of HLen bytes.
            var mgfSeed = _entropyProvider.GetEntropy(_sha.HashFunction.OutputLen);

            // e. Apply the mask-generation function in Section 7.2.2.2 to compute:
            // dbMask = MGF(mgfSeed, nLen – HLen – 1).
            var dbMask = _mgf.Generate(mgfSeed, (nLen - HLen - 1) * BitString.BITSINBYTE);

            // f. Let maskedDB = DB ⊕ dbMask.
            var maskedDB = DB.XOR(dbMask);

            // g. Apply the mask-generation function in Section 7.2.2.2 to compute:
            // mgfSeedMask = MGF(maskedDB, HLen).
            var mgfSeedMask = _mgf.Generate(maskedDB, _sha.HashFunction.OutputLen);

            // h. Let maskedMGFSeed = mgfSeed ⊕ mgfSeedMask.
            var maskedMGFSeed = mgfSeed.XOR(mgfSeedMask);

            // i. Concatenate a single byte with hexadecimal value 00, maskedMGFSeed, and
            // maskedDB to form an encoded message EM of nLen bytes as follows:
            // EM = 00000000 || maskedMGFSeed || maskedDB,
            var EM = BitString.To8BitString(0x00).ConcatenateBits(maskedMGFSeed).ConcatenateBits(maskedDB);

            // 4. RSA encryption:
            // a. Convert the encoded message EM to an integer em (see Appendix B.2):
            // em = BS2I(EM).
            var em = EM.ToPositiveBigInteger();

            // b. Apply RSAEP (see Section 7.1.1) to the integer em using the public key (n, e) to
            // produce a ciphertext integer c:
            // c = RSAEP((n, e), em).
            var c = _rsa.Encrypt(em, rsaPublicKey).CipherText;

            // c. Convert the ciphertext integer c to a ciphertext byte string C of nLen bytes (see
            // Appendix B.1):
            // C = I2BS(c, nLen).
            var C = new BitString(c).PadToModulusMsb(rsaPublicKey.N.ExactBitLength().ValueToMod(BitString.BITSINBYTE));

            return(new SharedSecretResponse(C));
        }
Ejemplo n.º 5
0
        private PrimeGeneratorResult GeneratePrimes(PrimeGeneratorParameters param)
        {
            // 1, 2, 3 performed by guards

            // 4, 4.1
            var        i            = 0;
            BigInteger p            = 0;
            var        pqLowerBound = GetBound(param.Modulus);

            do
            {
                do
                {
                    // 4.2
                    if (p != 0 && _kat)
                    {
                        return(new PrimeGeneratorResult("Given p less than sqrt(2) * 2 ^ (n/2) - 1, need to get a new random number."));
                    }
                    p = _entropyProvider.GetEntropy(param.Modulus / 2).ToPositiveBigInteger();

                    // 4.3
                    if (_performAShift)
                    {
                        p += (param.A - p).PosMod(8);
                    }
                    else if (p.IsEven)
                    {
                        p++;
                    }

                    // 4.4
                } while (p < pqLowerBound);

                // 4.5
                if (NumberTheory.GCD(p - 1, param.PublicE) == 1)
                {
                    if (PrimeGeneratorHelper.MillerRabin(_primeTestMode, param.Modulus, p, false))
                    {
                        break;
                    }
                }

                // 4.6, 4.7
                i++;
                if (i >= _iBoundForP * (param.Modulus / 2))
                {
                    return(new PrimeGeneratorResult("Too many iterations for p"));
                }

                if (_kat)
                {
                    return(new PrimeGeneratorResult("Given p is not prime"));
                }
            } while (!_kat);

            // 5, 5.1
            i = 0;
            BigInteger q = 0;

            do
            {
                do
                {
                    // 5.2
                    if (q != 0 && _kat)
                    {
                        return(new PrimeGeneratorResult("Given q less than sqrt(2) * 2 ^ (n/2) - 1, need to get a new random number."));
                    }
                    q = _entropyProvider.GetEntropy(param.Modulus / 2).ToPositiveBigInteger();

                    // 5.3
                    if (_performBShift)
                    {
                        q += (param.B - q).PosMod(8);
                    }
                    else if (q.IsEven)
                    {
                        q++;
                    }

                    // 5.4
                    // 5.5
                } while (BigInteger.Abs(p - q) <= NumberTheory.Pow2(param.Modulus / 2 - 100) || q < pqLowerBound);

                // 5.6
                if (NumberTheory.GCD(q - 1, param.PublicE) == 1)
                {
                    if (PrimeGeneratorHelper.MillerRabin(_primeTestMode, param.Modulus, q, false))
                    {
                        break;
                    }
                }

                // 5.7, 5.8
                i++;
                if (i >= _iBoundForQ * (param.Modulus / 2))
                {
                    return(new PrimeGeneratorResult("Too many iterations for q"));
                }

                if (_kat)
                {
                    return(new PrimeGeneratorResult("Given q is not prime"));
                }
            } while (!_kat);

            var auxValues = new AuxiliaryResult();
            var primePair = new PrimePair {
                P = p, Q = q
            };

            return(new PrimeGeneratorResult(primePair, auxValues));
        }
Ejemplo n.º 6
0
        public IKdfParameter CreateParameter(OneStepConfiguration kdfConfiguration)
        {
            var fiPieces = kdfConfiguration.FixedInfoPattern.Split("||", StringSplitOptions.RemoveEmptyEntries).ToList();
            var fiPiecesRemovedDelimiter = fiPieces.Select(fiPiece => fiPiece.Replace("||", "")).ToList();

            var param = new KdfParameterOneStep()
            {
                L                  = kdfConfiguration.L,
                AuxFunction        = kdfConfiguration.AuxFunction,
                FixedInfoPattern   = kdfConfiguration.FixedInfoPattern,
                FixedInputEncoding = kdfConfiguration.FixedInfoEncoding,
                // If the fixedInfoPattern contains these optional context specific fields, make up a value for them
                Context = kdfConfiguration.FixedInfoPattern.Contains(nameof(KdfParameterOneStep.Context), StringComparison.OrdinalIgnoreCase) ?
                          _entropyProvider.GetEntropy(BitsOfEntropy) : null,
                AlgorithmId = kdfConfiguration.FixedInfoPattern.Contains(nameof(KdfParameterOneStep.AlgorithmId), StringComparison.OrdinalIgnoreCase) ?
                              _entropyProvider.GetEntropy(BitsOfEntropy) : null,
                Label = kdfConfiguration.FixedInfoPattern.Contains(nameof(KdfParameterOneStep.Label), StringComparison.OrdinalIgnoreCase) ?
                        _entropyProvider.GetEntropy(BitsOfEntropy) : null,
                T           = GetNullOrT(kdfConfiguration.FixedInfoPattern),
                EntropyBits = GetEntropyBitsOrNull(kdfConfiguration.FixedInfoPattern),
            };

            if (kdfConfiguration.SaltLen > 0)
            {
                param.Salt = kdfConfiguration.SaltMethod == MacSaltMethod.Default
                    ? new BitString(kdfConfiguration.SaltLen)
                    : _entropyProvider.GetEntropy(kdfConfiguration.SaltLen);
            }

            return(param);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// A.1.1.2 from FIPS 186-4
        /// </summary>
        /// <param name="L"></param>
        /// <param name="N"></param>
        /// <param name="seedLen"></param>
        /// <returns></returns>
        public PQGenerateResult Generate(int L, int N, int seedLen)
        {
            // 1. Check L/N pair
            if (!DSAHelper.VerifyLenPair(L, N))
            {
                return(new PQGenerateResult("Invalid L, N pair"));
            }

            // 2. Check seedLen
            if (seedLen < N)
            {
                return(new PQGenerateResult("Invalid seedLen"));
            }

            // 3, 4 Compute n, b
            var outLen = _sha.HashFunction.OutputLen;
            var n      = L.CeilingDivide(outLen) - 1;
            var b      = L - 1 - (n * outLen);

            do
            {
                BigInteger seed, q;

                do
                {
                    // 5. Get random seed
                    seed = _entropy.GetEntropy(seedLen).ToPositiveBigInteger();

                    // 6. Hash seed
                    var U = _sha.HashNumber(seed).ToBigInteger() % NumberTheory.Pow2(N - 1);

                    // 7. Compute q
                    q = NumberTheory.Pow2(N - 1) + U + 1 - (U % 2);

                    // Check if q is prime, if not go back to 5, assume highest security strength
                } while (!NumberTheory.MillerRabin(q, DSAHelper.GetMillerRabinIterations(L, N)));

                // 10, 11 Compute p
                var offset     = 1;
                var upperBound = (4 * L - 1);
                for (var ctr = 0; ctr <= upperBound; ctr++)
                {
                    // 11.1, 11.2
                    var W = _sha.HashNumber(seed + offset).ToBigInteger();
                    for (var j = 1; j < n; j++)
                    {
                        W += _sha.HashNumber(seed + offset + j).ToBigInteger() * NumberTheory.Pow2(j * outLen);
                    }
                    W += (_sha.HashNumber(seed + offset + n).ToBigInteger() % NumberTheory.Pow2(b)) * NumberTheory.Pow2(n * outLen);

                    // 11.3
                    var X = W + NumberTheory.Pow2(L - 1);

                    // 11.4
                    var c = X % (2 * q);

                    // 11.5
                    var p = X - (c - 1);

                    // 11.6, 11.7, 11.8
                    if (p >= NumberTheory.Pow2(L - 1))
                    {
                        // Check if p is prime, if so return
                        if (NumberTheory.MillerRabin(p, DSAHelper.GetMillerRabinIterations(L, N)))
                        {
                            return(new PQGenerateResult(p, q, new DomainSeed(seed), new Counter(ctr)));
                        }
                    }

                    // 11.9
                    offset += n + 1;
                }

                // 12
            } while (true);
        }