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