public BigInteger GetNonce(BigInteger privateD, BigInteger hashedMessage, BigInteger orderN) { return(_entropyProvider.GetEntropy(1, orderN - 1)); }
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)); }
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)); }
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)); }
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); }
/// <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); }