Branch data Line data Source code
1 : : // Copyright (c) 2019-2022 The Bitcoin Core developers 2 : : // Distributed under the MIT software license, see the accompanying 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : : 5 : : #ifndef BITCOIN_CRYPTO_POLY1305_H 6 : : #define BITCOIN_CRYPTO_POLY1305_H 7 : : 8 : : #include <span.h> 9 : : 10 : : #include <cassert> 11 : : #include <cstdlib> 12 : : #include <stdint.h> 13 : : 14 : : #define POLY1305_BLOCK_SIZE 16 15 : : 16 : : namespace poly1305_donna { 17 : : 18 : : // Based on the public domain implementation by Andrew Moon 19 : : // poly1305-donna-32.h from https://github.com/floodyberry/poly1305-donna 20 : : 21 : : typedef struct { 22 : : uint32_t r[5]; 23 : : uint32_t h[5]; 24 : : uint32_t pad[4]; 25 : : size_t leftover; 26 : : unsigned char buffer[POLY1305_BLOCK_SIZE]; 27 : : unsigned char final; 28 : : } poly1305_context; 29 : : 30 : : void poly1305_init(poly1305_context *st, const unsigned char key[32]) noexcept; 31 : : void poly1305_update(poly1305_context *st, const unsigned char *m, size_t bytes) noexcept; 32 : : void poly1305_finish(poly1305_context *st, unsigned char mac[16]) noexcept; 33 : : 34 : : } // namespace poly1305_donna 35 : : 36 : : /** C++ wrapper with std::byte Span interface around poly1305_donna code. */ 37 : : class Poly1305 38 : : { 39 : : poly1305_donna::poly1305_context m_ctx; 40 : : 41 : : public: 42 : : /** Length of the output produced by Finalize(). */ 43 : : static constexpr unsigned TAGLEN{16}; 44 : : 45 : : /** Length of the keys expected by the constructor. */ 46 : : static constexpr unsigned KEYLEN{32}; 47 : : 48 : : /** Construct a Poly1305 object with a given 32-byte key. */ 49 : 360 : Poly1305(Span<const std::byte> key) noexcept 50 : : { 51 [ + - ]: 360 : assert(key.size() == KEYLEN); 52 [ - + ]: 360 : poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data())); 53 : 360 : } 54 : : 55 : : /** Process message bytes. */ 56 : 1800 : Poly1305& Update(Span<const std::byte> msg) noexcept 57 : : { 58 [ # # ]: 1800 : poly1305_donna::poly1305_update(&m_ctx, UCharCast(msg.data()), msg.size()); 59 : 1800 : return *this; 60 : : } 61 : : 62 : : /** Write authentication tag to 16-byte out. */ 63 : 360 : void Finalize(Span<std::byte> out) noexcept 64 : : { 65 [ + - ]: 360 : assert(out.size() == TAGLEN); 66 [ - + ]: 360 : poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data())); 67 : 360 : } 68 : : }; 69 : : 70 : : #endif // BITCOIN_CRYPTO_POLY1305_H