public KdfResult DeriveKey(IAns942Parameters param) { if (!(param is DerAns942Parameters derParams)) { return(new KdfResult("Unable to parse der parameters")); } if (derParams.KeyLen <= 0 || derParams.KeyLen > 65536) { return(new KdfResult($"KeyLen must be between [1, 65536]. Value given was: {derParams.KeyLen}")); } var d = (int)System.Math.Ceiling(derParams.KeyLen / (decimal)_sha.HashFunction.OutputLen); var h = new BitString(0); var counter = BitString.To32BitString(0); for (var i = 1; i <= d; i++) { // Increment Counter counter = counter.BitStringAddition(BitString.One()); // Prepare ANS.1/DER encoded OtherInfo var derEncodedOtherInfo = DerEncode(derParams, counter); var str = derEncodedOtherInfo.ToHex(); // H[i] = Hash(ZZ || otherInfo) h = h.ConcatenateBits(_sha.HashMessage(derParams.Zz.ConcatenateBits(derEncodedOtherInfo)).Digest); } return(new KdfResult(h.GetMostSignificantBits(derParams.KeyLen))); }
private BitString HashGen(BitString v, int bitsToReturn) { // 1 var m = bitsToReturn / HashAttributes.OutputLength + (bitsToReturn % HashAttributes.OutputLength != 0 ? 1 : 0); // 2 var data = v.GetDeepCopy(); // 3 var W = new BitString(0); // 4 for (var i = 0; i < m; i++) { // 4.1 var w = _sha.HashMessage(data).Digest; // 4.2 W = W.ConcatenateBits(w); // 4.3 data = data.BitStringAddition(BitString.One()).GetLeastSignificantBits(HashAttributes.SeedLength); } // 5 var returnedBits = W.MSBSubstring(0, bitsToReturn); // 6 return(returnedBits); }
// Public for use in HashConditioningComponent public DrbgResult Hash_Df(BitString data, int bitsToReturn) { // 0 if (bitsToReturn > 255 * HashAttributes.OutputLength) { throw new ArgumentException("Requesting too many bits to return"); } // 1 var temp = new BitString(0); // 2 var len = bitsToReturn.CeilingDivide(HashAttributes.OutputLength); // 3 var counter = new BitString("01"); // 4 for (var i = 0; i < len; i++) { // 4.1 var dataToHash = counter.ConcatenateBits(BitString.To32BitString(bitsToReturn)).ConcatenateBits(data); temp = temp.ConcatenateBits(_sha.HashMessage(dataToHash).Digest); // 4.2 counter = counter.BitStringAddition(BitString.One()); } // 5 var requestedBits = temp.MSBSubstring(0, bitsToReturn); // 6 return(new DrbgResult(requestedBits)); }
public KdfResult DeriveKey(IAns942Parameters param) { if (!(param is ConcatAns942Parameters concatParams)) { return(new KdfResult("Unable to parse concat parameters")); } if (concatParams.KeyLen <= 0 || concatParams.KeyLen > 65536) { return(new KdfResult($"KeyLen must be between [1, 65536]. Value given was: {concatParams.KeyLen}")); } var d = (int)System.Math.Ceiling(concatParams.KeyLen / (decimal)_sha.HashFunction.OutputLen); var counter = BitString.To32BitString(1); var h = new BitString(0); for (var i = 1; i <= d; i++) { // H[i] = Hash(ZZ || counter || otherInfo) var hashInput = concatParams.Zz.ConcatenateBits(counter).ConcatenateBits(concatParams.OtherInfo); h = h.ConcatenateBits(_sha.HashMessage(hashInput).Digest); counter = counter.BitStringAddition(BitString.One()); } return(new KdfResult(h.GetMostSignificantBits(concatParams.KeyLen))); }
public BitString GetNextIV() { var currentIV = _iv.GetLeastSignificantBits(_blockSize).GetDeepCopy(); _iv = _iv.BitStringAddition(BitString.One()); return(currentIV); }
/// <summary> /// pad10*1 /// </summary> /// <param name="message">Message to which to add padding</param> /// <param name="x">Positive integer, rate of sponge function</param> /// <returns></returns> public static BitString PadMessage(BitString message, int x) { var m = message.BitLength; var j = ((-1 * m - 2) % x + x) % x; var zeros = new BitString(j); // Works just fine if j == 0 // 1 || 0^j || 1 var padding = BitString.ConcatenateBits(BitString.One(), BitString.ConcatenateBits(zeros, BitString.One())); return(BitString.ConcatenateBits(message, padding)); }
private BitString ConcatenatePieceOntoOtherInfo(string workingPiece) { BitString oi = new BitString(0); if (workingPiece.Equals("uPartyInfo", StringComparison.OrdinalIgnoreCase)) { if (_thisPartyKeyAgreementRole == KeyAgreementRole.InitiatorPartyU) { oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_thisPartyOtherInfo.PartyId)); oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_thisPartyOtherInfo.DkmNonce)); } else { oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_otherPartyOtherInfo.PartyId)); oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_otherPartyOtherInfo.DkmNonce)); } return(oi); } if (workingPiece.Equals("vPartyInfo", StringComparison.OrdinalIgnoreCase)) { if (_thisPartyKeyAgreementRole == KeyAgreementRole.ResponderPartyV) { oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_thisPartyOtherInfo.PartyId)); oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_thisPartyOtherInfo.DkmNonce)); } else { oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_otherPartyOtherInfo.PartyId)); oi = oi.ConcatenateBits(BitString.GetAtLeastZeroLengthBitString(_otherPartyOtherInfo.DkmNonce)); } return(oi); } if (workingPiece.Equals("counter", StringComparison.OrdinalIgnoreCase)) { oi = oi.ConcatenateBits(new BitString(32).BitStringAddition(BitString.One())); return(oi); } if (workingPiece.StartsWith("literal[", StringComparison.OrdinalIgnoreCase)) { // remove the "literal[]" to get just the hex value workingPiece = workingPiece.Replace("literal[", "").Replace("]", ""); oi = oi.ConcatenateBits(new BitString(workingPiece)); return(oi); } throw new ArgumentException(nameof(workingPiece)); }
public void ShouldWrapTheCounterWhenAtMaxValue() { var initialValue = BitString.Ones(128); var subject = new AdditiveCounter(_aesEngine, initialValue); var firstResult = subject.GetNextIV(); var secondResult = subject.GetNextIV(); var thirdResult = subject.GetNextIV(); Assert.AreEqual(initialValue, firstResult); Assert.AreEqual(BitString.Zeroes(128), secondResult); Assert.AreEqual(BitString.ConcatenateBits(BitString.Zeroes(127), BitString.One()), thirdResult); }
private HashResult Md5Final() { var originalLength = _fullMessage.Sum(block => block.BitLength); var lastBlock = _fullMessage[_fullMessage.Length - 1]; // If the last block is full, we need to process and put a new one on the end if (lastBlock.BitLength == SizeOfChunk) { var result = Md5Compress(lastBlock); if (!result.Success) { return(result); } _fullMessage = _fullMessage.Append(new BitString(0)).ToArray(); lastBlock = _fullMessage[_fullMessage.Length - 1]; } lastBlock = lastBlock.ConcatenateBits(BitString.One()); if (lastBlock.BitLength > SizeOfChunk) { return(new HashResult("Invalid block size, must be 512-bits")); } // If the last block has more than 448 bits, append 0s to fill it and process the full block if (lastBlock.BitLength > 448) { lastBlock = lastBlock.ConcatenateBits(BitString.Zeroes(SizeOfChunk - lastBlock.BitLength)); var result = Md5Compress(lastBlock); if (!result.Success) { return(result); } _fullMessage = _fullMessage.Append(new BitString(0)).ToArray(); lastBlock = _fullMessage[_fullMessage.Length - 1]; } // Append zeroes to the last block until it has 448 bits and append 64 bits of original length lastBlock = lastBlock.ConcatenateBits(BitString.Zeroes(448 - lastBlock.BitLength)); var lengthBytes = BitString.To64BitString(originalLength).ToBytes(true); lastBlock = lastBlock.ConcatenateBits(new BitString(lengthBytes)); // Process the final block return(Md5Compress(lastBlock)); }
/// <summary> /// External Keccak function. This is the method to call. /// </summary> /// <param name="message">Message to hash</param> /// <param name="digestSize">Size of the digest to return</param> /// <param name="capacity">Capacity of the function</param> /// <param name="outputType">XOF for SHAKE, CONSTANT for SHA3, cXOF for cSHAKE</param> /// <param name="cSHAKEPrePad">True if cSHAKE had customization parameters other than empty string</param> /// <returns>Message digest as BitString</returns> public static BitString Keccak(BitString message, int digestSize, int capacity, bool XOF, bool cSHAKEPrePad = false) { message = ConvertEndianness(message); if (!cSHAKEPrePad && XOF) { message = BitString.ConcatenateBits(message, BitString.Ones(4)); } else if (!XOF) { message = BitString.ConcatenateBits(message, BitString.Zero()); message = BitString.ConcatenateBits(message, BitString.One()); } return(Sponge(message, digestSize, capacity)); }
/// <inheritdoc /> protected override void GenerateDomainParameters() { var paramDetails = ParameterSetDetails.GetDetailsForFfcParameterSet(SchemeParameters.KasAlgoAttributes.ParameterSet); SetDomainParameters( Dsa.GenerateDomainParameters( new FfcDomainParametersGenerateRequest( paramDetails.qLength, paramDetails.pLength, paramDetails.qLength, Dsa.Sha.HashFunction.OutputLen, BitString.One(), PrimeGenMode.Provable, GeneratorGenMode.Canonical ) ).PqgDomainParameters); }
public BitString Expand(BitString pseudoRandomKey, BitString otherInfo, int keyLengthBytes) { // keyLength comes in as bytes var keyLengthBits = keyLengthBytes * 8; var n = keyLengthBits.CeilingDivide(_hmac.OutputLength); var t = new BitString(0); var counter = new BitString("00"); var result = new BitString(0); for (short i = 1; i <= n; i++) { counter = counter.BitStringAddition(BitString.One()); t = _hmac.Generate(pseudoRandomKey, t.ConcatenateBits(otherInfo).ConcatenateBits(counter)).Mac; result = result.ConcatenateBits(t); } return(result.GetMostSignificantBits(keyLengthBits)); }
public static BitString Encode(EdPoint point, int b) { var encoding = new BitString(point.Y, b); var xBit = new BitString(point.X, b).GetLeastSignificantBits(1); var bytes = new byte[b / 8]; bytes[0] = 1 << 7; if (xBit.Equals(BitString.One())) { encoding = encoding.OR(new BitString(bytes)); } else { encoding = encoding.AND(new BitString(bytes).NOT()); } return(BitString.ReverseByteOrder(encoding)); // switch to little endian }
public BitString GetNextIV() { if (_iv.BitLength < _blockSize) { _iv = BitString.Zeroes(_blockSize - _iv.BitLength).ConcatenateBits(_iv); } var currentIV = _iv.GetLeastSignificantBits(_blockSize).GetDeepCopy(); // Avoid throwing an exception by subtracting from 000...0 if (currentIV.Equals(BitString.Zeroes(_blockSize))) { _iv = BitString.Ones(_blockSize); } else { _iv = _iv.BitStringSubtraction(BitString.One()); } return(currentIV); }
private void Update(BitString seedMaterial) { BitString v = V.GetDeepCopy(); BitString key = Key.GetDeepCopy(); // 1. temp = Null BitString temp = new BitString(0); // 2. While (len(temp)<seedlen) do: while (temp.BitLength < CounterAttributes.SeedLength) { v = v .BitStringAddition(BitString.One()) .ConcatenateBits(new BitString(CounterAttributes.OutputLength - v.BitLength)); // Add zeroes to bitstring to make it the length of the OutputLength BitString outputBlock = BlockEncrypt(key, v); temp = temp.ConcatenateBits(outputBlock); } // 3. temp = Leftmost seedlen bits of temp temp = temp.GetMostSignificantBits(CounterAttributes.SeedLength); // 4. temp = temp xor provided_data Debug.Assert(temp.BitLength == seedMaterial.BitLength); temp = temp.XOR(seedMaterial); // 5. Key = Leftmost keylen bits of temp key = temp.GetMostSignificantBits(CounterAttributes.KeyLength); // 6. V = Rightmost outlen bits of temp v = temp.GetLeastSignificantBits(CounterAttributes.OutputLength); // 7. Return new values of Key and V Key = key.GetDeepCopy(); V = v.GetDeepCopy(); }
private void GetDataFromPiece(Dictionary <string, BitString> fixedInfoParts, string workingPiece, FixedInfoParameter fixedInfoParameter) { if (workingPiece.Equals("uPartyInfo", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, BitString.GetAtLeastZeroLengthBitString(fixedInfoParameter.FixedInfoPartyU.PartyId) .ConcatenateBits( BitString.GetAtLeastZeroLengthBitString(fixedInfoParameter.FixedInfoPartyU.EphemeralData))); return; } if (workingPiece.Equals("uPartyId", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, BitString.GetAtLeastZeroLengthBitString(fixedInfoParameter.FixedInfoPartyU.PartyId)); return; } if (workingPiece.Equals("uEphemeralData", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, BitString.GetAtLeastZeroLengthBitString(fixedInfoParameter.FixedInfoPartyU.EphemeralData)); return; } if (workingPiece.Equals("vPartyInfo", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, BitString.GetAtLeastZeroLengthBitString(fixedInfoParameter.FixedInfoPartyV.PartyId) .ConcatenateBits( BitString.GetAtLeastZeroLengthBitString(fixedInfoParameter.FixedInfoPartyV.EphemeralData))); return; } if (workingPiece.Equals("vPartyId", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, BitString.GetAtLeastZeroLengthBitString(fixedInfoParameter.FixedInfoPartyV.PartyId)); return; } if (workingPiece.Equals("vEphemeralData", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, BitString.GetAtLeastZeroLengthBitString(fixedInfoParameter.FixedInfoPartyV.EphemeralData)); return; } if (workingPiece.Equals("L", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, BitString.To32BitString(fixedInfoParameter.L)); return; } if (workingPiece.Equals("salt", StringComparison.OrdinalIgnoreCase)) { if (fixedInfoParameter.Salt?.BitLength > 0) { // We only want to add the salt to the fixed info when it isn't the default if (fixedInfoParameter.Salt.ToPositiveBigInteger() == 0) { return; } fixedInfoParts.Add(workingPiece, fixedInfoParameter.Salt); } return; } if (workingPiece.Equals("iv", StringComparison.OrdinalIgnoreCase)) { if (fixedInfoParameter.Iv?.BitLength > 0) { fixedInfoParts.Add(workingPiece, fixedInfoParameter.Iv); } return; } if (workingPiece.Equals("counter", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, new BitString(32).BitStringAddition(BitString.One())); return; } if (workingPiece.Equals("algorithmId", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, fixedInfoParameter.AlgorithmId); return; } if (workingPiece.Equals("label", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, fixedInfoParameter.Label); return; } if (workingPiece.Equals("context", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, fixedInfoParameter.Context); return; } if (workingPiece.Equals("t", StringComparison.OrdinalIgnoreCase)) { fixedInfoParts.Add(workingPiece, fixedInfoParameter.T); return; } if (workingPiece.StartsWith("literal[", StringComparison.OrdinalIgnoreCase)) { // remove the "literal[]" to get just the hex value workingPiece = workingPiece.Replace("literal[", "").Replace("]", ""); fixedInfoParts.Add(workingPiece, new BitString(workingPiece)); return; } if (workingPiece.StartsWith("entropyBits[", StringComparison.OrdinalIgnoreCase)) { workingPiece = workingPiece.Replace("entropyBits[", "").Replace("]", ""); int.TryParse(workingPiece, out var result); fixedInfoParts.Add("entropyBits", fixedInfoParameter.EntropyBits); return; } throw new ArgumentException($"{nameof(workingPiece)}: {workingPiece}"); }
public virtual KdfResult DeriveKey(BitString z, int keyDataLength, BitString fixedInfo, BitString salt) { KeyDataLength = keyDataLength; // 1. reps = keydatalen / hashlen. var reps = KeyDataLength.CeilingDivide(OutputLength); // 2. If reps > (23^2 −1), then return an error indicator without performing the remaining actions. if (reps > ((BigInteger)1 << 32) - 1) { throw new ArgumentException($"{nameof(reps)} exceeds (2^32)-1"); } if (!UseCounter & reps != 1) { throw new ArgumentException("When utilizing NoCounter, reps should always be 1."); } // 3. Initialize a 32-bit, big-endian bit string counter as 1 (i.e. 0x00000001). var counter = new BitString(32).BitStringAddition(BitString.One()); if (!UseCounter) { counter = new BitString(0); } var messageToH = counter.ConcatenateBits(z).ConcatenateBits(fixedInfo); // 4. If counter || Z || FixedInfo is more than max_H_inputlen bits long, // then return an error indicator without performing the remaining actions if (MaxInputLength != -1 && messageToH.BitLength > MaxInputLength) { throw new ArgumentException($"{nameof(messageToH)} exceeds length of {MaxInputLength}"); } BitString k = new BitString(0); // 5. For i = 1 to reps by 1, do the following: for (int i = 0; i < reps - 1; i++) { // 5.1 Compute K(i) = H(counter || Z || OtherInfo). k = k.ConcatenateBits(H(messageToH, salt)); // 5.2 Increment counter(modulo 23^2), treating it as an unsigned 32 - bit integer. counter = counter.BitStringAddition(BitString.One()); // Update the message to H with the current counter messageToH = counter.ConcatenateBits(z).ConcatenateBits(fixedInfo); } // 6. Let K_Last be set to K(reps) if (keydatalen / hashlen) is an integer; otherwise, let K_Last // be set to the(keydatalen mod hashlen) leftmost bits of K(reps) if (KeyDataLength % OutputLength == 0) { k = k.ConcatenateBits(H(messageToH, salt)); } else { k = k.ConcatenateBits( H(messageToH, salt).GetMostSignificantBits(KeyDataLength % OutputLength) ); } // 7. Set DerivedKeyingMaterial = K(1) || K(2) || … || K(reps-1) || K_Last. return(new KdfResult(k.GetMostSignificantBits(keyDataLength))); }
private DrbgResult GenerateAlgorithmNoDf(int requestedNumberOfBits, BitString additionalInput) { additionalInput = additionalInput.GetDeepCopy(); // 1. If reseed_counter > reseed_interval, then return an indication that // a reseed is required if (ReseedCounter > Attributes.MaxNumberOfRequestsBetweenReseeds) { return(new DrbgResult(DrbgStatus.ReseedRequired)); } // 2. If (additional_input != Null), then if (additionalInput.BitLength != 0) { // 2.1 temp = len(additional_input) int tempLen = additionalInput.BitLength; // 2.2 If (temp < seedlen), then // additional_input = additional_input || 0^(seedlen - temp) if (tempLen < CounterAttributes.SeedLength) { additionalInput = additionalInput.ConcatenateBits(new BitString(CounterAttributes.SeedLength - tempLen)); } // 2.3 (Key, V) = Update(additional_input, Key, V) Update(additionalInput); } else { // 2 (cont) Else additional_input = 0^seedlen additionalInput = new BitString(CounterAttributes.SeedLength); } // 3. temp = Null BitString temp = new BitString(0); // 4. While (len(temp) < requested_number_of_bits) do: while (temp.BitLength < requestedNumberOfBits) { // 4.1 V = (V + 1) mod 2^outlen V = V .BitStringAddition(BitString.One()) .GetLeastSignificantBits(CounterAttributes.OutputLength); // 4.2 output_block = Block_Encrypt(Key, V) BitString outputBlock = BlockEncrypt(Key, V); // 4.3 temp = temp || output_block temp = temp.ConcatenateBits(outputBlock); } // 5. returned_bits = Leftmost requested_number_of_bits of temp var returnedBits = temp.GetMostSignificantBits(requestedNumberOfBits); // 6. (Key, V) = Update(additional_input, Key, V) // Comment: Update for backtracking resistance Update(additionalInput); // 7. reseed_counter = reseed_counter + 1 ++ReseedCounter; // 8. Return SUCCESS and returned bits; also return Key, V and // reseed_counter as the new_working_state // NOTE: returned_bits is a function parameter passed by non-const // value. m_Key, m_V, and m_reseed_counter hold the new working state return(new DrbgResult(returnedBits)); }
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)); }