Branch data Line data Source code
1 : : // Copyright (c) 2019-present 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 <cstddef>
12 : : #include <cstdint>
13 : : #include <span>
14 : :
15 : : #define POLY1305_BLOCK_SIZE 16
16 : :
17 : : namespace poly1305_donna {
18 : :
19 : : // Based on the public domain implementation by Andrew Moon
20 : : // poly1305-donna-32.h from https://github.com/floodyberry/poly1305-donna
21 : :
22 : : typedef struct {
23 : : uint32_t r[5];
24 : : uint32_t h[5];
25 : : uint32_t pad[4];
26 : : size_t leftover;
27 : : unsigned char buffer[POLY1305_BLOCK_SIZE];
28 : : unsigned char final;
29 : : } poly1305_context;
30 : :
31 : : void poly1305_init(poly1305_context *st, const unsigned char key[32]) noexcept;
32 : : void poly1305_update(poly1305_context *st, const unsigned char *m, size_t bytes) noexcept;
33 : : void poly1305_finish(poly1305_context *st, unsigned char mac[16]) noexcept;
34 : :
35 : : } // namespace poly1305_donna
36 : :
37 : : /** C++ wrapper with std::byte span interface around poly1305_donna code. */
38 : : class Poly1305
39 : : {
40 : : poly1305_donna::poly1305_context m_ctx;
41 : :
42 : : public:
43 : : /** Length of the output produced by Finalize(). */
44 : : static constexpr unsigned TAGLEN{16};
45 : :
46 : : /** Length of the keys expected by the constructor. */
47 : : static constexpr unsigned KEYLEN{32};
48 : :
49 : : /** Construct a Poly1305 object with a given 32-byte key. */
50 : 15179870 : Poly1305(std::span<const std::byte> key) noexcept
51 : 15179870 : {
52 [ - + ]: 15179870 : assert(key.size() == KEYLEN);
53 : 15179870 : poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data()));
54 : 15179870 : }
55 : :
56 : : /** Process message bytes. */
57 : 75900276 : Poly1305& Update(std::span<const std::byte> msg) noexcept
58 : : {
59 : 30361257 : poly1305_donna::poly1305_update(&m_ctx, UCharCast(msg.data()), msg.size());
60 [ + - - + ]: 30361257 : return *this;
61 : : }
62 : :
63 : : /** Write authentication tag to 16-byte out. */
64 : 15179870 : void Finalize(std::span<std::byte> out) noexcept
65 : : {
66 [ - + ]: 15179870 : assert(out.size() == TAGLEN);
67 : 15179870 : poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data()));
68 : 15179870 : }
69 : : };
70 : :
71 : : #endif // BITCOIN_CRYPTO_POLY1305_H
|