Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:54

0001 // blake2.h - written and placed in the public domain by Jeffrey Walton

0002 //            and Zooko Wilcox-O'Hearn. Based on Aumasson, Neves,

0003 //            Wilcox-O'Hearn and Winnerlein's reference BLAKE2

0004 //            implementation at http://github.com/BLAKE2/BLAKE2.

0005 
0006 /// \file blake2.h

0007 /// \brief Classes for BLAKE2b and BLAKE2s message digests and keyed message digests

0008 /// \details This implementation follows Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's

0009 ///   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).

0010 ///   Static algorithm name return either "BLAKE2b" or "BLAKE2s". An object algorithm name follows

0011 ///   the naming described in <A HREF="http://tools.ietf.org/html/rfc7693#section-4">RFC 7693, The

0012 ///   BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)</A>.

0013 /// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0,

0014 ///   Power8 since Crypto++ 8.0

0015 
0016 #ifndef CRYPTOPP_BLAKE2_H
0017 #define CRYPTOPP_BLAKE2_H
0018 
0019 #include "cryptlib.h"
0020 #include "secblock.h"
0021 #include "seckey.h"
0022 
0023 NAMESPACE_BEGIN(CryptoPP)
0024 
0025 /// \brief BLAKE2s hash information

0026 /// \since Crypto++ 5.6.4

0027 struct BLAKE2s_Info : public VariableKeyLength<32,0,32,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE>
0028 {
0029     typedef VariableKeyLength<32,0,32,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase;
0030     CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH);
0031     CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH);
0032     CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH);
0033 
0034     CRYPTOPP_CONSTANT(BLOCKSIZE = 64);
0035     CRYPTOPP_CONSTANT(DIGESTSIZE = 32);
0036     CRYPTOPP_CONSTANT(SALTSIZE = 8);
0037     CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = 8);
0038 
0039     CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2s";}
0040 };
0041 
0042 /// \brief BLAKE2b hash information

0043 /// \since Crypto++ 5.6.4

0044 struct BLAKE2b_Info : public VariableKeyLength<64,0,64,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE>
0045 {
0046     typedef VariableKeyLength<64,0,64,1,SimpleKeyingInterface::NOT_RESYNCHRONIZABLE> KeyBase;
0047     CRYPTOPP_CONSTANT(MIN_KEYLENGTH = KeyBase::MIN_KEYLENGTH);
0048     CRYPTOPP_CONSTANT(MAX_KEYLENGTH = KeyBase::MAX_KEYLENGTH);
0049     CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = KeyBase::DEFAULT_KEYLENGTH);
0050 
0051     CRYPTOPP_CONSTANT(BLOCKSIZE = 128);
0052     CRYPTOPP_CONSTANT(DIGESTSIZE = 64);
0053     CRYPTOPP_CONSTANT(SALTSIZE = 16);
0054     CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = 16);
0055 
0056     CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2b";}
0057 };
0058 
0059 /// \brief BLAKE2s parameter block

0060 struct CRYPTOPP_NO_VTABLE BLAKE2s_ParameterBlock
0061 {
0062     CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2s_Info::SALTSIZE);
0063     CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2s_Info::DIGESTSIZE);
0064     CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2s_Info::PERSONALIZATIONSIZE);
0065 
0066     BLAKE2s_ParameterBlock()
0067     {
0068         Reset();
0069     }
0070 
0071     BLAKE2s_ParameterBlock(size_t digestSize)
0072     {
0073         Reset(digestSize);
0074     }
0075 
0076     BLAKE2s_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength,
0077         const byte* personalization, size_t personalizationLength);
0078 
0079     void Reset(size_t digestLength=DIGESTSIZE, size_t keyLength=0);
0080 
0081     byte* data() {
0082         return m_data.data();
0083     }
0084 
0085     const byte* data() const {
0086         return m_data.data();
0087     }
0088 
0089     size_t size() const {
0090         return m_data.size();
0091     }
0092 
0093     byte* salt() {
0094         return m_data + SaltOff;
0095     }
0096 
0097     byte* personalization() {
0098         return m_data + PersonalizationOff;
0099     }
0100 
0101     // Offsets into the byte array

0102     enum {
0103         DigestOff = 0, KeyOff = 1, FanoutOff = 2, DepthOff = 3, LeafOff = 4, NodeOff = 8,
0104         NodeDepthOff = 14, InnerOff = 15, SaltOff = 16, PersonalizationOff = 24
0105     };
0106 
0107     FixedSizeAlignedSecBlock<byte, 32, true> m_data;
0108 };
0109 
0110 /// \brief BLAKE2b parameter block

