Crypto++  5.6.5
Free C++ class library of cryptographic schemes
blake2.h
Go to the documentation of this file.
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 
25 NAMESPACE_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
31 template <bool T_64bit>
32 struct BLAKE2_Info : public VariableKeyLength<(T_64bit ? 64 : 32),0,(T_64bit ? 64 : 32),1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE>
33 {
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
53 template <bool T_64bit>
54 struct CRYPTOPP_NO_VTABLE BLAKE2_ParameterBlock
55 {
56 };
57 
58 //! \brief BLAKE2b parameter block specialization
59 template<>
60 struct 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 
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
94 template<>
95 struct 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 
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
135 template <class W, bool T_64bit>
136 struct 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
161 template <class W, bool T_64bit>
162 class BLAKE2_Base : public SimpleKeyingInterfaceImpl<MessageAuthenticationCode, BLAKE2_Info<T_64bit> >
163 {
164 public:
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 
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 
219 protected:
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 
232 private:
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
249 class BLAKE2b : public BLAKE2_Base<word64, true>
250 {
251 public:
252  typedef BLAKE2_Base<word64, true> ThisBase; // Early Visual Studio workaround
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
285 class BLAKE2s : public BLAKE2_Base<word32, false>
286 {
287 public:
288  typedef BLAKE2_Base<word32, false> ThisBase; // Early Visual Studio workaround
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 
312 NAMESPACE_END
313 
314 #endif
void Restart()
Restart the hash.
Definition: blake2.cpp:372
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
Definition: blake2.h:193
BLAKE2b(const byte *key, size_t keyLength, const byte *salt=NULL, size_t saltLength=0, const byte *personalization=NULL, size_t personalizationLength=0, bool treeMode=false, unsigned int digestSize=DIGESTSIZE)
Construct a BLAKE2b hash.
Definition: blake2.h:270
BLAKE2 hash implementation.
Definition: blake2.h:162
Provides a base implementation of SimpleKeyingInterface.
Definition: seckey.h:278
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
Definition: blake2.cpp:444
Secure memory block with allocator and cleanup.
Definition: secblock.h:437
Abstract base classes that provide a uniform interface to this library.
BLAKE2 hash information.
Definition: blake2.h:32
BLAKE2s(bool treeMode=false, unsigned int digestSize=DIGESTSIZE)
Construct a BLAKE2s hash.
Definition: blake2.h:295
The BLAKE2s cryptographic hash function.
Definition: blake2.h:285
Classes and functions for secure memory allocations.
Classes and functions for implementing secret key algorithms.
#define CRYPTOPP_COMPILE_ASSERT(expr)
Compile time assertion.
Definition: misc.h:123
Interface for algorithms that take byte strings as keys.
Definition: cryptlib.h:529
SecBlock using AllocatorWithCleanup&lt;byte, true&gt; typedef.
Definition: secblock.h:737
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:62
BLAKE2s parameter block specialization.
Definition: blake2.h:95
Inherited by keyed algorithms with variable key length.
Definition: seckey.h:177
BLAKE2 state information.
Definition: blake2.h:136
std::string AlgorithmName() const
Retrieve the object&#39;s name.
Definition: blake2.h:190
BLAKE2 parameter block.
Definition: blake2.h:54
bool GetTreeMode() const
Get tree mode.
Definition: blake2.h:215
void SetTreeMode(bool mode)
Set tree mode.
Definition: blake2.h:210
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:533
static const char * StaticAlgorithmName()
Retrieve the static algorithm name.
Definition: blake2.h:183
BLAKE2b(bool treeMode=false, unsigned int digestSize=DIGESTSIZE)
Construct a BLAKE2b hash.
Definition: blake2.h:259
BLAKE2s(const byte *key, size_t keyLength, const byte *salt=NULL, size_t saltLength=0, const byte *personalization=NULL, size_t personalizationLength=0, bool treeMode=false, unsigned int digestSize=DIGESTSIZE)
Construct a BLAKE2s hash.
Definition: blake2.h:306
unsigned int DigestSize() const
Provides the digest size of the hash.
Definition: blake2.h:192
The BLAKE2b cryptographic hash function.
Definition: blake2.h:249
BLAKE2b parameter block specialization.
Definition: blake2.h:60
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: blake2.cpp:410