/Users/brunogarcia/projects/bitcoin-core-dev/src/crypto/poly1305.h
Line | Count | Source |
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 | 0 | #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 | | Poly1305(std::span<const std::byte> key) noexcept |
51 | 0 | { |
52 | 0 | assert(key.size() == KEYLEN); |
53 | 0 | poly1305_donna::poly1305_init(&m_ctx, UCharCast(key.data())); |
54 | 0 | } |
55 | | |
56 | | /** Process message bytes. */ |
57 | | Poly1305& Update(std::span<const std::byte> msg) noexcept |
58 | 0 | { |
59 | 0 | poly1305_donna::poly1305_update(&m_ctx, UCharCast(msg.data()), msg.size()); |
60 | 0 | return *this; |
61 | 0 | } |
62 | | |
63 | | /** Write authentication tag to 16-byte out. */ |
64 | | void Finalize(std::span<std::byte> out) noexcept |
65 | 0 | { |
66 | 0 | assert(out.size() == TAGLEN); |
67 | 0 | poly1305_donna::poly1305_finish(&m_ctx, UCharCast(out.data())); |
68 | 0 | } |
69 | | }; |
70 | | |
71 | | #endif // BITCOIN_CRYPTO_POLY1305_H |