From 62e99837e8277290e90f93ee615aa5d711645822 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sun, 27 Nov 2016 15:31:50 -0500 Subject: Add Poly1305 class (Issue 338) --- poly1305.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 poly1305.h (limited to 'poly1305.h') diff --git a/poly1305.h b/poly1305.h new file mode 100644 index 00000000..d848ed2d --- /dev/null +++ b/poly1305.h @@ -0,0 +1,102 @@ +// poly1305.h - written and placed in the public domain by Jeffrey Walton and Jean-Pierre Munch +// Based on Andy Polyakov's 32-bit OpenSSL implementation using scalar multiplication. +// Copyright assigned to the Crypto++ project + +//! \file poly1305.h +//! \brief Classes for Poly1305 message authentication code +//! \sa Daniel J. Bernstein The Poly1305-AES +//! Message-Authentication Code (20050329) and Andy Polyakov Poly1305 Revised +//! \since Crypto++ 5.7 + +#ifndef CRYPTOPP_POLY1305_H +#define CRYPTOPP_POLY1305_H + +#include "cryptlib.h" +#include "seckey.h" +#include "secblock.h" +#include "argnames.h" +#include "algparam.h" + + +#include "files.h" +#include "filters.h" +#include "hex.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! \class Poly1305_Base +//! \brief Poly1305 message authentication code base class +//! \tparam T class derived from BlockCipherDocumentation with 16-byte key and 16-byte blocksize +//! \since Crypto++ 5.7 +template +class CRYPTOPP_NO_VTABLE Poly1305_Base : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 16>, public MessageAuthenticationCode +{ + CRYPTOPP_COMPILE_ASSERT(T::DEFAULT_KEYLENGTH == 16); + CRYPTOPP_COMPILE_ASSERT(T::BLOCKSIZE == 16); + +public: + static std::string StaticAlgorithmName() {return std::string("Poly1305(") + T::StaticAlgorithmName() + ")";} + + CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE) + CRYPTOPP_CONSTANT(BLOCKSIZE=T::BLOCKSIZE) + + Poly1305_Base() : m_used(true) {} + + void Resynchronize (const byte *iv, int ivLength=-1); + void GetNextIV (RandomNumberGenerator &rng, byte *iv); + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + void Restart(); + + unsigned int BlockSize() const {return BLOCKSIZE;} + unsigned int DigestSize() const {return DIGESTSIZE;} + +protected: + void ProcessBlocks(const byte *input, size_t length, word32 padbit); + void ProcessFinal(byte *mac, size_t length); + + CPP_TYPENAME T::Encryption m_cipher; + + // Accumulated hash, clamped r-key, and encrypted nonce + FixedSizeAlignedSecBlock m_h; + FixedSizeAlignedSecBlock m_r; + FixedSizeAlignedSecBlock m_n; + + // Accumulated message bytes and index + FixedSizeAlignedSecBlock m_acc; + size_t m_idx; + + // Track nonce reuse; assert in debug but continue + bool m_used; +}; + +//! \class Poly1305 +//! \brief Poly1305 message authentication code +//! \tparam T class derived from BlockCipherDocumentation +//! \sa Daniel J. Bernstein The Poly1305-AES +//! Message-Authentication Code (20050329) and Andy Polyakov Poly1305 Revised +//! \since Crypto++ 5.7 +template +class Poly1305 : public MessageAuthenticationCodeFinal > +{ +public: + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=Poly1305_Base::DEFAULT_KEYLENGTH); + + //! \brief Construct a Poly1305 + Poly1305() {} + + //! \brief Construct a Poly1305 + //! \param key a byte array used to key the cipher + //! \param length the size of the byte array, in bytes + Poly1305(const byte *key, size_t keyLength=DEFAULT_KEYLENGTH, const byte *nonce=NULL, size_t nonceLength=0) + {this->SetKey(key, keyLength, MakeParameters(Name::IV(), ConstByteArrayParameter(nonce, nonceLength)));} +}; + +NAMESPACE_END + +#endif // CRYPTOPP_POLY1305_H -- cgit v1.2.1