Botan 3.9.0
Crypto and TLS for C&
donna128.h
Go to the documentation of this file.
1/*
2* A minimal 128-bit integer type
3* (C) 2014 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_DONNA128_H_
9#define BOTAN_DONNA128_H_
10
11#include <botan/internal/ct_utils.h>
12#include <botan/internal/mul128.h>
13#include <concepts>
14
15namespace Botan {
16
17class donna128 final {
18 public:
19 constexpr explicit donna128(uint64_t l = 0, uint64_t h = 0) : m_lo(l), m_hi(h) {}
20
21 template <std::unsigned_integral T>
22 constexpr friend donna128 operator>>(const donna128& x, T shift) {
23 donna128 z = x;
24
25 if(shift > 64) {
26 z.m_lo = z.m_hi >> (shift - 64);
27 z.m_hi = 0;
28 } else if(shift == 64) {
29 z.m_lo = z.m_hi;
30 z.m_hi = 0;
31 } else if(shift > 0) {
32 const uint64_t carry = z.m_hi << static_cast<size_t>(64 - shift);
33 z.m_hi >>= shift;
34 z.m_lo >>= shift;
35 z.m_lo |= carry;
36 }
37
38 return z;
39 }
40
41 template <std::unsigned_integral T>
42 constexpr friend donna128 operator<<(const donna128& x, T shift) {
43 donna128 z = x;
44 if(shift > 64) {
45 z.m_hi = z.m_lo << (shift - 64);
46 z.m_lo = 0;
47 } else if(shift == 64) {
48 z.m_hi = z.m_lo;
49 z.m_lo = 0;
50 } else if(shift > 0) {
51 const uint64_t carry = z.m_lo >> static_cast<size_t>(64 - shift);
52 z.m_lo = (z.m_lo << shift);
53 z.m_hi = (z.m_hi << shift) | carry;
54 }
55
56 return z;
57 }
58
59 constexpr friend uint64_t operator&(const donna128& x, uint64_t mask) { return x.m_lo & mask; }
60
61 constexpr uint64_t operator&=(uint64_t mask) {
62 m_hi = 0;
63 m_lo &= mask;
64 return m_lo;
65 }
66
67 constexpr donna128& operator+=(const donna128& x) {
68 m_lo += x.m_lo;
69 m_hi += x.m_hi;
70
71 const uint64_t carry = CT::Mask<uint64_t>::is_lt(m_lo, x.m_lo).if_set_return(1);
72 m_hi += carry;
73 return *this;
74 }
75
76 constexpr donna128& operator+=(uint64_t x) {
77 m_lo += x;
78 const uint64_t carry = CT::Mask<uint64_t>::is_lt(m_lo, x).if_set_return(1);
79 m_hi += carry;
80 return *this;
81 }
82
83 constexpr uint64_t lo() const { return m_lo; }
84
85 constexpr uint64_t hi() const { return m_hi; }
86
87 constexpr explicit operator uint64_t() const { return lo(); }
88
89 private:
90 uint64_t m_lo = 0;
91 uint64_t m_hi = 0;
92};
93
94template <std::integral T>
95constexpr inline donna128 operator*(const donna128& x, T y) {
96 BOTAN_ARG_CHECK(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply");
97
98 uint64_t lo = 0;
99 uint64_t hi = 0;
100 mul64x64_128(x.lo(), static_cast<uint64_t>(y), &lo, &hi);
101 return donna128(lo, hi);
102}
103
104template <std::integral T>
105constexpr inline donna128 operator*(T y, const donna128& x) {
106 return x * y;
107}
108
109constexpr inline donna128 operator+(const donna128& x, const donna128& y) {
110 donna128 z = x;
111 z += y;
112 return z;
113}
114
115constexpr inline donna128 operator+(const donna128& x, uint64_t y) {
116 donna128 z = x;
117 z += y;
118 return z;
119}
120
121constexpr inline donna128 operator|(const donna128& x, const donna128& y) {
122 return donna128(x.lo() | y.lo(), x.hi() | y.hi());
123}
124
125constexpr inline donna128 operator|(const donna128& x, uint64_t y) {
126 return donna128(x.lo() | y, x.hi());
127}
128
129constexpr inline uint64_t carry_shift(const donna128& a, size_t shift) {
130 return (a >> shift).lo();
131}
132
133constexpr inline uint64_t combine_lower(const donna128& a, size_t s1, const donna128& b, size_t s2) {
134 donna128 z = (a >> s1) | (b << s2);
135 return z.lo();
136}
137
138#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
139inline uint64_t carry_shift(const uint128_t a, size_t shift) {
140 return static_cast<uint64_t>(a >> shift);
141}
142
143inline uint64_t combine_lower(const uint128_t a, size_t s1, const uint128_t b, size_t s2) {
144 return static_cast<uint64_t>((a >> s1) | (b << s2));
145}
146#endif
147
148} // namespace Botan
149
150#endif
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
static constexpr Mask< T > is_lt(T x, T y)
Definition ct_utils.h:478
constexpr uint64_t operator&=(uint64_t mask)
Definition donna128.h:61
constexpr uint64_t lo() const
Definition donna128.h:83
constexpr donna128 & operator+=(uint64_t x)
Definition donna128.h:76
constexpr friend donna128 operator<<(const donna128 &x, T shift)
Definition donna128.h:42
constexpr friend uint64_t operator&(const donna128 &x, uint64_t mask)
Definition donna128.h:59
constexpr uint64_t hi() const
Definition donna128.h:85
constexpr friend donna128 operator>>(const donna128 &x, T shift)
Definition donna128.h:22
constexpr donna128 & operator+=(const donna128 &x)
Definition donna128.h:67
constexpr donna128(uint64_t l=0, uint64_t h=0)
Definition donna128.h:19
ASN1_Type operator|(ASN1_Type x, ASN1_Type y)
Definition asn1_obj.h:74
constexpr uint64_t carry_shift(const donna128 &a, size_t shift)
Definition donna128.h:129
BigInt operator*(const BigInt &x, const BigInt &y)
Definition big_ops3.cpp:56
OctetString operator+(const OctetString &k1, const OctetString &k2)
Definition symkey.cpp:99
void carry(int64_t &h0, int64_t &h1)
constexpr void mul64x64_128(uint64_t a, uint64_t b, uint64_t *lo, uint64_t *hi)
Definition mul128.h:24
constexpr uint64_t combine_lower(const donna128 &a, size_t s1, const donna128 &b, size_t s2)
Definition donna128.h:133