summaryrefslogtreecommitdiff
path: root/keccak.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2016-09-08 20:24:25 -0400
committerJeffrey Walton <noloader@gmail.com>2016-09-08 20:24:25 -0400
commit7f958575eaf267c8011e25dfbe6350b818524ff4 (patch)
treeaa9577e74e276b5ca88fb71d6cc09be1de2ea465 /keccak.cpp
parent42085eea4194c10be60caab7ca3626ecb9716b19 (diff)
downloadcryptopp-git-7f958575eaf267c8011e25dfbe6350b818524ff4.tar.gz
Squashed commit of the following:
commit 47c75c6e9397e240919207e50e5a611d3e2a2428 Merge: d7685c2 42085ee Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 20:20:39 2016 -0400 Attempting to fix binary file merge conflict commit d7685c2d946beecc419ddb6901c24e972c7cf3ee Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 16:39:23 2016 -0400 Add vsClean.cmd to vs2010.zip commit 4b96fdf1c551260da60eb021f324bcc3fcfec626 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 16:15:38 2016 -0400 Add Keccak to vs2010.zip commit 3962db73b7113ee805b46a5bb4da64e204fe6bb0 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 15:40:35 2016 -0400 Fold hmqv.cpp and fhmqv.cpp into mqv.cpp. There's no need for three empty source files commit 44401448cbb6c8125b0f1ab4419c5b174408ffd7 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 15:39:23 2016 -0400 Fold hmqv.cpp and fhmqv.cpp into mqv.cpp. There's no need for three empty source files commit 847bfccb8d5c388e67745dc8c69768fa503c5135 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 14:48:02 2016 -0400 Whitespace cleanup commit 46a37be6fef361704dcf852bc9a099ce0a1da4c8 Merge: aefb8f8 3697867 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 14:43:01 2016 -0400 Merge 'master' into 'keccak' commit aefb8f8ff2b81b967089c53b457a92fc6f7544d6 Merge: 51a828b 3c91d93 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 12:39:51 2016 -0400 Merge 'master' into 'keccak' commit 51a828b88e37a4d18abb00300cd5522bd0e110c5 Merge: 4152870 e7c7722 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 10:41:36 2016 -0400 Merge 'master' into 'keccak' commit 415287041e69ddadf5ca1f6fc794b87e145fc2db Merge: 357a0c5 83ac849 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 10:34:45 2016 -0400 Merge 'master' into 'keccak' commit 357a0c510f75e4e58078b500dd469462e90f7650 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 10:13:32 2016 -0400 Removed deprecated warning from SHA3 classes commit 5cf9ec10d53b895b5a583e265e4e1298ed402195 Merge: 10ce0ed c2d60cc Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 09:43:15 2016 -0400 Merge 'master' into 'keccak' commit 10ce0ed4c5b8a1ea230062fd2dfdec0d87ec5b42 Author: Jeffrey Walton <noloader@gmail.com> Date: Thu Sep 8 09:37:40 2016 -0400 Add Keccak implementation based on early SHA3. Change SHA3 to NIST FIPS 202 conforming implementation
Diffstat (limited to 'keccak.cpp')
-rw-r--r--keccak.cpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/keccak.cpp b/keccak.cpp
new file mode 100644
index 00000000..452df6d6
--- /dev/null
+++ b/keccak.cpp
@@ -0,0 +1,291 @@
+// keccak.cpp - modified by Wei Dai from Ronny Van Keer's public domain sha3-simple.c
+// all modifications here are placed in the public domain by Wei Dai
+
+/*
+The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
+Michael Peeters and Gilles Van Assche. For more information, feedback or
+questions, please refer to our website: http://keccak.noekeon.org/
+
+Implementation by Ronny Van Keer,
+hereby denoted as "the implementer".
+
+To the extent possible under law, the implementer has waived all copyright
+and related or neighboring rights to the source code in this file.
+http://creativecommons.org/publicdomain/zero/1.0/
+*/
+
+#include "pch.h"
+#include "keccak.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+static const word64 KeccakF_RoundConstants[24] =
+{
+ W64LIT(0x0000000000000001), W64LIT(0x0000000000008082), W64LIT(0x800000000000808a),
+ W64LIT(0x8000000080008000), W64LIT(0x000000000000808b), W64LIT(0x0000000080000001),
+ W64LIT(0x8000000080008081), W64LIT(0x8000000000008009), W64LIT(0x000000000000008a),
+ W64LIT(0x0000000000000088), W64LIT(0x0000000080008009), W64LIT(0x000000008000000a),
+ W64LIT(0x000000008000808b), W64LIT(0x800000000000008b), W64LIT(0x8000000000008089),
+ W64LIT(0x8000000000008003), W64LIT(0x8000000000008002), W64LIT(0x8000000000000080),
+ W64LIT(0x000000000000800a), W64LIT(0x800000008000000a), W64LIT(0x8000000080008081),
+ W64LIT(0x8000000000008080), W64LIT(0x0000000080000001), W64LIT(0x8000000080008008)
+};
+
+static void KeccakF1600(word64 *state)
+{
+ {
+ word64 Aba, Abe, Abi, Abo, Abu;
+ word64 Aga, Age, Agi, Ago, Agu;
+ word64 Aka, Ake, Aki, Ako, Aku;
+ word64 Ama, Ame, Ami, Amo, Amu;
+ word64 Asa, Ase, Asi, Aso, Asu;
+ word64 BCa, BCe, BCi, BCo, BCu;
+ word64 Da, De, Di, Do, Du;
+ word64 Eba, Ebe, Ebi, Ebo, Ebu;
+ word64 Ega, Ege, Egi, Ego, Egu;
+ word64 Eka, Eke, Eki, Eko, Eku;
+ word64 Ema, Eme, Emi, Emo, Emu;
+ word64 Esa, Ese, Esi, Eso, Esu;
+
+ //copyFromState(A, state)
+ typedef BlockGetAndPut<word64, LittleEndian, true, true> Block;
+ Block::Get(state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu);
+
+ for( unsigned int round = 0; round < 24; round += 2 )
+ {
+ // prepareTheta
+ BCa = Aba^Aga^Aka^Ama^Asa;
+ BCe = Abe^Age^Ake^Ame^Ase;
+ BCi = Abi^Agi^Aki^Ami^Asi;
+ BCo = Abo^Ago^Ako^Amo^Aso;
+ BCu = Abu^Agu^Aku^Amu^Asu;
+
+ //thetaRhoPiChiIotaPrepareTheta(round , A, E)
+ Da = BCu^rotlFixed(BCe, 1);
+ De = BCa^rotlFixed(BCi, 1);
+ Di = BCe^rotlFixed(BCo, 1);
+ Do = BCi^rotlFixed(BCu, 1);
+ Du = BCo^rotlFixed(BCa, 1);
+
+ Aba ^= Da;
+ BCa = Aba;
+ Age ^= De;
+ BCe = rotlFixed(Age, 44);
+ Aki ^= Di;
+ BCi = rotlFixed(Aki, 43);
+ Amo ^= Do;
+ BCo = rotlFixed(Amo, 21);
+ Asu ^= Du;
+ BCu = rotlFixed(Asu, 14);
+ Eba = BCa ^((~BCe)& BCi );
+ Eba ^= (word64)KeccakF_RoundConstants[round];
+ Ebe = BCe ^((~BCi)& BCo );
+ Ebi = BCi ^((~BCo)& BCu );
+ Ebo = BCo ^((~BCu)& BCa );
+ Ebu = BCu ^((~BCa)& BCe );
+
+ Abo ^= Do;
+ BCa = rotlFixed(Abo, 28);
+ Agu ^= Du;
+ BCe = rotlFixed(Agu, 20);
+ Aka ^= Da;
+ BCi = rotlFixed(Aka, 3);
+ Ame ^= De;
+ BCo = rotlFixed(Ame, 45);
+ Asi ^= Di;
+ BCu = rotlFixed(Asi, 61);
+ Ega = BCa ^((~BCe)& BCi );
+ Ege = BCe ^((~BCi)& BCo );
+ Egi = BCi ^((~BCo)& BCu );
+ Ego = BCo ^((~BCu)& BCa );
+ Egu = BCu ^((~BCa)& BCe );
+
+ Abe ^= De;
+ BCa = rotlFixed(Abe, 1);
+ Agi ^= Di;
+ BCe = rotlFixed(Agi, 6);
+ Ako ^= Do;
+ BCi = rotlFixed(Ako, 25);
+ Amu ^= Du;
+ BCo = rotlFixed(Amu, 8);
+ Asa ^= Da;
+ BCu = rotlFixed(Asa, 18);
+ Eka = BCa ^((~BCe)& BCi );
+ Eke = BCe ^((~BCi)& BCo );
+ Eki = BCi ^((~BCo)& BCu );
+ Eko = BCo ^((~BCu)& BCa );
+ Eku = BCu ^((~BCa)& BCe );
+
+ Abu ^= Du;
+ BCa = rotlFixed(Abu, 27);
+ Aga ^= Da;
+ BCe = rotlFixed(Aga, 36);
+ Ake ^= De;
+ BCi = rotlFixed(Ake, 10);
+ Ami ^= Di;
+ BCo = rotlFixed(Ami, 15);
+ Aso ^= Do;
+ BCu = rotlFixed(Aso, 56);
+ Ema = BCa ^((~BCe)& BCi );
+ Eme = BCe ^((~BCi)& BCo );
+ Emi = BCi ^((~BCo)& BCu );
+ Emo = BCo ^((~BCu)& BCa );
+ Emu = BCu ^((~BCa)& BCe );
+
+ Abi ^= Di;
+ BCa = rotlFixed(Abi, 62);
+ Ago ^= Do;
+ BCe = rotlFixed(Ago, 55);
+ Aku ^= Du;
+ BCi = rotlFixed(Aku, 39);
+ Ama ^= Da;
+ BCo = rotlFixed(Ama, 41);
+ Ase ^= De;
+ BCu = rotlFixed(Ase, 2);
+ Esa = BCa ^((~BCe)& BCi );
+ Ese = BCe ^((~BCi)& BCo );
+ Esi = BCi ^((~BCo)& BCu );
+ Eso = BCo ^((~BCu)& BCa );
+ Esu = BCu ^((~BCa)& BCe );
+
+ // prepareTheta
+ BCa = Eba^Ega^Eka^Ema^Esa;
+ BCe = Ebe^Ege^Eke^Eme^Ese;
+ BCi = Ebi^Egi^Eki^Emi^Esi;
+ BCo = Ebo^Ego^Eko^Emo^Eso;
+ BCu = Ebu^Egu^Eku^Emu^Esu;
+
+ //thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
+ Da = BCu^rotlFixed(BCe, 1);
+ De = BCa^rotlFixed(BCi, 1);
+ Di = BCe^rotlFixed(BCo, 1);
+ Do = BCi^rotlFixed(BCu, 1);
+ Du = BCo^rotlFixed(BCa, 1);
+
+ Eba ^= Da;
+ BCa = Eba;
+ Ege ^= De;
+ BCe = rotlFixed(Ege, 44);
+ Eki ^= Di;
+ BCi = rotlFixed(Eki, 43);
+ Emo ^= Do;
+ BCo = rotlFixed(Emo, 21);
+ Esu ^= Du;
+ BCu = rotlFixed(Esu, 14);
+ Aba = BCa ^((~BCe)& BCi );
+ Aba ^= (word64)KeccakF_RoundConstants[round+1];
+ Abe = BCe ^((~BCi)& BCo );
+ Abi = BCi ^((~BCo)& BCu );
+ Abo = BCo ^((~BCu)& BCa );
+ Abu = BCu ^((~BCa)& BCe );
+
+ Ebo ^= Do;
+ BCa = rotlFixed(Ebo, 28);
+ Egu ^= Du;
+ BCe = rotlFixed(Egu, 20);
+ Eka ^= Da;
+ BCi = rotlFixed(Eka, 3);
+ Eme ^= De;
+ BCo = rotlFixed(Eme, 45);
+ Esi ^= Di;
+ BCu = rotlFixed(Esi, 61);
+ Aga = BCa ^((~BCe)& BCi );
+ Age = BCe ^((~BCi)& BCo );
+ Agi = BCi ^((~BCo)& BCu );
+ Ago = BCo ^((~BCu)& BCa );
+ Agu = BCu ^((~BCa)& BCe );
+
+ Ebe ^= De;
+ BCa = rotlFixed(Ebe, 1);
+ Egi ^= Di;
+ BCe = rotlFixed(Egi, 6);
+ Eko ^= Do;
+ BCi = rotlFixed(Eko, 25);
+ Emu ^= Du;
+ BCo = rotlFixed(Emu, 8);
+ Esa ^= Da;
+ BCu = rotlFixed(Esa, 18);
+ Aka = BCa ^((~BCe)& BCi );
+ Ake = BCe ^((~BCi)& BCo );
+ Aki = BCi ^((~BCo)& BCu );
+ Ako = BCo ^((~BCu)& BCa );
+ Aku = BCu ^((~BCa)& BCe );
+
+ Ebu ^= Du;
+ BCa = rotlFixed(Ebu, 27);
+ Ega ^= Da;
+ BCe = rotlFixed(Ega, 36);
+ Eke ^= De;
+ BCi = rotlFixed(Eke, 10);
+ Emi ^= Di;
+ BCo = rotlFixed(Emi, 15);
+ Eso ^= Do;
+ BCu = rotlFixed(Eso, 56);
+ Ama = BCa ^((~BCe)& BCi );
+ Ame = BCe ^((~BCi)& BCo );
+ Ami = BCi ^((~BCo)& BCu );
+ Amo = BCo ^((~BCu)& BCa );
+ Amu = BCu ^((~BCa)& BCe );
+
+ Ebi ^= Di;
+ BCa = rotlFixed(Ebi, 62);
+ Ego ^= Do;
+ BCe = rotlFixed(Ego, 55);
+ Eku ^= Du;
+ BCi = rotlFixed(Eku, 39);
+ Ema ^= Da;
+ BCo = rotlFixed(Ema, 41);
+ Ese ^= De;
+ BCu = rotlFixed(Ese, 2);
+ Asa = BCa ^((~BCe)& BCi );
+ Ase = BCe ^((~BCi)& BCo );
+ Asi = BCi ^((~BCo)& BCu );
+ Aso = BCo ^((~BCu)& BCa );
+ Asu = BCu ^((~BCa)& BCe );
+ }
+
+ //copyToState(state, A)
+ Block::Put(NULL, state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu);
+ }
+}
+
+void Keccak::Update(const byte *input, size_t length)
+{
+ assert((input && length) || !(input || length));
+ if (!length)
+ return;
+
+ size_t spaceLeft;
+ while (length >= (spaceLeft = r() - m_counter))
+ {
+ if (spaceLeft)
+ xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft);
+ KeccakF1600(m_state);
+ input += spaceLeft;
+ length -= spaceLeft;
+ m_counter = 0;
+ }
+
+ if (length)
+ xorbuf(m_state.BytePtr() + m_counter, input, length);
+ m_counter += (unsigned int)length;
+}
+
+void Keccak::Restart()
+{
+ memset(m_state, 0, m_state.SizeInBytes());
+ m_counter = 0;
+}
+
+void Keccak::TruncatedFinal(byte *hash, size_t size)
+{
+ ThrowIfInvalidTruncatedSize(size);
+
+ m_state.BytePtr()[m_counter] ^= 1;
+ m_state.BytePtr()[r()-1] ^= 0x80;
+ KeccakF1600(m_state);
+ memcpy(hash, m_state, size);
+ Restart();
+}
+
+NAMESPACE_END