0111 struct CRYPTOPP_NO_VTABLE BLAKE2b_ParameterBlock
0112 {
0113     CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2b_Info::SALTSIZE);
0114     CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2b_Info::DIGESTSIZE);
0115     CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2b_Info::PERSONALIZATIONSIZE);
0116 
0117     BLAKE2b_ParameterBlock()
0118     {
0119         Reset();
0120     }
0121 
0122     BLAKE2b_ParameterBlock(size_t digestSize)
0123     {
0124         Reset(digestSize);
0125     }
0126 
0127     BLAKE2b_ParameterBlock(size_t digestSize, size_t keyLength, const byte* salt, size_t saltLength,
0128         const byte* personalization, size_t personalizationLength);
0129 
0130     void Reset(size_t digestLength=DIGESTSIZE, size_t keyLength=0);
0131 
0132     byte* data() {
0133         return m_data.data();
0134     }
0135 
0136     const byte* data() const {
0137         return m_data.data();
0138     }
0139 
0140     size_t size() const {
0141         return m_data.size();
0142     }
0143 
0144     byte* salt() {
0145         return m_data + SaltOff;
0146     }
0147 
0148     byte* personalization() {
0149         return m_data + PersonalizationOff;
0150     }
0151 
0152     // Offsets into the byte array

0153     enum {
0154         DigestOff = 0, KeyOff = 1, FanoutOff = 2, DepthOff = 3, LeafOff = 4, NodeOff = 8,
0155         NodeDepthOff = 16, InnerOff = 17, RfuOff = 18, SaltOff = 32, PersonalizationOff = 48
0156     };
0157 
0158     FixedSizeAlignedSecBlock<byte, 64, true> m_data;
0159 };
0160 
0161 /// \brief BLAKE2s state information

0162 /// \since Crypto++ 5.6.4

0163 struct CRYPTOPP_NO_VTABLE BLAKE2s_State
0164 {
0165     BLAKE2s_State() {
0166         Reset();
0167     }
0168 
0169     void Reset();
0170 
0171     inline word32* h() {
0172         return m_hft.data();
0173     }
0174 
0175     inline word32* t() {
0176         return m_hft.data() + 8;
0177     }
0178 
0179     inline word32* f() {
0180         return m_hft.data() + 10;
0181     }
0182 
0183     inline byte* data() {
0184         return m_buf.data();
0185     }
0186 
0187     // SSE4, Power7 and NEON depend upon t[] and f[] being side-by-side

0188     CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2s_Info::BLOCKSIZE);
0189     FixedSizeAlignedSecBlock<word32, 8+2+2, true> m_hft;
0190     FixedSizeAlignedSecBlock<byte, BLOCKSIZE, true> m_buf;
0191     size_t m_len;
0192 };
0193 
0194 /// \brief BLAKE2b state information

0195 /// \since Crypto++ 5.6.4

0196 struct CRYPTOPP_NO_VTABLE BLAKE2b_State
0197 {
0198     BLAKE2b_State() {
0199         Reset();
0200     }
0201 
0202     void Reset();
0203 
0204     inline word64* h() {
0205         return m_hft.data();
0206     }
0207 
0208     inline word64* t() {
0209         return m_hft.data() + 8;
0210     }
0211 
0212     inline word64* f() {
0213         return m_hft.data() + 10;
0214     }
0215 
0216     inline byte* data() {
0217         return m_buf.data();
0218     }
0219 
0220     // SSE4, Power8 and NEON depend upon t[] and f[] being side-by-side

0221     CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2b_Info::BLOCKSIZE);
0222     FixedSizeAlignedSecBlock<word64, 8+2+2, true> m_hft;
0223     FixedSizeAlignedSecBlock<byte, BLOCKSIZE, true> m_buf;
0224     size_t m_len;
0225 };
0226 
0227 /// \brief The BLAKE2s cryptographic hash function

0228 /// \details BLAKE2s can function as both a hash and keyed hash. If you want only the hash,

0229 ///   then use the BLAKE2s constructor that accepts no parameters or digest size. If you

0230 ///   want a keyed hash, then use the constructor that accpts the key as a parameter.

0231 ///   Once a key and digest size are selected, its effectively immutable. The Restart()

0232 ///   method that accepts a ParameterBlock does not allow you to change it.

0233 /// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's

0234 ///   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).

0235 /// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0,

0236 ///   Power8 since Crypto++ 8.0

0237 class BLAKE2s : public SimpleKeyingInterfaceImpl<MessageAuthenticationCode, BLAKE2s_Info>
0238 {
0239 public:
0240     CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2s_Info::DEFAULT_KEYLENGTH);
0241     CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2s_Info::MIN_KEYLENGTH);
0242     CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2s_Info::MAX_KEYLENGTH);
0243 
0244     CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2s_Info::DIGESTSIZE);
0245     CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2s_Info::BLOCKSIZE);
0246     CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2s_Info::SALTSIZE);
0247     CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2s_Info::PERSONALIZATIONSIZE);
0248 
0249     typedef BLAKE2s_State State;
0250     typedef BLAKE2s_ParameterBlock ParameterBlock;
0251 
0252     CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2s";}
0253 
0254     virtual ~BLAKE2s() {}
0255 
0256     /// \brief Construct a BLAKE2s hash

