Botan 3.6.1
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/ct_utils.h>
12#include <botan/internal/mul128.h>
13#include <type_traits>
14
15namespace Botan {
16
18 public:
19 constexpr donna128(uint64_t ll = 0, uint64_t hh = 0) {
20 l = ll;
21 h = hh;
22 }
23
24 donna128(const donna128&) = default;
25 donna128& operator=(const donna128&) = default;
26
27 template <typename T>
28 constexpr friend donna128 operator>>(const donna128& x, T shift) {
29 donna128 z = x;
30
31 if(shift > 64) {
32 z.l = z.h >> (shift - 64);
33 z.h = 0;
34 } else if(shift == 64) {
35 z.l = z.h;
36 z.h = 0;
37 } else if(shift > 0) {
38 const uint64_t carry = z.h << static_cast<size_t>(64 - shift);
39 z.h >>= shift;
40 z.l >>= shift;
41 z.l |= carry;
42 }
43
44 return z;
45 }
46
47 template <typename T>
48 constexpr friend donna128 operator<<(const donna128& x, T shift) {
49 donna128 z = x;
50 if(shift > 64) {
51 z.h = z.l << (shift - 64);
52 z.l = 0;
53 } else if(shift == 64) {
54 z.h = z.l;
55 z.l = 0;
56 } else if(shift > 0) {
57 const uint64_t carry = z.l >> static_cast<size_t>(64 - shift);
58 z.l = (z.l << shift);
59 z.h = (z.h << shift) | carry;
60 }
61
62 return z;
63 }
64
65 constexpr friend uint64_t operator&(const donna128& x, uint64_t mask) { return x.l & mask; }
66
67 constexpr uint64_t operator&=(uint64_t mask) {
68 h = 0;
69 l &= mask;
70 return l;
71 }
72
73 constexpr donna128& operator+=(const donna128& x) {
74 l += x.l;
75 h += x.h;
76
77 const uint64_t carry = CT::Mask<uint64_t>::is_lt(l, x.l).if_set_return(1);
78 h += carry;
79 return *this;
80 }
81
82 constexpr donna128& operator+=(uint64_t x) {
83 l += x;
84 const uint64_t carry = CT::Mask<uint64_t>::is_lt(l, x).if_set_return(1);
85 h += carry;
86 return *this;
87 }
88
89 constexpr uint64_t lo() const { return l; }
90
91 constexpr uint64_t hi() const { return h; }
92
93 constexpr operator uint64_t() const { return l; }
94
95 private:
96 uint64_t h = 0, l = 0;
97};
98
99template <std::unsigned_integral T>
100constexpr inline donna128 operator*(const donna128& x, T y) {
101 BOTAN_ARG_CHECK(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply");
102
103 uint64_t lo = 0, hi = 0;
104 mul64x64_128(x.lo(), static_cast<uint64_t>(y), &lo, &hi);
105 return donna128(lo, hi);
106}
107
108template <std::unsigned_integral T>
109constexpr inline donna128 operator*(T y, const donna128& x) {
110 return x * y;
111}
112
113constexpr inline donna128 operator+(const donna128& x, const donna128& y) {
114 donna128 z = x;
115 z += y;
116 return z;
117}
118
119constexpr inline donna128 operator+(const donna128& x, uint64_t y) {
120 donna128 z = x;
121 z += y;
122 return z;
123}
124
125constexpr inline donna128 operator|(const donna128& x, const donna128& y) {
126 return donna128(x.lo() | y.lo(), x.hi() | y.hi());
127}
128
129constexpr inline donna128 operator|(const donna128& x, uint64_t y) {
130 return donna128(x.lo() | y, x.hi());
131}
132
133constexpr inline uint64_t carry_shift(const donna128& a, size_t shift) {
134 return (a >> shift).lo();
135}
136
137constexpr inline uint64_t combine_lower(const donna128& a, size_t s1, const donna128& b, size_t s2) {
138 donna128 z = (a >> s1) | (b << s2);
139 return z.lo();
140}
141
142#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
143inline uint64_t carry_shift(const uint128_t a, size_t shift) {
144 return static_cast<uint64_t>(a >> shift);
145}
146
147inline uint64_t combine_lower(const uint128_t a, size_t s1, const uint128_t b, size_t s2) {
148 return static_cast<uint64_t>((a >> s1) | (b << s2));
149}
150#endif
151
152} // namespace Botan
153
154#endif
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
static constexpr Mask< T > is_lt(T x, T y)
Definition ct_utils.h:442
constexpr uint64_t operator&=(uint64_t mask)
Definition donna128.h:67
constexpr uint64_t lo() const
Definition donna128.h:89
constexpr donna128 & operator+=(uint64_t x)
Definition donna128.h:82
constexpr friend donna128 operator<<(const donna128 &x, T shift)
Definition donna128.h:48
constexpr friend uint64_t operator&(const donna128 &x, uint64_t mask)
Definition donna128.h:65
constexpr uint64_t hi() const
Definition donna128.h:91
constexpr donna128(uint64_t ll=0, uint64_t hh=0)
Definition donna128.h:19
constexpr friend donna128 operator>>(const donna128 &x, T shift)
Definition donna128.h:28
constexpr donna128 & operator+=(const donna128 &x)
Definition donna128.h:73
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:133
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)
const SIMD_8x32 & b
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:137