Coverage Report

Created: 2023-09-25 06:33

/src/botan/build/include/botan/internal/donna128.h
Line
Count
Source (jump to first uncovered line)
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
13
namespace Botan {
14
15
class donna128 final {
16
   public:
17
0
      donna128(uint64_t ll = 0, uint64_t hh = 0) {
18
0
         l = ll;
19
0
         h = hh;
20
0
      }
21
22
      donna128(const donna128&) = default;
23
      donna128& operator=(const donna128&) = default;
24
25
0
      friend donna128 operator>>(const donna128& x, size_t shift) {
26
0
         donna128 z = x;
27
0
         if(shift > 0) {
28
0
            const uint64_t carry = z.h << (64 - shift);
29
0
            z.h = (z.h >> shift);
30
0
            z.l = (z.l >> shift) | carry;
31
0
         }
32
0
         return z;
33
0
      }
34
35
0
      friend donna128 operator<<(const donna128& x, size_t shift) {
36
0
         donna128 z = x;
37
0
         if(shift > 0) {
38
0
            const uint64_t carry = z.l >> (64 - shift);
39
0
            z.l = (z.l << shift);
40
0
            z.h = (z.h << shift) | carry;
41
0
         }
42
0
         return z;
43
0
      }
44
45
0
      friend uint64_t operator&(const donna128& x, uint64_t mask) { return x.l & mask; }
46
47
0
      uint64_t operator&=(uint64_t mask) {
48
0
         h = 0;
49
0
         l &= mask;
50
0
         return l;
51
0
      }
52
53
0
      donna128& operator+=(const donna128& x) {
54
0
         l += x.l;
55
0
         h += x.h;
56
0
57
0
         const uint64_t carry = (l < x.l);
58
0
         h += carry;
59
0
         return *this;
60
0
      }
61
62
0
      donna128& operator+=(uint64_t x) {
63
0
         l += x;
64
0
         const uint64_t carry = (l < x);
65
0
         h += carry;
66
0
         return *this;
67
0
      }
68
69
0
      uint64_t lo() const { return l; }
70
71
0
      uint64_t hi() const { return h; }
72
73
   private:
74
      uint64_t h = 0, l = 0;
75
};
76
77
0
inline donna128 operator*(const donna128& x, uint64_t y) {
78
0
   BOTAN_ARG_CHECK(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply");
79
0
80
0
   uint64_t lo = 0, hi = 0;
81
0
   mul64x64_128(x.lo(), y, &lo, &hi);
82
0
   return donna128(lo, hi);
83
0
}
84
85
0
inline donna128 operator*(uint64_t y, const donna128& x) {
86
0
   return x * y;
87
0
}
88
89
0
inline donna128 operator+(const donna128& x, const donna128& y) {
90
0
   donna128 z = x;
91
0
   z += y;
92
0
   return z;
93
0
}
94
95
0
inline donna128 operator+(const donna128& x, uint64_t y) {
96
0
   donna128 z = x;
97
0
   z += y;
98
0
   return z;
99
0
}
100
101
0
inline donna128 operator|(const donna128& x, const donna128& y) {
102
0
   return donna128(x.lo() | y.lo(), x.hi() | y.hi());
103
0
}
104
105
0
inline uint64_t carry_shift(const donna128& a, size_t shift) {
106
0
   return (a >> shift).lo();
107
0
}
108
109
0
inline uint64_t combine_lower(const donna128& a, size_t s1, const donna128& b, size_t s2) {
110
0
   donna128 z = (a >> s1) | (b << s2);
111
0
   return z.lo();
112
0
}
113
114
#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
115
678k
inline uint64_t carry_shift(const uint128_t a, size_t shift) {
116
678k
   return static_cast<uint64_t>(a >> shift);
117
678k
}
118
119
192
inline uint64_t combine_lower(const uint128_t a, size_t s1, const uint128_t b, size_t s2) {
120
192
   return static_cast<uint64_t>((a >> s1) | (b << s2));
121
192
}
122
#endif
123
124
}  // namespace Botan
125
126
#endif