0257     /// \param digestSize the digest size, in bytes

0258     /// \param treeMode flag indicating tree mode

0259     /// \since Crypto++ 5.6.4

0260     BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
0261 
0262     /// \brief Construct a BLAKE2s hash

0263     /// \param digestSize the digest size, in bytes

0264     /// \details treeMode flag is set to false

0265     /// \since Crypto++ 8.2

0266     BLAKE2s(unsigned int digestSize);
0267 
0268     /// \brief Construct a BLAKE2s hash

0269     /// \param key a byte array used to key the cipher

0270     /// \param keyLength the size of the byte array

0271     /// \param salt a byte array used as salt

0272     /// \param saltLength the size of the byte array

0273     /// \param personalization a byte array used as personalization string

0274     /// \param personalizationLength the size of the byte array

0275     /// \param treeMode flag indicating tree mode

0276     /// \param digestSize the digest size, in bytes

0277     /// \since Crypto++ 5.6.4

0278     BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0,
0279         const byte* personalization = NULLPTR, size_t personalizationLength = 0,
0280         bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
0281 
0282     /// \brief Retrieve the object's name

0283     /// \return the object's algorithm name following RFC 7693

0284     /// \details Object algorithm name follows the naming described in

0285     ///   <A HREF="http://tools.ietf.org/html/rfc7693#section-4">RFC 7693, The BLAKE2 Cryptographic Hash and

0286     /// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".

0287     std::string AlgorithmName() const {return std::string(BLAKE2s_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);}
0288 
0289     unsigned int BlockSize() const {return BLOCKSIZE;}
0290     unsigned int DigestSize() const {return m_digestSize;}
0291     unsigned int OptimalDataAlignment() const;
0292 
0293     void Update(const byte *input, size_t length);
0294     void Restart();
0295 
0296     /// \brief Restart a hash with parameter block and counter

0297     /// \param block parameter block

0298     /// \param counter counter array

0299     /// \details Parameter block is persisted across calls to Restart().

0300     void Restart(const BLAKE2s_ParameterBlock& block, const word32 counter[2]);
0301 
0302     /// \brief Set tree mode

0303     /// \param mode the new tree mode

0304     /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1].

0305     ///   If <tt>treeMode=false</tt> (default), then State::f[1] is never set. If

0306     ///   <tt>treeMode=true</tt>, then State::f[1] is set when State::f[0] is set.

0307     ///   Tree mode is persisted across calls to Restart().

0308     void SetTreeMode(bool mode) {m_treeMode=mode;}
0309 
0310     /// \brief Get tree mode

0311     /// \return the current tree mode

0312     /// \details Tree mode is persisted across calls to Restart().

0313     bool GetTreeMode() const {return m_treeMode;}
0314 
0315     void TruncatedFinal(byte *hash, size_t size);
0316 
0317     std::string AlgorithmProvider() const;
0318 
0319 protected:
0320     // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's.

0321     void Compress(const byte *input);
0322     inline void IncrementCounter(size_t count=BLOCKSIZE);
0323 
0324     void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params);
0325 
0326 private:
0327     State m_state;
0328     ParameterBlock m_block;
0329     AlignedSecByteBlock m_key;
0330     word32 m_digestSize, m_keyLength;
0331     bool m_treeMode;
0332 };
0333 
0334 /// \brief The BLAKE2b cryptographic hash function

0335 /// \details BLAKE2b can function as both a hash and keyed hash. If you want only the hash,

0336 ///   then use the BLAKE2b constructor that accepts no parameters or digest size. If you

0337 ///   want a keyed hash, then use the constructor that accpts the key as a parameter.

0338 ///   Once a key and digest size are selected, its effectively immutable. The Restart()

0339 ///   method that accepts a ParameterBlock does not allow you to change it.

0340 /// \sa Aumasson, Neves, Wilcox-O'Hearn and Winnerlein's

0341 ///   <A HREF="http://blake2.net/blake2.pdf">BLAKE2: simpler, smaller, fast as MD5</A> (2013.01.29).

0342 /// \since C++ since Crypto++ 5.6.4, SSE since Crypto++ 5.6.4, NEON since Crypto++ 6.0,

0343 ///   Power8 since Crypto++ 8.0

