public byte[][] SplitBlocks(byte[] paddedInputBits) { Debug.Assert(paddedInputBits.Length % rate == 0); int numberOfBlocks = paddedInputBits.Length / rate; byte[][] inputBlocks = null; byte[] block; /* split message into blocks of size `rate` */ List <byte[]> inputBlockList = new List <byte[]>(numberOfBlocks); for (int i = 0; i < numberOfBlocks; i++) { block = KeccakHashFunction.SubArray(paddedInputBits, i * rate, rate); inputBlockList.Add(block); } inputBlocks = inputBlockList.ToArray(); return(inputBlocks); }
public void Absorb(byte[] input) { byte[] paddedInputBits; byte[][] inputBlocks; /* pad message */ paddedInputBits = Pad(input); /* split padded message into blocks of equal length */ inputBlocks = SplitBlocks(paddedInputBits); #region presentation execution phase information if (pres.IsVisible && !pres.skipPresentation) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelCurrentPhase.Content = Resources.PresExecution; pres.labelCurrentStep.Content = Resources.PresOverview; pres.labelExecutionInfoStateSize.Content = string.Format(Resources.PresExecutionInfoStateSize, (rate + capacity)); pres.labelExecutionInfoCapacitySize.Content = string.Format(Resources.PresExecutionInfoCapacitySize, capacity); pres.labelExecutionInfoRateSize.Content = string.Format(Resources.PresExecutionInfoBitRateSize, rate); pres.labelExecutionMessageLength.Content = string.Format(Resources.PresExecutionMessageLength, input.Length, input.Length / 8); pres.labelExecutionPaddedMessageLength.Content = string.Format(Resources.PresExecutionPaddedMessageLength, paddedInputBits.Length, paddedInputBits.Length / 8); pres.labelExecutionNumberOfBlocks.Content = string.Format(Resources.PresExecutionNumberOfBlocks, inputBlocks.Length); pres.executionInfoCanvas.Visibility = Visibility.Visible; }, null); AutoResetEvent buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.executionInfoCanvas.Visibility = Visibility.Hidden; }, null); } #endregion #if _DEBUG_ Console.WriteLine("#Sponge: the input of length {0} bits is padded to {1} bits\n" + "#Sponge: the padded input is splitted into {2} block(s) of size {3} bit\n", input.Length, paddedInputBits.Length, inputBlocks.Length, inputBlocks[0].Length); Console.WriteLine("#Sponge: begin absorbing phase"); #endif int blocksCounter = 1; progressionStepCounter = 0; if (pres.IsVisible && !pres.skipPresentation) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.spInfo.Visibility = Visibility.Visible; }, null); } /* absorb and permute */ foreach (byte[] block in inputBlocks) { #if _DEBUG_ Console.WriteLine("#Sponge: XORing input block #{0} on state\n", blocksCounter); #endif #region presentation absorbing phase if (pres.IsVisible && !pres.skipPresentation) { string stateStr = KeccakHashFunction.GetByteArrayAsString(state, laneSize); string blockStr = KeccakHashFunction.GetByteArrayAsString(block, laneSize); pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelRound.Content = ""; pres.labelBlock.Content = string.Format("Block {0}/{1}", blocksCounter, inputBlocks.Length); pres.textBlockExplanation.Text = string.Format(Resources.PresAbsorbingPhaseExplanation, blocksCounter); pres.imgBlankPage.Visibility = Visibility.Visible; pres.labelCurrentPhase.Content = Resources.PresAbsorbingPhase; pres.labelCurrentStep.Content = ""; pres.labelAbsorbGridBlockCounter.Content = string.Format("Block #{0}/{1}", blocksCounter, inputBlocks.Length); pres.labelNewState.Visibility = Visibility.Visible; pres.labelOldState.Content = Resources.PresOldState; pres.textBlockStateBeforeAbsorb.Text = stateStr; pres.textBlockBlockToAbsorb.Text = blockStr; pres.absorbGrid.Visibility = Visibility.Visible; pres.buttonSkipPermutation.IsEnabled = true; pres.buttonSkip.IsEnabled = false; pres.buttonAutostep.IsEnabled = false; pres.autostepSpeedSlider.IsEnabled = false; }, null); //AutoResetEvent buttonNextClickedEvent = pres.buttonNextClickedEvent; //buttonNextClickedEvent.WaitOne(); } #endregion XorBlockOnState(block); plugin.ProgressChanged((double)progressionStepCounter + (1.0 / 6.0), (double)progressionSteps); #region presentation absorbing phase if (pres.IsVisible && !pres.skipPresentation) { string stateStr = KeccakHashFunction.GetByteArrayAsString(state, laneSize); pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.textBlockStateAfterAbsorb.Text = stateStr; }, null); AutoResetEvent buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); } if (pres.IsVisible || pres.skipPresentation) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.textBlockExplanation.Text = ""; pres.labelAbsorbGridBlockCounter.Content = ""; pres.absorbGrid.Visibility = Visibility.Hidden; pres.imgBlankPage.Visibility = Visibility.Hidden; pres.labelNewState.Visibility = Visibility.Hidden; pres.labelOldState.Content = ""; pres.textBlockStateBeforeAbsorb.Text = ""; pres.textBlockBlockToAbsorb.Text = ""; pres.textBlockStateAfterAbsorb.Text = ""; pres.labelCurrentPhase.Content = ""; pres.labelCurrentStep.Content = ""; }, null); } #endregion keccak_f.Permute(ref state, progressionStepCounter, progressionSteps); blocksCounter++; progressionStepCounter++; pres.skipPermutation = false; } #if _DEBUG_ Console.WriteLine("\n#Sponge: absorbing done!"); blocksCounter++; #endif }
public byte[] Squeeze(int outputLength) { byte[] output = new byte[outputLength]; #if _DEBUG_ Console.WriteLine("\n#Sponge: begin squeezing phase"); #endif if (outputLength <= rate) { #if _DEBUG_ Console.WriteLine("#Sponge: the output length is smaller or equal to the bit rate size ({0} <= {1})", outputLength, rate); Console.WriteLine("#Sponge: -> squeeze output from state"); #endif /* append `outputLength` bits of the state to the output */ output = KeccakHashFunction.SubArray(state, 0, outputLength); /* presentation squeezing phase*/ #region presentation squeezing phase if (pres.IsVisible && !pres.skipPresentation) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelRound.Content = ""; pres.labelBlock.Content = ""; }, null); } if (pres.IsVisible && !pres.skipPresentation) { string stateStr = KeccakHashFunction.GetByteArrayAsString(state, laneSize); string outputStr = KeccakHashFunction.GetByteArrayAsString(output, laneSize); pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.textBlockExplanation.Text = string.Format(Resources.PresSqueezingPhaseExplanation, outputLength); // If the hash value is larger than this part the state is repeatedly permuted by Keccak-f such that sufficient output can be extracted.", outputLength); pres.imgBlankPage.Visibility = Visibility.Visible; pres.labelCurrentPhase.Content = Resources.PresSqueezingPhase; pres.labelOutput.Visibility = Visibility.Visible; pres.textBlockStateBeforeAbsorb.Text = stateStr; pres.absorbGrid.Visibility = Visibility.Visible; pres.labelOldState.Content = Resources.PresState; pres.textBlockStateAfterAbsorb.Text = outputStr; }, null); } #endregion } else { int remainingOutput = outputLength, i = 0; #if _DEBUG_ int squeezingRounds = remainingOutput % rate == 0 ? (int)(remainingOutput / rate - 1) : (remainingOutput / rate); Console.WriteLine("#Sponge: the output length is larger than the bit rate ({0} > {1})", outputLength, rate); Console.WriteLine("#Sponge: -> squeeze output from state iteratively ({0} iteration(s) required)\n", squeezingRounds); #endif /* append size of `rate` bits of the state to the output */ while (remainingOutput > rate) { Array.Copy(state, 0, output, i++ *rate, rate); #if _DEBUG_ Console.WriteLine("#Sponge: squeeze iteration #{0}\n", i); #endif remainingOutput -= rate; plugin.ProgressChanged((double)progressionStepCounter + (1.0 / 6.0), (double)progressionSteps); keccak_f.Permute(ref state, progressionStepCounter, progressionSteps); progressionStepCounter++; } if (remainingOutput > 0) { /* append remaining bits of the state to the output to fit the output length */ Array.Copy(state, 0, output, i * rate, remainingOutput); } } #if _DEBUG_ Console.WriteLine("#Sponge: squeezing done!\n"); #endif if (pres.IsVisible) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.spInfo.Visibility = Visibility.Hidden; //pres.labelCurrentStep.Content = ""; //pres.labelCurrentPhase.Content = ""; }, null); } return(output); }
public void Execute() { /* do not execute if checks in PreExecution() failed */ if (!execute) { return; } ProgressChanged(0, 1); byte[] input, output; int outputLength, rate, capacity; /* setup output stream writer */ CStreamWriter OutputStreamwriter = new CStreamWriter(); OutputStream = OutputStreamwriter; OnPropertyChanged("OutputStream"); #if _DEBUG_ /* setup debug stream writer */ TextWriter consoleOut = Console.Out; // save the standard output CStreamWriter debugStream = new CStreamWriter(); StreamWriter debugStreamWriter = new StreamWriter(debugStream); debugStreamWriter.AutoFlush = true; // flush stream every time WriteLine is called Console.SetOut(debugStreamWriter); DebugStream = debugStream; OnPropertyChanged("DebugStream"); #endif #region get input /* read input */ using (CStreamReader reader = InputStream.CreateReader()) { int bytesRead; byte[] buffer = new byte[128]; // buffer of length 128 byte MemoryStream stream = new MemoryStream(); BinaryWriter bw = new BinaryWriter(stream); while ((bytesRead = reader.Read(buffer)) > 0) { bw.Write(buffer, 0, bytesRead); } bw.Close(); input = stream.ToArray(); OnPropertyChanged("OutputStream"); } #endregion outputLength = settings.OutputLength; rate = settings.Rate; capacity = settings.Capacity; /* show presentation intro */ #region presentation intro if (pres.IsVisible) { /* clean up last round */ pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.absorbGrid.Visibility = Visibility.Hidden; pres.imgBlankPage.Visibility = Visibility.Hidden; pres.labelOutput.Visibility = Visibility.Hidden; pres.textBlockStateBeforeAbsorb.Text = ""; pres.textBlockBlockToAbsorb.Text = ""; pres.textBlockStateAfterAbsorb.Text = ""; pres.labelCurrentPhase.Content = ""; pres.labelCurrentStep.Content = ""; pres.textBlockExplanation.Text = ""; pres.textBlockParametersNotSupported.Visibility = Visibility.Hidden; pres.textBlockParametersNotSupported.Text = ""; pres.textBlockStepPresentationNotAvailable.Visibility = Visibility.Hidden; pres.textBlockStepPresentationNotAvailable.Text = ""; pres.buttonNext.IsEnabled = true; pres.buttonSkip.IsEnabled = false; pres.buttonAutostep.IsEnabled = false; pres.buttonSkipPermutation.IsEnabled = false; pres.autostepSpeedSlider.IsEnabled = false; pres.spButtons.Visibility = Visibility.Visible; pres.buttonSkipIntro.Visibility = Visibility.Visible; pres.imgIntroFirstPage.Visibility = Visibility.Visible; }, null); AutoResetEvent buttonNextClickedEvent = pres.buttonNextClickedEvent; #region check if selected parameters are supported if (outputLength > rate) { pres.skipPresentation = true; pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.imgIntroFirstPage.Visibility = Visibility.Hidden; pres.textBlockParametersNotSupported.Text = Resources.PresOutputLengthError; pres.textBlockParametersNotSupported.Visibility = Visibility.Visible; }, null); } else if (rate + capacity < 200) { pres.skipPresentation = true; pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.imgIntroFirstPage.Visibility = Visibility.Hidden; pres.textBlockParametersNotSupported.Text = Resources.PresStateSizeError; pres.textBlockParametersNotSupported.Visibility = Visibility.Visible; }, null); } #endregion if (!pres.skipPresentation) { buttonNextClickedEvent.WaitOne(); } if (!pres.skipPresentation && !pres.skipIntro) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.imgIntroFirstPage.Visibility = Visibility.Hidden; pres.labelIntroIntroduction.Visibility = Visibility.Visible; }, null); buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); } if (!pres.skipPresentation && !pres.skipIntro) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelCurrentPhase.Content = Resources.PresIntroduction; pres.labelCurrentStep.Content = Resources.PresInitialization; pres.textBlockIntroduction.Text = string.Format(Resources.PresInitializationText, (rate + capacity), capacity, rate); pres.labelIntroIntroduction.Visibility = Visibility.Hidden; pres.imgIntroSpongeInit.Visibility = Visibility.Visible; }, null); buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); } if (!pres.skipPresentation && !pres.skipIntro) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelCurrentStep.Content = Resources.PresAbsorbingPhase; pres.textBlockIntroduction.Text = string.Format(Resources.PresAbsorbingPhaseText, rate); pres.imgIntroSpongeInit.Visibility = Visibility.Hidden; pres.imgIntroSpongeAbsorb.Visibility = Visibility.Visible; }, null); buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); } if (!pres.skipPresentation && !pres.skipIntro) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelCurrentStep.Content = Resources.PresSqueezingPhase; pres.textBlockIntroduction.Text = Resources.PresSqueezingPhaseText; pres.imgIntroSpongeAbsorb.Visibility = Visibility.Hidden; pres.imgIntroSpongeSqueeze.Visibility = Visibility.Visible; }, null); buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); } if (!pres.skipPresentation && !pres.skipIntro) { /* calculate l parameter */ int l = (int)Math.Log((double)((rate + capacity) / 25), 2); pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelCurrentStep.Content = Resources.PresKeccakFPhase; pres.textBlockIntroduction.Text = string.Format(Resources.PresKeccakFPhaseText, l, (12 + 2 * l)); pres.labelIntroIterationAmount.Content = string.Format(Resources.PresKeccakFIterations, (12 + 2 * l)); pres.imgIntroSpongeSqueeze.Visibility = Visibility.Hidden; pres.imgIntroSpongeKeccakf2.Visibility = Visibility.Visible; }, null); buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); } if (!pres.skipPresentation && !pres.skipIntro) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelIntroIterationAmount.Content = ""; pres.imgIntroSpongeKeccakf2.Visibility = Visibility.Hidden; pres.imgIntroStateMapping.Visibility = Visibility.Visible; pres.textBlockIntroduction.Text = string.Format(Resources.PresKeccakFStateMapping, (capacity + rate), (capacity + rate) / 25); }, null); buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); } if (!pres.skipPresentation && !pres.skipIntro) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.buttonSkipIntro.Visibility = Visibility.Hidden; pres.imgIntroStateMapping.Visibility = Visibility.Hidden; pres.labelIntroExecution.Visibility = Visibility.Visible; pres.textBlockIntroduction.Text = ""; pres.labelCurrentPhase.Content = ""; pres.labelCurrentStep.Content = ""; }, null); buttonNextClickedEvent = pres.buttonNextClickedEvent; buttonNextClickedEvent.WaitOne(); } if (!pres.skipPresentation && !pres.skipIntro) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelIntroExecution.Visibility = Visibility.Hidden; }, null); } if (pres.skipPresentation || pres.skipIntro) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.labelIntroIterationAmount.Content = ""; pres.imgIntroFirstPage.Visibility = Visibility.Hidden; pres.imgIntroIntroduction.Visibility = Visibility.Hidden; pres.imgIntroSpongeInit.Visibility = Visibility.Hidden; pres.imgIntroSpongeAbsorb.Visibility = Visibility.Hidden; pres.imgIntroSpongeSqueeze.Visibility = Visibility.Hidden; pres.imgIntroSpongeKeccakf2.Visibility = Visibility.Hidden; pres.imgIntroStateMapping.Visibility = Visibility.Hidden; pres.imgIntroExecution.Visibility = Visibility.Hidden; pres.buttonSkipIntro.Visibility = Visibility.Hidden; pres.labelIntroIntroduction.Visibility = Visibility.Hidden; pres.labelIntroExecution.Visibility = Visibility.Hidden; pres.textBlockIntroduction.Text = ""; }, null); } } #endregion /* hash input */ output = KeccakHashFunction.Hash(input, outputLength, rate, capacity, ref pres, this); /* write output */ OutputStreamwriter.Write(output); OutputStreamwriter.Close(); #if _DEBUG_ /* close debug stream and reset standard output */ debugStreamWriter.Close(); Console.SetOut(consoleOut); #endif /* hide button panel */ if (pres.IsVisible) { pres.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback) delegate { pres.spButtons.Visibility = Visibility.Hidden; }, null); } ProgressChanged(1, 1); }