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