0344 class BLAKE2b : public SimpleKeyingInterfaceImpl<MessageAuthenticationCode, BLAKE2b_Info>
0345 {
0346 public:
0347     CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH = BLAKE2b_Info::DEFAULT_KEYLENGTH);
0348     CRYPTOPP_CONSTANT(MIN_KEYLENGTH = BLAKE2b_Info::MIN_KEYLENGTH);
0349     CRYPTOPP_CONSTANT(MAX_KEYLENGTH = BLAKE2b_Info::MAX_KEYLENGTH);
0350 
0351     CRYPTOPP_CONSTANT(DIGESTSIZE = BLAKE2b_Info::DIGESTSIZE);
0352     CRYPTOPP_CONSTANT(BLOCKSIZE = BLAKE2b_Info::BLOCKSIZE);
0353     CRYPTOPP_CONSTANT(SALTSIZE = BLAKE2b_Info::SALTSIZE);
0354     CRYPTOPP_CONSTANT(PERSONALIZATIONSIZE = BLAKE2b_Info::PERSONALIZATIONSIZE);
0355 
0356     typedef BLAKE2b_State State;
0357     typedef BLAKE2b_ParameterBlock ParameterBlock;
0358 
0359     CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BLAKE2b";}
0360 
0361     virtual ~BLAKE2b() {}
0362 
0363     /// \brief Construct a BLAKE2b hash

0364     /// \param digestSize the digest size, in bytes

0365     /// \param treeMode flag indicating tree mode

0366     /// \since Crypto++ 5.6.4

0367     BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
0368 
0369     /// \brief Construct a BLAKE2s hash

0370     /// \param digestSize the digest size, in bytes

0371     /// \details treeMode flag is set to false

0372     /// \since Crypto++ 8.2

0373     BLAKE2b(unsigned int digestSize);
0374 
0375     /// \brief Construct a BLAKE2b hash

0376     /// \param key a byte array used to key the cipher

0377     /// \param keyLength the size of the byte array

0378     /// \param salt a byte array used as salt

0379     /// \param saltLength the size of the byte array

0380     /// \param personalization a byte array used as personalization string

0381     /// \param personalizationLength the size of the byte array

0382     /// \param treeMode flag indicating tree mode

0383     /// \param digestSize the digest size, in bytes

0384     /// \since Crypto++ 5.6.4

0385     BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0,
0386         const byte* personalization = NULLPTR, size_t personalizationLength = 0,
0387         bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
0388 
0389     /// \brief Retrieve the object's name

0390     /// \return the object's algorithm name following RFC 7693

0391     /// \details Object algorithm name follows the naming described in

0392     ///   <A HREF="http://tools.ietf.org/html/rfc7693#section-4">RFC 7693, The BLAKE2 Cryptographic Hash and

0393     /// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".

0394     std::string AlgorithmName() const {return std::string(BLAKE2b_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);}
0395 
0396     unsigned int BlockSize() const {return BLOCKSIZE;}
0397     unsigned int DigestSize() const {return m_digestSize;}
0398     unsigned int OptimalDataAlignment() const;
0399 
0400     void Update(const byte *input, size_t length);
0401     void Restart();
0402 
0403     /// \brief Restart a hash with parameter block and counter

0404     /// \param block parameter block

0405     /// \param counter counter array

0406     /// \details Parameter block is persisted across calls to Restart().

0407     void Restart(const BLAKE2b_ParameterBlock& block, const word64 counter[2]);
0408 
0409     /// \brief Set tree mode

0410     /// \param mode the new tree mode

0411     /// \details BLAKE2 has two finalization flags, called State::f[0] and State::f[1].

0412     ///   If <tt>treeMode=false</tt> (default), then State::f[1] is never set. If

0413     ///   <tt>treeMode=true</tt>, then State::f[1] is set when State::f[0] is set.

0414     ///   Tree mode is persisted across calls to Restart().

0415     void SetTreeMode(bool mode) {m_treeMode=mode;}
0416 
0417     /// \brief Get tree mode

0418     /// \return the current tree mode

0419     /// \details Tree mode is persisted across calls to Restart().

0420     bool GetTreeMode() const {return m_treeMode;}
0421 
0422     void TruncatedFinal(byte *hash, size_t size);
0423 
0424     std::string AlgorithmProvider() const;
0425 
0426 protected:
0427 
0428     // Operates on state buffer and/or input. Must be BLOCKSIZE, final block will pad with 0's.

0429     void Compress(const byte *input);
0430     inline void IncrementCounter(size_t count=BLOCKSIZE);
0431 
0432     void UncheckedSetKey(const byte* key, unsigned int length, const CryptoPP::NameValuePairs& params);
0433 
0434 private:
0435     State m_state;
0436     ParameterBlock m_block;
0437     AlignedSecByteBlock m_key;
0438     word32 m_digestSize, m_keyLength;
0439     bool m_treeMode;
0440 };
0441 
0442 NAMESPACE_END
0443 
0444 #endif