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 : 2988329 : Poly1305(Span<const std::byte> key) noexcept
50 : 2988329 : {
51 [ - + ]: 2988329 : assert(key.size() == KEYLEN);
52 : 2988329 : poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data()));
53 : 2988329 : }
54 : :
55 : : /** Process message bytes. */
56 : 11954421 : Poly1305& Update(Span<const std::byte> msg) noexcept
57 : : {
58 : 5978129 : poly1305_donna::poly1305_update(&m_ctx, UCharCast(msg.data()), msg.size());
59 [ + - ]: 5978129 : return *this;
60 : : }
61 : :
62 : : /** Write authentication tag to 16-byte out. */
63 : 2988329 : void Finalize(Span<std::byte> out) noexcept
64 : : {
65 [ - + ]: 2988329 : assert(out.size() == TAGLEN);
66 : 2988329 : poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data()));
67 : 2988329 : }
68 : : };
69 : :
70 : : #endif // BITCOIN_CRYPTO_POLY1305_H
|