public void ShouldEncryptNotModEightCs2() { var payloadLen = 374; var iv = new BitString("00000000000000000000000000000000"); var key = new BitString("00000000000000000000000000000000"); var pt = new BitString("F34481EC3CC627BACD5DC3FB08F273E600000000000000000000000000000000000000000000000000000000000000") .GetMostSignificantBits(payloadLen); var encryptResult = _subjectCs2 .ProcessPayload( new ModeBlockCipherParameters( BlockCipherDirections.Encrypt, iv.GetDeepCopy(), key.GetDeepCopy(), pt.GetDeepCopy())).Result; var decryptResult = _subjectCs2 .ProcessPayload( new ModeBlockCipherParameters( BlockCipherDirections.Decrypt, iv.GetDeepCopy(), key.GetDeepCopy(), encryptResult.GetDeepCopy())).Result; Assert.AreEqual(pt.ToHex(), decryptResult.ToHex(), "Expected decrypt back to original PT"); }
public void ShouldEncryptNotModEightCs3() { var payloadLen = 374; var iv = new BitString("00000000000000000000000000000000"); var key = new BitString("00000000000000000000000000000000"); var pt = new BitString("F34481EC3CC627BACD5DC3FB08F273E600000000000000000000000000000000000000000000000000000000000000") .GetMostSignificantBits(payloadLen); var expectedCtAsPerAegis = new BitString("0336763E966D92595A567CC9CE537F5ED9492AAFC53406FCD852F32A99EED2AD6EF1A3F88079814A8E7083AB12EB10") .GetMostSignificantBits(payloadLen); var expectedCtFromServer = new BitString("0336763E966D92595A567CC9CE537F5ED2AD6EF1A3F88079814A8E7083AB12EBD9492AAFC53406FCD852F32A99EE08") .GetMostSignificantBits(payloadLen); var encryptResult = _subjectCs3 .ProcessPayload( new ModeBlockCipherParameters( BlockCipherDirections.Encrypt, iv.GetDeepCopy(), key.GetDeepCopy(), pt.GetDeepCopy())).Result; var decryptResult = _subjectCs3 .ProcessPayload( new ModeBlockCipherParameters( BlockCipherDirections.Decrypt, iv.GetDeepCopy(), key.GetDeepCopy(), encryptResult.GetDeepCopy())).Result; //Assert.AreEqual(expectedCtFromServer.ToHex(), encryptResult.ToHex(), "Expected CT"); Assert.AreEqual(pt.ToHex(), decryptResult.ToHex(), "Expected decrypt back to original PT"); }
private MCTResult <AlgoArrayResponse> Encrypt(IModeBlockCipherParameters param) { var ivs = TdesPartitionHelpers.SetupIvs(param.Iv); var responses = new List <AlgoArrayResponse> { new AlgoArrayResponse { IV = ivs[0], Keys = param.Key.GetDeepCopy(), PlainText = param.Payload.GetDeepCopy() } }; var lastCipherTexts = new List <BitString>(); var indexAtWhichToStartSaving = NUMBER_OF_ITERATIONS - NUMBER_OF_OUTPUTS_TO_SAVE; for (var i = 0; i < NumberOfCases; i++) { var encryptionOutputs = new List <BitString>(); var cipherText = new BitString(0); var encryptionInput = new BitString(0); var key = responses.Last().Keys.GetDeepCopy(); for (var j = 0; j < NUMBER_OF_ITERATIONS; j++) { encryptionInput = j < PARTITIONS ? ivs[j] : encryptionOutputs[j - PARTITIONS]; var encryptionOutput = _algo.ProcessPayload(new ModeBlockCipherParameters( BlockCipherDirections.Encrypt, key, encryptionInput )).Result; encryptionOutputs.Add(encryptionOutput.GetDeepCopy()); cipherText = param.Payload.XOR(encryptionOutput); if (j >= indexAtWhichToStartSaving) { lastCipherTexts.Insert(0, cipherText.GetDeepCopy()); } param.Payload = encryptionInput.GetDeepCopy(); } responses.Last().CipherText = cipherText.GetDeepCopy(); ivs = TdesPartitionHelpers.SetupIvs(encryptionOutputs[9995].XOR(cipherText)); responses.Add(new AlgoArrayResponse { IV = ivs[0], Keys = _keyMaker.MixKeys(new TDESKeys(responses[i].Keys.GetDeepCopy()), lastCipherTexts.ToList()).ToOddParityBitString(), PlainText = responses.Last().PlainText.XOR(encryptionInput) }); } responses.RemoveAt(responses.Count() - 1); return(new MCTResult <AlgoArrayResponse>(responses)); }
public SignatureResult BuildSign() { // Check for empty values that prevent building if (_paddingScheme == null || _rsa == null || _publicKey == null || _privateKey == null || _message == null) { return(new SignatureResult("Improper signature build")); } _key = new KeyPair { PubKey = _publicKey, PrivKey = _privateKey }; // Do provided padding method either correct or incorrect var preCheck = _paddingScheme.PrePadCheck(_key, _message.GetDeepCopy(), _publicKey.N.ExactBitLength()); var paddedResult = _paddingScheme.Pad(preCheck.key.PubKey.N.ExactBitLength(), preCheck.message); if (!paddedResult.Success) { return(new SignatureResult(paddedResult.ErrorMessage)); } // Perform the RSA Decryption var decryptionResult = _rsa.Decrypt(paddedResult.PaddedMessage.ToPositiveBigInteger(), preCheck.key.PrivKey, preCheck.key.PubKey); if (!decryptionResult.Success) { return(new SignatureResult(decryptionResult.ErrorMessage)); } // Perform the Post-Check depending on the padding scheme var postCheck = _paddingScheme.PostSignCheck(decryptionResult.PlainText, preCheck.key.PubKey); return(new SignatureResult(postCheck)); }
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); }
protected override BitString Wrap(BitString K, BitString S, bool wrapWithInverseCipher) { // 0. Pre-conditions var n = S.BitLength / 32; if ((n < 3) || (S.BitLength % 32 != 0)) { throw new ArgumentException($"Invalid {nameof(S)} length."); } var keylen = K.BitLength; var K2 = K.GetDeepCopy(); //if (keylen == 192) //{ // // Convert to 168 bits because TDES Block encrypt takes 168 bits // K2 = to168BitKey(K); // keylen = K2.BitLength; //} //else //{ // K2 = K; //} //if (keylen != 168) //{ // throw new ArgumentException($"Invalid {nameof(keylen)}"); //} // 1. Initialize variables // 1.a) Let s = 6(n-1) int s = 6 * (n - 1); // 1.b) Let S1,S2,...,Sn be the semi-blocks s.t. S=S1 || S2 || ... || Sn // 1.c) Let A0 = S1 BitString A = S.GetMostSignificantBits(32); // 1.d) For i=2,...,n: let Ri0 = Si BitString R2n = S.GetLeastSignificantBits(S.BitLength - 32); // 2. Calculate the intermediate values. For t = 1,...,s update variables // as follows: for (int t = 1; t <= s; ++t) { // a) A^t = MSB32(CIPH_K(A^t-1 || R2^t-1)) xor [t]32 BitString R2 = R2n.GetMostSignificantBits(32); //BitString t32 = to_bitstring32((unsigned long long)t); BitString t32 = BitString.To64BitString(t).GetLeastSignificantBits(32); var param = new ModeBlockCipherParameters(BlockCipherDirections.Encrypt, K2, A.ConcatenateBits(R2), wrapWithInverseCipher); BitString block_t = Cipher.ProcessPayload(param).Result; A = block_t.GetMostSignificantBits(32).XOR(t32); // b) For i=2,...,n: Ri^t = Ri+1^t-1 // c) Rn^t = LSB32(CIPH_K(CIPH_K(A^t-1 || R2^t-1))) R2n = R2n.GetLeastSignificantBits(R2n.BitLength - 32).ConcatenateBits(block_t.GetLeastSignificantBits(32)); } // 3. Output the results: // a) Let C1 = A^s // b) For i=2,...,n: Ci = Ri^s // c) Return C1 || C2 || ... || Cn return(A.ConcatenateBits(R2n)); }
// Override with good or bad padding methods public virtual PaddingResult Pad(int nlen, BitString message) { // 1. Message Hashing var hashedMessage = Sha.HashMessage(message).Digest; // 2. Hash Encapsulation var trailer = GetTrailer(); // Header is always 4, trailer is always 16 var paddingLen = nlen - Header.BitLength - Sha.HashFunction.OutputLen - trailer.BitLength; var padding = GetPadding(paddingLen); var IR = Header.GetDeepCopy(); IR = BitString.ConcatenateBits(IR, padding); IR = BitString.ConcatenateBits(IR, hashedMessage); IR = BitString.ConcatenateBits(IR, trailer); if (IR.BitLength != nlen) { return(new PaddingResult("Improper length for IR")); } return(new PaddingResult(IR)); }
protected override BitString WrapInverse(BitString K, BitString C, bool wrappedWithInverseCipher) { // 0. Pre-conditions int n = C.BitLength / 32; if ((n < 3) || (C.BitLength % 32 != 0)) { throw new ArgumentException($"Invalid {nameof(C)} length."); } int keyLength = K.BitLength; var K2 = K.GetDeepCopy(); //if (keyLength == 192) //{ // // Convert to 168 bits because TDES Block encrypt takes 168 bits // K2 = to168BitKey(K); // keyLength = K2.BitLength; //} //else //{ // K2 = K; //} //if (keyLength != 168) //{ // throw new ArgumentException($"Invalid {nameof(keyLength)}"); //} // 1. Initialize variables // 1.a) Let s = 6(n-1) int s = 6 * (n - 1); // 1.b) Let C1,C2,...,Cn be the semi-blocks s.t. C=C1 || C2 || ... || Cn // 1.c) Let As = C1 BitString A = C.GetMostSignificantBits(32); // 1.d) For i=2,...,n: let Ri0 = Ci BitString R2n = C.GetLeastSignificantBits(C.BitLength - 32); // 2. Calculate the intermediate values. For t = s, s-1, ..., 1, // update the variables as follows: for (int t = s; t >= 1; --t) { // a) A^t-1 = MSB(CIPH^-1K((A^t xor [t]32) || Rn^t)) BitString t32 = BitString.To64BitString(t).GetLeastSignificantBits(32); BitString Rn = R2n.GetLeastSignificantBits(32); var param = new ModeBlockCipherParameters(BlockCipherDirections.Decrypt, K2, A.XOR(t32).ConcatenateBits(Rn), wrappedWithInverseCipher); BitString block_t = Cipher.ProcessPayload(param).Result; A = block_t.GetMostSignificantBits(32); // b) R2^t-1 = LSB(CIPH^-1K((A^t xor [t]32) || Rn^t)) // c) For i=2,...,n-1, Ri+1^t-1 = Ri^t R2n = block_t.GetLeastSignificantBits(32).ConcatenateBits(R2n.GetMostSignificantBits(R2n.BitLength - 32)); } // 3. Output the results: // 3.a) Let S1 = A0 // 3.b) For i=2,...,n: Si = Ri0 // 3.c) Return S1 || S2 || ... || Sn return(A.ConcatenateBits(R2n)); }
public static BitString[] SetupIvs(BitString iv) { return(new[] { iv.GetDeepCopy(), iv.AddWithModulo(new BitString("5555555555555555"), BLOCK_SIZE_BITS), iv.AddWithModulo(new BitString("AAAAAAAAAAAAAAAA"), BLOCK_SIZE_BITS) }); }
/* * INPUT: The initial Msg of 256 bits long * LmsParams * SEED * RootI * * { * lmsKeyPair = GenerateLmsKeyPair(SEED, RootI, Params); * Output0 = Msg; * for (j=0; j<100; j++) { * for (i=1; i<(isSample ? 101 : 1001); i++) { * M[i] = leftmost bits indexed from 96 to 352; * if (lmsKeyPair is expired) { * lmsKeyPair = GenerateLmsKeyPair(M[i], 128 left most bits of M[i], Params); * } * Output[i] = LmsSignature(M[i],lmsKeyPair); * lmsKeyPair = UpdateLmsKeyPair(lmsKeyPair); * } * Output[j] = Output[1000]; * OUTPUT: Output[j] * } * } */ #endregion MonteCarloAlgorithm Pseudocode public async Task <MCTResult <AlgoArrayResponse> > MCTHashAsync(LmsType[] lmsTypes, LmotsType[] lmotsTypes, BitString seed, BitString rootI, BitString message, bool isSample) { var hss = _hssFactory.GetInstance(lmsTypes.Length, lmsTypes, lmotsTypes, EntropyProviderTypes.Testable, seed, rootI); var keyPair = await hss.GenerateHssKeyPairAsync(); if (isSample) { NUM_OF_RESPONSES = 3; } var responses = new List <AlgoArrayResponse>(); var i = 0; var j = 0; var innerMessage = message.GetDeepCopy(); try { for (i = 0; i < NUM_OF_RESPONSES; i++) { var innerSignature = new BitString(0); var iterationResponse = new AlgoArrayResponse() { }; iterationResponse.Message = innerMessage; for (j = 0; j < (isSample ? 100 : 1000); j++) { if (keyPair.Expired) { hss = _hssFactory.GetInstance(lmsTypes.Length, lmsTypes, lmotsTypes, EntropyProviderTypes.Testable, innerMessage, innerMessage.MSBSubstring(0, 128)); keyPair = await hss.GenerateHssKeyPairAsync(); } innerSignature = (await hss.GenerateHssSignatureAsync(innerMessage, keyPair)).Signature; keyPair = await hss.UpdateKeyPairOneStepAsync(keyPair); innerMessage = innerSignature.MSBSubstring(96, 256); } iterationResponse.Signature = innerSignature.GetDeepCopy(); responses.Add(iterationResponse); } } catch (Exception ex) { ThisLogger.Debug($"i count {i}, j count {j}"); ThisLogger.Error(ex); return(new MCTResult <AlgoArrayResponse>($"{ex.Message}")); } return(new MCTResult <AlgoArrayResponse>(responses)); }
protected override DrbgStatus ReseedAlgorithm(BitString entropyInput, BitString additionalInput) { BitString seedMaterial; additionalInput = additionalInput.GetDeepCopy(); if (!DrbgParameters.DerFuncEnabled) { // 1. temp = len(additional_input) int temp = additionalInput.BitLength; // 2. If (temp < seedlen) then additional_input = // additional_input || 0^(seedlen - temp) if (temp < CounterAttributes.SeedLength) { additionalInput = additionalInput .ConcatenateBits(new BitString(CounterAttributes.SeedLength - temp)); // Concatenate with bitstring made up of 0s; } if (additionalInput.BitLength != CounterAttributes.SeedLength) { ThisLogger.Debug($"{nameof(additionalInput.BitLength)} != {nameof(CounterAttributes.SeedLength)}"); return(DrbgStatus.Error); } // 3. seed_material = entropy_input xor additional_input seedMaterial = entropyInput.XOR(additionalInput); } else { // 1. seed_material = entropy_input || additional_input seedMaterial = entropyInput.ConcatenateBits(additionalInput); // 2. seed_material = Block_Cipher_df(seed_material, seedlen) var blockCipherDf = BlockCipherDf(seedMaterial, CounterAttributes.SeedLength); if (blockCipherDf.Success) { seedMaterial = blockCipherDf.Bits; } else { ThisLogger.Debug("blockCipherDf"); return(DrbgStatus.Error); } } // 3./4. (Key, V) = Update(seed_material, Key, V) Update(seedMaterial); // 4./5. reseed_counter = 1 ReseedCounter = 1; // 5./6. Return V, Key, and reseed_counter as the new_working_state // NOTE: m_V, m_Key, and m_reseed_counter hold the new working state return(DrbgStatus.Success); }
public SharedSecretResponse Encrypt(PublicKey rsaPublicKey, BitString keyingMaterial, BitString additionalInput) { var keyingMaterialByteLen = keyingMaterial.BitLength.CeilingDivide(BitString.BITSINBYTE); var newKeyingMaterial = keyingMaterial.GetDeepCopy(); // Modify a random byte in the keying material prior to executing the base method newKeyingMaterial[_random.GetRandomInt(0, keyingMaterialByteLen)] += 2; return(_kts.Encrypt(rsaPublicKey, newKeyingMaterial, additionalInput)); }
private MCTResult <AlgoArrayResponse> Decrypt(IModeBlockCipherParameters param) { List <AlgoArrayResponse> responses = new List <AlgoArrayResponse>(); int i = 0; int j = 0; try { for (i = 0; i < _OUTPUT_ITERATIONS; i++) { AlgoArrayResponse iIterationResponse = new AlgoArrayResponse() { IV = param.Iv, Key = param.Key, CipherText = param.Payload }; responses.Add(iIterationResponse); List <BitString> previousPlainTexts = new List <BitString>(); param.Iv = param.Iv.GetDeepCopy(); param.Payload = param.Payload.GetDeepCopy(); for (j = 0; j < _INNER_ITERATIONS_PER_OUTPUT; j++) { var jResult = _algo.ProcessPayload(param); var jPlainText = jResult.Result.GetDeepCopy(); previousPlainTexts.Add(jPlainText); iIterationResponse.PlainText = jPlainText; param.Payload = GetNextPayload(j, iIterationResponse.IV, previousPlainTexts); BitString iv = param.Iv.GetDeepCopy(); BitString key = param.Key.GetDeepCopy(); BitString payload = param.Payload.GetDeepCopy(); SetupNextOuterLoopValues(ref iv, ref key, ref payload, j, previousPlainTexts); param.Iv = iv.GetDeepCopy(); param.Key = key.GetDeepCopy(); param.Payload = payload.GetDeepCopy(); } } } catch (Exception ex) { ThisLogger.Debug($"i count {i}, j count {j}"); ThisLogger.Error(ex); return(new MCTResult <AlgoArrayResponse>(ex.Message)); } return(new MCTResult <AlgoArrayResponse>(responses)); }
private Common.Symmetric.MCTResult <AlgoArrayResponse> Encrypt(IModeBlockCipherParameters param) { var responses = new List <AlgoArrayResponse> { new AlgoArrayResponse { IV = param.Iv, Keys = param.Key, PlainText = param.Payload } }; int numberOfOutputsToSave = 192 / Shift; var indexAtWhichToStartSaving = NUMBER_OF_ITERATIONS - numberOfOutputsToSave; for (var i = 0; i < NumberOfCases; i++) { Debug.WriteLineIf((i + 1) % 10 == 0, $"Running MCT Encryption round {i + 1} out of {NumberOfCases}"); var lastResponse = responses.Last(); var tempText = lastResponse.PlainText.GetDeepCopy(); var tempIv = lastResponse.IV.GetDeepCopy(); BitString prevTempIv = null; var lastCipherTexts = new List <BitString>(); BitString output = null; var keysForThisRound = responses[i].Keys; for (var j = 0; j < NUMBER_OF_ITERATIONS; j++) { prevTempIv = tempIv.GetDeepCopy(); output = _algo.ProcessPayload(new ModeBlockCipherParameters( BlockCipherDirections.Encrypt, tempIv, keysForThisRound, tempText )).Result; tempText = prevTempIv.MSBSubstring(0, Shift); if (j >= indexAtWhichToStartSaving) { lastCipherTexts.Insert(0, output.GetDeepCopy()); } } lastResponse.CipherText = output; responses.Add(new AlgoArrayResponse() { Keys = _keyMaker.MixKeys(new TDESKeys(lastResponse.Keys.GetDeepCopy()), lastCipherTexts).ToOddParityBitString(), PlainText = prevTempIv.GetDeepCopy().MSBSubstring(0, Shift), IV = tempIv.GetDeepCopy() }); } responses.RemoveAt(responses.Count() - 1); return(new Common.Symmetric.MCTResult <AlgoArrayResponse>(responses)); }
private Common.Symmetric.MCTResult <AlgoArrayResponse> Decrypt(IModeBlockCipherParameters param) { var responses = new List <AlgoArrayResponse> { new AlgoArrayResponse { IV = param.Iv.GetDeepCopy(), Keys = param.Key.GetDeepCopy(), CipherText = param.Payload.GetDeepCopy() } }; var indexAtWhichToStartSaving = NUMBER_OF_ITERATIONS - NUMBER_OF_OUTPUTS_TO_SAVE; for (var i = 0; i < NumberOfCases; i++) { var tempCipherText = responses.Last().CipherText.GetDeepCopy(); var tempIv = responses.Last().IV.GetDeepCopy(); BitString prevTempIv = null; SymmetricCipherResult decryptionResult = null; var lastPlainTexts = new List <BitString>(); for (var j = 0; j < NUMBER_OF_ITERATIONS; j++) { prevTempIv = tempIv.GetDeepCopy(); decryptionResult = _algo.ProcessPayload(new ModeBlockCipherParameters( BlockCipherDirections.Decrypt, tempIv, responses[i].Keys, tempCipherText )); tempCipherText = prevTempIv.GetDeepCopy(); if (j >= indexAtWhichToStartSaving) { lastPlainTexts.Insert(0, decryptionResult.Result.GetDeepCopy()); } } responses.Last().PlainText = decryptionResult.Result.GetDeepCopy(); responses.Add(new AlgoArrayResponse() { Keys = _keyMaker.MixKeys(new TDESKeys(responses.Last().Keys.GetDeepCopy()), lastPlainTexts).ToOddParityBitString(), CipherText = responses.Last().CipherText.GetDeepCopy().XOR(prevTempIv), IV = tempIv.GetDeepCopy() }); } responses.RemoveAt(responses.Count() - 1); return(new Common.Symmetric.MCTResult <AlgoArrayResponse>(responses)); }
private BitString HmacPrf(IHmac hmac, BitString secret, BitString seed, int outputLength) { var hmacLen = hmac.OutputLength; var numBlocks = outputLength.CeilingDivide(hmacLen); var A = seed.GetDeepCopy(); var output = new BitString(0); for (var i = 0; i < numBlocks; i++) { A = hmac.Generate(secret, A).Mac; output = output.ConcatenateBits(hmac.Generate(secret, A.ConcatenateBits(seed)).Mac); } return(output); }
public void OriginalSharedSecretShouldBeModified() { var kdfFactory = new KdfOneStepFactory(new NativeShaFactory(), new HmacFactory(new NativeShaFactory()), new KmacFactory(new CSHAKEWrapper())); var fakeKdfFactory = new FakeKdfFactory_BadZ(kdfFactory); var originalZ = new BitString("01"); var copyZ = originalZ.GetDeepCopy(); Assert.AreEqual(copyZ, originalZ, "sanity check"); var badKdf = fakeKdfFactory.GetInstance(KdaOneStepAuxFunction.SHA2_D256, true); badKdf.DeriveKey(originalZ, 256, new BitString(256), null); Assert.AreNotEqual(copyZ, originalZ, nameof(copyZ)); }
//INPUT: A random Seed n bits long //{ // MD[0] = Seed; // for (j=0; j<100; j++) { // for (i=1; i<1001; i++) { // M[i] = MD[i-1]; // MD[i] = SHA3(M[i]); // } // MD[0] = MD[1000]; // OUTPUT: MD[0] // } //} #endregion public MctResult <AlgoArrayResponse> MctHash(BitString message, MathDomain domain = null, bool isSample = false) { if (isSample) { NUM_OF_RESPONSES = 3; } var responses = new List <AlgoArrayResponse>(); var i = 0; var j = 0; try { for (i = 0; i < NUM_OF_RESPONSES; i++) { var iterationResponse = new AlgoArrayResponse { Message = message }; var innerMessage = message.GetDeepCopy(); var innerDigest = new BitString(0); for (j = 0; j < 1000; j++) { var innerResult = _sha.HashMessage(innerMessage); innerDigest = innerResult.Digest; innerMessage = innerDigest.GetDeepCopy(); } iterationResponse.Digest = innerDigest; responses.Add(iterationResponse); message = innerDigest; } } catch (Exception ex) { ThisLogger.Debug($"i count {i}, j count {j}"); ThisLogger.Error(ex); return(new MctResult <AlgoArrayResponse>(ex.Message)); } return(new MctResult <AlgoArrayResponse>(responses)); }
private BitString GetNextPayload(int j, BitString currentIv, List <BitString> previousOutputs) { switch (Shift) { case 1: if (j < 128) { // Note, Bits are stored in the opposite direction on the BitString in comparison to where the MCT pseudo code expects them return(currentIv .Substring(currentIv.BitLength - 1 - j, Shift).GetDeepCopy()); } else { return(previousOutputs[j - _blockSizeBits / Shift].GetDeepCopy()); } case 8: if (j < 16) { return(new BitString(new byte[] { currentIv[j] })); } else { return(previousOutputs[j - 16].GetDeepCopy()); } case 128: if (j == 0) { return(currentIv.GetDeepCopy()); } else { return(previousOutputs[previousOutputs.Count - 2].GetDeepCopy()); } default: throw new ArgumentException(nameof(Shift)); } }
public static BitString PadKey(BitString key, ISha sha) { var keyLength = key.BitLength; var blockSize = sha.HashFunction.BlockSize; // Step 1 If the length of K = B: set K0 = K.Go to step 4. if (keyLength == blockSize) { return(key.GetDeepCopy()); } // Step 2 If the length of K > B: hash K to obtain an L byte string, then append(B - L) zeros to create a B - byte string K0(i.e., K0 = H(K) || 00...00). Go to step 4. else if (keyLength > blockSize) { var hashedKey = sha.HashMessage(key).Digest; return(hashedKey.ConcatenateBits(BitString.Zeroes(blockSize - hashedKey.BitLength)).GetDeepCopy()); } // Step 3 If the length of K < B: append zeros to the end of K to create a B - byte string K0 (e.g., if K is 20 bytes in length and B = 64, then K will be appended with 44 zero bytes x’00’). else { return(key.ConcatenateBits(BitString.Zeroes(blockSize - keyLength)).GetDeepCopy()); } }
public MacResult Generate(BitString key, BitString message, int macLength = 0) { // From MD5 var blockSize = 512; BitString shortenedKey; if (key.BitLength > blockSize) { shortenedKey = _hash.Hash(key).Digest; } else if (key.BitLength == blockSize) { shortenedKey = key.GetDeepCopy(); } else { shortenedKey = key.ConcatenateBits(BitString.Zeroes(blockSize - key.BitLength)); } var oKeyPad = _opad.XOR(shortenedKey); var iKeyPad = _ipad.XOR(shortenedKey); // HMAC_MD5 = Hash(oKeyPad || Hash(iKeyPad || message)) var iKeyPadConcatMessage = iKeyPad.GetDeepCopy(); if (message.BitLength != 0) { iKeyPadConcatMessage = iKeyPadConcatMessage.ConcatenateBits(message); } var innerDigest = _hash.Hash(iKeyPadConcatMessage).Digest; var oKeyPadConcatInnerDigest = oKeyPad.ConcatenateBits(innerDigest); var outerDigest = _hash.Hash(oKeyPadConcatInnerDigest).Digest; return(new MacResult(outerDigest)); }
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(); }
public BitString AesCtr(BitString key, BitString initialCounterBlock, BitString input) { var ecb = _factory.GetStandardCipher(_engine, BlockCipherModesOfOperation.Ecb); var block = initialCounterBlock.GetDeepCopy(); var output = new BitString(0); var iterations = (int)System.Math.Ceiling(input.BitLength / 128.0); for (var i = 0; i < iterations; i++) { var inputBlock = (i * 128 + 128 <= input.BitLength) ? input.MSBSubstring(i * 128, 128) : input.MSBSubstring(i * 128, input.BitLength % 128); if (block.BitLength != 128) { throw new Exception($"\nBlock length is not a mulitple of 128.\nInput: {input.ToHex()}\nKey: {key.ToHex()}\nInitialCtr: {initialCounterBlock.ToHex()}"); } var keyStreamBlock = ecb.ProcessPayload ( new ModeBlockCipherParameters ( BlockCipherDirections.Encrypt, key, block ) ); var beginOfBlock = block.MSBSubstring(0, 32); var endOfBlock = block.MSBSubstring(32, 96); block = beginOfBlock.BitStringAddition(new BitString("01000000")).ConcatenateBits(endOfBlock).Substring(0, 128); var inputXor = inputBlock.GetDeepCopy().ConcatenateBits(BitString.Zeroes(keyStreamBlock.Result.BitLength - inputBlock.BitLength)); var xor = keyStreamBlock.Result.XOR(inputXor).MSBSubstring(0, inputBlock.BitLength); output = output.ConcatenateBits(xor); } return(output); }
public void ShouldDecryptCorrectly(string label, BitString iv, BitString pt, BitString key, BitString ct) { var result = _subjectCs3 .ProcessPayload(new ModeBlockCipherParameters(BlockCipherDirections.Decrypt, iv.GetDeepCopy(), key, ct)).Result; Assert.AreEqual(pt.ToHex(), result.ToHex()); }
public void ShouldEncryptDecryptToSameValue(string label, BitString iv, BitString pt, BitString key, BitString ct) { var encryptResult = _subjectCs3 .ProcessPayload(new ModeBlockCipherParameters(BlockCipherDirections.Encrypt, iv.GetDeepCopy(), key, pt)).Result; var decryptResult = _subjectCs3 .ProcessPayload(new ModeBlockCipherParameters(BlockCipherDirections.Decrypt, iv.GetDeepCopy(), key, encryptResult)).Result; Assert.AreEqual(pt.GetMostSignificantBits(pt.BitLength).ToHex(), decryptResult.GetMostSignificantBits(pt.BitLength).ToHex()); }
public MacResult Generate(BitString keyBits, BitString message, int macLength = 0) { // https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-38b.pdf //6.2 MAC Generation //Prerequisites: // block cipher CIPH with block size b; // key K; // MAC length parameter Tlen //Input: // message M of bit length Mlen. //Output: // MAC T of bit length Tlen. //Suggested Notation: // CMAC(K, M, Tlen) or, if Tlen is understood from the context, CMAC(K, M). //Steps: // 1. Apply the subkey generation process in Sec. 6.1 to K to produce K1 and K2. var subKeys = ComputeSubKey(keyBits); var K1 = subKeys.k1; var K2 = subKeys.k2; // 2. If Mlen = 0, let n = 1; else, let n = ceiling(Mlen / b). //var n = message.BitLength == 0 ? 1 : System.Math.Ceiling( // message.BitLength / (double)Engine.BlockSizeBits //); var n = message.BitLength == 0 ? 1 : message.BitLength.CeilingDivide(Engine.BlockSizeBits); // 3. Let M1, M2, ... , Mn - 1, Mn* denote the unique sequence of bit strings // such that M = M1 || M2 || ... || Mn - 1 || Mn*, // where M1, M2,..., Mn-1 are complete blocks.2 // 4. If Mn* is a complete block, let Mn = K1 XOR Mn*; //var numOfBlocks = (int)System.Math.Ceiling(message.BitLength / (double)_engine.BlockSizeBits); var numOfBlocks = message.BitLength.CeilingDivide(Engine.BlockSizeBits); var s1 = message.BitLength > Engine.BlockSizeBits ? message.MSBSubstring(0, (numOfBlocks - 1) * Engine.BlockSizeBits) : new BitString(0); var lastBlock = message.BitLength != 0 ? message.MSBSubstring(s1.BitLength, message.BitLength - s1.BitLength) : new BitString(0); if (message.BitLength % Engine.BlockSizeBits == 0 && message.BitLength != 0) { lastBlock = lastBlock.XOR(K1); } // else, let Mn = K2 XOR (Mn* || 10^j), where j = nb - Mlen - 1. else { var padding = new BitString(Engine.BlockSizeBits - lastBlock.BitLength); padding.Set(padding.BitLength - 1, true); lastBlock = K2.XOR(lastBlock.ConcatenateBits(padding)); } message = s1.ConcatenateBits(lastBlock).GetDeepCopy(); //if this was an empty message, it would have been padded with another block if (message.BitLength % Engine.BlockSizeBits != 0) { throw new Exception("Message isn't composed of same sized blocks."); } numOfBlocks = message.BitLength / Engine.BlockSizeBits; BitString prevC = new BitString(Engine.BlockSizeBits); BitString currC = new BitString(Engine.BlockSizeBits); for (var i = 0; i < numOfBlocks; i++) { var block = message.MSBSubstring(i * Engine.BlockSizeBits, Engine.BlockSizeBits); var param2 = new ModeBlockCipherParameters( BlockCipherDirections.Encrypt, keyBits, prevC.XOR(block) ); currC = AlgoMode.ProcessPayload(param2).Result; prevC = currC.GetDeepCopy(); } // 5. Let C0 = 0^b. // 6. For i = 1 to n, let Ci = CIPHK(Ci - 1 XOR Mi). // 7. Let T = MSBTlen(Cn). // 8. Return T. BitString mac; if (macLength != 0) { mac = currC.GetMostSignificantBits(macLength); } else { mac = currC.GetDeepCopy(); } return(new MacResult(mac)); }
public EdSignature(BitString sig) { Sig = sig.GetDeepCopy(); }
/* * INPUT: The initial Msg is the length of the digest size * * MCT(Msg, MaxOutLen, MinOutLen, OutLenIncrement, MaxBlockSize, MinBlockSize) * { * Range = (MaxOutLen – MinOutLen + 1); * OutputLen = MaxOutLen; * BlockRange = (MaxBlockSize – MinBlockSize + 1); * BlockSize = MinBlockSize; * Customization = ""; * * Output[0] = Msg; * for (j = 0; j < 100; j++) * { * for (i = 1; i < 1001; i++) * { * InnerMsg = Left(Output[i-1] || ZeroBits(128), 128); * Output[i] = ParallelHash(InnerMsg, OutputLen, BlockSize, FunctionName, Customization); * Rightmost_Output_bits = Right(Output[i], 16); * OutputLen = MinOutLen + (floor((Rightmost_Output_bits % Range) / OutLenIncrement) * OutLenIncrement); * BlockSize = MinBlockSize + Right(Rightmost_Output_bits, 8) % BlockRange; * Customization = BitsToString(InnerMsg || Rightmost_Output_bits); * } * * OutputJ[j] = Output[1000]; * } * * return OutputJ; * } */ #endregion MonteCarloAlgorithm Pseudocode public MctResult <AlgoArrayResponseWithCustomization> MCTHash(HashFunction function, BitString message, MathDomain outputLength, MathDomain blockSizeDomain, bool hexCustomization, bool isSample) { _hexCustomization = hexCustomization; if (isSample) { NUM_OF_RESPONSES = 3; } var responses = new List <AlgoArrayResponseWithCustomization>(); var i = 0; var j = 0; var min = outputLength.GetDomainMinMax().Minimum; var max = outputLength.GetDomainMinMax().Maximum; var increment = outputLength.GetDomainMinMax().Increment; var minBlockSize = blockSizeDomain.GetDomainMinMax().Minimum; var maxBlockSize = blockSizeDomain.GetDomainMinMax().Maximum; var outputLen = max; var blockSize = minBlockSize; var blockSizeRange = (maxBlockSize - minBlockSize) + 1; var customization = ""; var range = (max - min) + 1; var innerMessage = message.GetDeepCopy(); try { for (i = 0; i < NUM_OF_RESPONSES; i++) { var innerDigest = new BitString(0); var iterationResponse = new AlgoArrayResponseWithCustomization() { }; iterationResponse.Message = innerMessage; iterationResponse.Customization = customization; iterationResponse.BlockSize = blockSize; for (j = 0; j < 1000; j++) { // Might not have 128 bits to pull from so we pad with 0 innerMessage = BitString.ConcatenateBits(innerMessage, BitString.Zeroes(128)) .GetMostSignificantBits(128); function.DigestLength = outputLen; var innerResult = _iParallelHash.HashMessage(function, innerMessage, blockSize, customization); innerDigest = innerResult.Digest.GetDeepCopy(); // Will always have 16 bits to pull from var rightmostBitString = innerDigest.GetLeastSignificantBits(16); var rightmostBits = rightmostBitString.Bits; outputLen = min + (int)System.Math.Floor((double)(rightmostBits.ToInt() % range) / increment) * increment; blockSize = minBlockSize + rightmostBitString.GetLeastSignificantBits(8).Bits.ToInt() % blockSizeRange; customization = GetStringFromBytes(BitString.ConcatenateBits(innerMessage, rightmostBitString).ToBytes()); innerMessage = innerDigest.GetDeepCopy(); } iterationResponse.Digest = innerDigest.GetDeepCopy(); responses.Add(iterationResponse); } } catch (Exception ex) { ThisLogger.Debug($"i count {i}, j count {j}"); ThisLogger.Error(ex); return(new MctResult <AlgoArrayResponseWithCustomization>($"{ex.Message}; {outputLen}")); } return(new MctResult <AlgoArrayResponseWithCustomization>(responses)); }
/* * INPUT: The initial Msg of 128 bits long * * Initial Outputlen = (floor(maxoutlen/8) )*8 * //makes maxoutlen a multiple of 8 and remains within the range specified. * * { * Output0 = Msg; * for (j=0; j<100; j++) { * for (i=1; i<1001; i++) { * M[i] = 128 leftmost bits of Output[i-1]; * Output[i] = SHAKE(M[i],Outputlen); * If (i == 1000){ * Outputlen[j] = Outputlen; * } * Rightmost_Output_bits = rightmost 16 bits of Output[i]; * Range = (maxoutbytes – minoutbytes + 1); * Outputlen = minoutbytes + (Rightmost_Output_bits mod Range); * } * Output[j] = Output[1000]; * OUTPUT: Outputlen[j], Output[j] * } * } */ #endregion MonteCarloAlgorithm Pseudocode public MctResult <AlgoArrayResponse> MctHash(BitString message, MathDomain domain, bool isSample = false) { if (isSample) { NUM_OF_RESPONSES = 3; } var responses = new List <AlgoArrayResponse>(); var i = 0; var j = 0; var min = domain.GetDomainMinMax().Minimum; var max = domain.GetDomainMinMax().Maximum; var minBytes = min / 8; var maxBytes = max / 8; var outputLen = (int)System.Math.Floor((double)max / 8) * 8; var range = (max - min) + 8; //var range = (max - min) + min; var innerMessage = message.GetDeepCopy(); // Might not have 128 bits to pull from so we pad with 0 innerMessage = BitString.ConcatenateBits(innerMessage, BitString.Zeroes(128)); innerMessage = BitString.MSBSubstring(innerMessage, 0, 128); try { for (i = 0; i < NUM_OF_RESPONSES; i++) { var innerDigest = new BitString(0); var iterationResponse = new AlgoArrayResponse() { }; iterationResponse.Message = innerMessage; for (j = 0; j < 1000; j++) { var innerResult = _sha.HashMessage(innerMessage, outputLen); innerDigest = innerResult.Digest.GetDeepCopy(); // Will always have 16 bits to pull from var rightmostBits = BitString.Substring(innerDigest, 0, 16).Bits; outputLen = min + (8 * GetIntFromBits(rightmostBits)) % range; innerMessage = innerDigest.GetDeepCopy(); // Might not have 128 bits to pull from so we pad with 0 innerMessage = BitString.ConcatenateBits(innerMessage, BitString.Zeroes(128)); innerMessage = BitString.MSBSubstring(innerMessage, 0, 128); } iterationResponse.Digest = innerDigest.GetDeepCopy(); responses.Add(iterationResponse); } } catch (Exception ex) { ThisLogger.Debug($"i count {i}, j count {j}"); ThisLogger.Error(ex); return(new MctResult <AlgoArrayResponse>($"{ex.Message}; {outputLen}")); } return(new MctResult <AlgoArrayResponse>(responses)); }
public void EncryptDecryptToSameResultTestsCs3(string label, BitString key, BitString iv, BitString pt, BitString ct, BitString nextIv) { var encryptResult = _subjectCs3.ProcessPayload(new ModeBlockCipherParameters(BlockCipherDirections.Encrypt, iv.GetDeepCopy(), key, pt)); var decryptResult = _subjectCs3.ProcessPayload(new ModeBlockCipherParameters(BlockCipherDirections.Decrypt, iv, key, encryptResult.Result)); Assert.AreEqual(pt.ToHex(), decryptResult.Result.ToHex()); }