source: git/src-cryptopp/blake2.h

Last change on this file was e230cb0, checked in by David Stainton <dstainton415@…>, at 2016-10-12T13:27:29Z

Add cryptopp from tag CRYPTOPP_5_6_5

  • Property mode set to 100644
File size: 12.9 KB
Line 
1// blake2.h - written and placed in the public domain by Jeffrey Walton and Zooko
2//            Wilcox-O'Hearn. Copyright assigned to the Crypto++ project.
3//            Based on Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's reference BLAKE2
4//            implementation at http://github.com/BLAKE2/BLAKE2.
5
6//! \file blake2.h
7//! \brief Classes for BLAKE2b and BLAKE2s message digests and keyed message digests
8//! \details This implmentation follows Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's
9//!   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).
10//!   Static algorithm name return either "BLAKE2b" or "BLAKE2s". An object algorithm name follows
11//!   the naming described in <A HREF="http://tools.ietf.org/html/rfc7693#section-4">RFC 7693, The
12//!   BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)</A>.
13//! \details The library provides specialized SSE2, SSE4 and NEON version of the BLAKE2 compression
14//!   function. For best results under ARM NEON, specify both an architecture and cpu. For example:
15//!   <pre>CXXFLAGS="-DNDEBUG -march=armv8-a+crc -mcpu=cortex-a53 ..."</pre>
16//! \since Crypto++ 5.6.4
17
18#ifndef CRYPTOPP_BLAKE2_H
19#define CRYPTOPP_BLAKE2_H
20
21#include "cryptlib.h"
22#include "secblock.h"
23#include "seckey.h"
24
25NAMESPACE_BEGIN(CryptoPP)
26
27//! \class BLAKE2_Info
28//! \brief BLAKE2 hash information
29//! \tparam T_64bit flag indicating 64-bit
30//! \since Crypto++ 5.6.4
31template <bool T_64bit>
32struct BLAKE2_Info : public VariableKeyLength<(T_64bit ? 64 : 32),0,(T_64bit ? 64 : 32),1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE>
33{
34        typedef VariableKeyLength<(T_64bit ? 64 : 32),0,(T_64bit ? 64 : 32),1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase;
35        CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH)
36        CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH)
37        CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH)
38
39        CRYPTOPP_CONSTANT(BLOCKSIZE = (T_64bit ? 128 : 64))
40        CRYPTOPP_CONSTANT(DIGESTSIZE = (T_64bit ? 64 : 32))
41        CRYPTOPP_CONSTANT(SALTSIZE = (T_64bit ? 16 : 8))
42        CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = (T_64bit ? 16 : 8))
43
44        CRYPTOPP_CONSTEXPR static const char *StaticAlgorithmName() {return (T_64bit ? "BLAKE2b" : "BLAKE2s");}
45};
46
47//! \class BLAKE2_ParameterBlock
48//! \brief BLAKE2 parameter block
49//! \tparam T_64bit flag indicating 64-bit
50//! \details BLAKE2b uses BLAKE2_ParameterBlock<true>, while BLAKE2s
51//!   uses BLAKE2_ParameterBlock<false>.
52//! \since Crypto++ 5.6.4
53template <bool T_64bit>
54struct CRYPTOPP_NO_VTABLE BLAKE2_ParameterBlock
55{
56};
57
58//! \brief BLAKE2b parameter block specialization
59template<>
60struct CRYPTOPP_NO_VTABLE BLAKE2_ParameterBlock<true>
61{
62        CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2_Info<true>::SALTSIZE)
63        CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2_Info<true>::DIGESTSIZE)
64        CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2_Info<true>::PERSONALIZATIONSIZE)
65
66        BLAKE2_ParameterBlock()
67        {
68                memset(this, 0x00, sizeof(*this));
69                digestLength = DIGESTSIZE;
70                fanout = depth = 1;
71        }
72
73        BLAKE2_ParameterBlock(size_t digestSize)
74        {
75                CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE);
76                memset(this, 0x00, sizeof(*this));
77                digestLength = (byte)digestSize;
78                fanout = depth = 1;
79        }
80
81        BLAKE2_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength,
82                const byte* personalization, size_t personalizationLength);
83
84        byte digestLength;
85        byte keyLength, fanout, depth;
86        byte leafLength[4];
87        byte nodeOffset[8];
88        byte nodeDepth, innerLength, rfu[14];
89        byte salt[SALTSIZE];
90        byte personalization[PERSONALIZATIONSIZE];
91};
92
93//! \brief BLAKE2s parameter block specialization
94template<>
95struct CRYPTOPP_NO_VTABLE BLAKE2_ParameterBlock<false>
96{
97        CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2_Info<false>::SALTSIZE)
98        CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2_Info<false>::DIGESTSIZE)
99        CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2_Info<false>::PERSONALIZATIONSIZE)
100
101        BLAKE2_ParameterBlock()
102        {
103                memset(this, 0x00, sizeof(*this));
104                digestLength = DIGESTSIZE;
105                fanout = depth = 1;
106        }
107
108        BLAKE2_ParameterBlock(size_t digestSize)
109        {
110                CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE);
111                memset(this, 0x00, sizeof(*this));
112                digestLength = (byte)digestSize;
113                fanout = depth = 1;
114        }
115
116        BLAKE2_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength,
117                const byte* personalization, size_t personalizationLength);
118
119        byte digestLength;
120        byte keyLength, fanout, depth;
121        byte leafLength[4];
122        byte nodeOffset[6];
123        byte nodeDepth, innerLength;
124        byte salt[SALTSIZE];
125        byte personalization[PERSONALIZATIONSIZE];
126};
127
128//! \class BLAKE2_State
129//! \brief BLAKE2 state information
130//! \tparam W word type
131//! \tparam T_64bit flag indicating 64-bit
132//! \details BLAKE2b uses BLAKE2_State<word64, true>, while BLAKE2s
133//!   uses BLAKE2_State<word32, false>.
134//! \since Crypto++ 5.6.4
135template <class W, bool T_64bit>
136struct CRYPTOPP_NO_VTABLE BLAKE2_State
137{
138        CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2_Info<T_64bit>::BLOCKSIZE)
139
140        BLAKE2_State()
141        {
142                // Set all members except scratch buffer[]
143                h[0]=h[1]=h[2]=h[3]=h[4]=h[5]=h[6]=h[7] = 0;
144                t[0]=t[1]=f[0]=f[1] = 0;
145                length = 0;
146        }
147
148        // SSE2, SSE4 and NEON depend upon t[] and f[] being side-by-side
149        W h[8], t[2], f[2];
150        byte  buffer[BLOCKSIZE];
151        size_t length;
152};
153
154//! \class BLAKE2_Base
155//! \brief BLAKE2 hash implementation
156//! \tparam W word type
157//! \tparam T_64bit flag indicating 64-bit
158//! \details BLAKE2b uses BLAKE2_Base<word64, true>, while BLAKE2s
159//!   uses BLAKE2_Base<word32, false>.
160//! \since Crypto++ 5.6.4
161template <class W, bool T_64bit>
162class BLAKE2_Base : public SimpleKeyingInterfaceImpl<MessageAuthenticationCode, BLAKE2_Info<T_64bit> >
163{
164public:
165        CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2_Info<T_64bit>::DEFAULT_KEYLENGTH)
166        CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2_Info<T_64bit>::MIN_KEYLENGTH)
167        CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2_Info<T_64bit>::MAX_KEYLENGTH)
168
169        CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2_Info<T_64bit>::DIGESTSIZE)
170        CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2_Info<T_64bit>::BLOCKSIZE)
171        CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2_Info<T_64bit>::SALTSIZE)
172        CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2_Info<T_64bit>::PERSONALIZATIONSIZE)
173
174        typedef BLAKE2_State<W, T_64bit> State;
175        typedef BLAKE2_ParameterBlock<T_64bit> ParameterBlock;
176        typedef SecBlock<State, AllocatorWithCleanup<State, true> > AlignedState;
177        typedef SecBlock<ParameterBlock, AllocatorWithCleanup<ParameterBlock, true> > AlignedParameterBlock;
178
179        virtual ~BLAKE2_Base() {}
180
181        //! \brief Retrieve the static algorithm name
182        //! \returns the algorithm name (BLAKE2s or BLAKE2b)
183        CRYPTOPP_CONSTEXPR static const char *StaticAlgorithmName() {return BLAKE2_Info<T_64bit>::StaticAlgorithmName();}
184
185        //! \brief Retrieve the object's name
186        //! \returns the object's algorithm name following RFC 7693
187        //! \details Object algorithm name follows the naming described in
188        //!   <A HREF="http://tools.ietf.org/html/rfc7693#section-4">RFC 7693, The BLAKE2 Cryptographic Hash and
189        //! Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".
190        std::string AlgorithmName() const {return std::string(StaticAlgorithmName()) + "-" + IntToString(this->DigestSize()*8);}
191
192        unsigned int DigestSize() const {return m_digestSize;}
193        unsigned int OptimalDataAlignment() const {return (CRYPTOPP_BOOL_ALIGN16 ? 16 : GetAlignmentOf<W>());}
194
195        void Update(const byte *input, size_t length);
196        void Restart();
197
198        //! \brief Restart a hash with parameter block and counter
199        //! \param block paramter block
200        //! \param counter counter array
201        //! \details Parameter block is persisted across calls to Restart().
202        void Restart(const BLAKE2_ParameterBlock<T_64bit>& block, const W counter[2]);
203
204        //! \brief Set tree mode
205        //! \param mode the new tree mode
206        //! \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1].
207        //!   If <tt>treeMode=false</tt> (default), then State::f[1] is never set. If
208        //!   <tt>treeMode=true</tt>, then State::f[1] is set when State::f[0] is set.
209        //!   Tree mode is persisted across calls to Restart().
210        void SetTreeMode(bool mode) {m_treeMode=mode;}
211
212        //! \brief Get tree mode
213        //! \returns the current tree mode
214        //! \details Tree mode is persisted across calls to Restart().
215        bool GetTreeMode() const {return m_treeMode;}
216
217        void TruncatedFinal(byte *hash, size_t size);
218
219protected:
220        BLAKE2_Base();
221        BLAKE2_Base(bool treeMode, unsigned int digestSize);
222        BLAKE2_Base(const byte *key, size_t keyLength, const byte* salt, size_t saltLength,
223                const byte* personalization, size_t personalizationLength,
224                bool treeMode, unsigned int digestSize);
225
226        // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's.
227        void Compress(const byte *input);
228        inline void IncrementCounter(size_t count=BLOCKSIZE);
229
230        void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params);
231
232private:
233        AlignedState m_state;
234        AlignedParameterBlock m_block;
235        AlignedSecByteBlock m_key;
236        word32 m_digestSize;
237        bool m_treeMode;
238};
239
240//! \brief The BLAKE2b cryptographic hash function
241//! \details BLAKE2b can function as both a hash and keyed hash. If you want only the hash,
242//!   then use the BLAKE2b constructor that accepts no parameters or digest size. If you
243//!   want a keyed hash, then use the constuctor that accpts the key as a parameter.
244//!   Once a key and digest size are selected, its effectively immutable. The Restart()
245//!   method that accepts a ParameterBlock does not allow you to change it.
246//! \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's
247//!   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).
248//! \since Crypto++ 5.6.4
249class BLAKE2b : public BLAKE2_Base<word64, true>
250{
251public:
252        typedef BLAKE2_Base<word64, true> ThisBase; // Early Visual Studio workaround
253        typedef BLAKE2_ParameterBlock<true> ParameterBlock;
254        CRYPTOPP_COMPILE_ASSERT(sizeof(ParameterBlock) == 64);
255
256        //! \brief Construct a BLAKE2b hash
257        //! \param digestSize the digest size, in bytes
258        //! \param treeMode flag indicating tree mode
259        BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE) : ThisBase(treeMode, digestSize) {}
260
261        //! \brief Construct a BLAKE2b hash
262        //! \param key a byte array used to key the cipher
263        //! \param keyLength the size of the byte array
264        //! \param salt a byte array used as salt
265        //! \param saltLength the size of the byte array
266        //! \param personalization a byte array used as prsonalization string
267        //! \param personalizationLength the size of the byte array
268        //! \param treeMode flag indicating tree mode
269        //! \param digestSize the digest size, in bytes
270        BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULL, size_t saltLength = 0,
271                const byte* personalization = NULL, size_t personalizationLength = 0,
272                bool treeMode=false, unsigned int digestSize = DIGESTSIZE)
273                : ThisBase(key, keyLength, salt, saltLength, personalization, personalizationLength, treeMode, digestSize) {}
274};
275
276//! \brief The BLAKE2s cryptographic hash function
277//! \details BLAKE2s can function as both a hash and keyed hash. If you want only the hash,
278//!   then use the BLAKE2s constructor that accepts no parameters or digest size. If you
279//!   want a keyed hash, then use the constuctor that accpts the key as a parameter.
280//!   Once a key and digest size are selected, its effectively immutable. The Restart()
281//!   method that accepts a ParameterBlock does not allow you to change it.
282//! \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's
283//!   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).
284//! \since Crypto++ 5.6.4
285class BLAKE2s : public BLAKE2_Base<word32, false>
286{
287public:
288        typedef BLAKE2_Base<word32, false> ThisBase; // Early Visual Studio workaround
289        typedef BLAKE2_ParameterBlock<false> ParameterBlock;
290        CRYPTOPP_COMPILE_ASSERT(sizeof(ParameterBlock) == 32);
291
292        //! \brief Construct a BLAKE2s hash
293        //! \param digestSize the digest size, in bytes
294        //! \param treeMode flag indicating tree mode
295        BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE) : ThisBase(treeMode, digestSize) {}
296
297        //! \brief Construct a BLAKE2s hash
298        //! \param key a byte array used to key the cipher
299        //! \param keyLength the size of the byte array
300        //! \param salt a byte array used as salt
301        //! \param saltLength the size of the byte array
302        //! \param personalization a byte array used as prsonalization string
303        //! \param personalizationLength the size of the byte array
304        //! \param treeMode flag indicating tree mode
305        //! \param digestSize the digest size, in bytes
306        BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULL, size_t saltLength = 0,
307                const byte* personalization = NULL, size_t personalizationLength = 0,
308                bool treeMode=false, unsigned int digestSize = DIGESTSIZE)
309                : ThisBase(key, keyLength, salt, saltLength, personalization, personalizationLength, treeMode, digestSize) {}
310};
311
312NAMESPACE_END
313
314#endif
Note: See TracBrowser for help on using the repository browser.