Coverage Report

Created: 2021-10-13 08:49

/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
   {
17
   public:
18
0
      donna128(uint64_t ll = 0, uint64_t hh = 0) { l = ll; h = hh; }
19
20
      donna128(const donna128&) = default;
21
      donna128& operator=(const donna128&) = default;
22
23
      friend donna128 operator>>(const donna128& x, size_t shift)
24
0
         {
25
0
         donna128 z = x;
26
0
         if(shift > 0)
27
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
      friend donna128 operator<<(const donna128& x, size_t shift)
36
0
         {
37
0
         donna128 z = x;
38
0
         if(shift > 0)
39
0
            {
40
0
            const uint64_t carry = z.l >> (64 - shift);
41
0
            z.l = (z.l << shift);
42
0
            z.h = (z.h << shift) | carry;
43
0
            }
44
0
         return z;
45
0
         }
46
47
      friend uint64_t operator&(const donna128& x, uint64_t mask)
48
0
         {
49
0
         return x.l & mask;
50
0
         }
51
52
      uint64_t operator&=(uint64_t mask)
53
0
         {
54
0
         h = 0;
55
0
         l &= mask;
56
0
         return l;
57
0
         }
58
59
      donna128& operator+=(const donna128& x)
60
0
         {
61
0
         l += x.l;
62
0
         h += x.h;
63
0
64
0
         const uint64_t carry = (l < x.l);
65
0
         h += carry;
66
0
         return *this;
67
0
         }
68
69
      donna128& operator+=(uint64_t x)
70
0
         {
71
0
         l += x;
72
0
         const uint64_t carry = (l < x);
73
0
         h += carry;
74
0
         return *this;
75
0
         }
76
77
0
      uint64_t lo() const { return l; }
78
0
      uint64_t hi() const { return h; }
79
   private:
80
      uint64_t h = 0, l = 0;
81
   };
82
83
inline donna128 operator*(const donna128& x, uint64_t y)
84
0
   {
85
0
   BOTAN_ARG_CHECK(x.hi() == 0, "High 64 bits of donna128 set to zero during multiply");
86
0
87
0
   uint64_t lo = 0, hi = 0;
88
0
   mul64x64_128(x.lo(), y, &lo, &hi);
89
0
   return donna128(lo, hi);
90
0
   }
91
92
inline donna128 operator*(uint64_t y, const donna128& x)
93
0
   {
94
0
   return x * y;
95
0
   }
96
97
inline donna128 operator+(const donna128& x, const donna128& y)
98
0
   {
99
0
   donna128 z = x;
100
0
   z += y;
101
0
   return z;
102
0
   }
103
104
inline donna128 operator+(const donna128& x, uint64_t y)
105
0
   {
106
0
   donna128 z = x;
107
0
   z += y;
108
0
   return z;
109
0
   }
110
111
inline donna128 operator|(const donna128& x, const donna128& y)
112
0
   {
113
0
   return donna128(x.lo() | y.lo(), x.hi() | y.hi());
114
0
   }
115
116
inline uint64_t carry_shift(const donna128& a, size_t shift)
117
0
   {
118
0
   return (a >> shift).lo();
119
0
   }
120
121
inline uint64_t combine_lower(const donna128& a, size_t s1,
122
                              const donna128& b, size_t s2)
123
0
   {
124
0
   donna128 z = (a >> s1) | (b << s2);
125
0
   return z.lo();
126
0
   }
127
128
#if defined(BOTAN_TARGET_HAS_NATIVE_UINT128)
129
inline uint64_t carry_shift(const uint128_t a, size_t shift)
130
6.66M
   {
131
6.66M
   return static_cast<uint64_t>(a >> shift);
132
6.66M
   }
133
134
inline uint64_t combine_lower(const uint128_t a, size_t s1,
135
                              const uint128_t b, size_t s2)
136
1.88k
   {
137
1.88k
   return static_cast<uint64_t>((a >> s1) | (b << s2));
138
1.88k
   }
139
#endif
140
141
}
142
143
#endif