Coverage Report

Created: 2024-11-29 06:10

/src/botan/src/lib/pubkey/ec_group/ec_scalar.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* (C) 2024 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#include <botan/ec_scalar.h>
8
9
#include <botan/ec_group.h>
10
#include <botan/internal/ec_inner_data.h>
11
12
namespace Botan {
13
14
0
EC_Scalar EC_Scalar::_from_inner(std::unique_ptr<EC_Scalar_Data> inner) {
15
0
   return EC_Scalar(std::move(inner));
16
0
}
17
18
35.8k
EC_Scalar::EC_Scalar(std::unique_ptr<EC_Scalar_Data> scalar) : m_scalar(std::move(scalar)) {
19
35.8k
   BOTAN_ASSERT_NONNULL(m_scalar);
20
35.8k
}
21
22
1.26k
EC_Scalar::EC_Scalar(const EC_Scalar& other) : m_scalar(other.inner().clone()) {}
23
24
24.6k
EC_Scalar::EC_Scalar(EC_Scalar&& other) noexcept : m_scalar(std::move(other.m_scalar)) {}
25
26
0
EC_Scalar& EC_Scalar::operator=(const EC_Scalar& other) {
27
0
   if(this != &other) {
28
0
      this->assign(other);
29
0
   }
30
0
   return (*this);
31
0
}
32
33
0
EC_Scalar& EC_Scalar::operator=(EC_Scalar&& other) noexcept {
34
0
   BOTAN_ARG_CHECK(_inner().group() == other._inner().group(), "Curve mismatch");
35
0
   std::swap(m_scalar, other.m_scalar);
36
0
   return (*this);
37
0
}
38
39
62.1k
EC_Scalar::~EC_Scalar() = default;
40
41
0
size_t EC_Scalar::bytes() const {
42
0
   return m_scalar->bytes();
43
0
}
44
45
347
EC_Scalar EC_Scalar::from_bytes_with_trunc(const EC_Group& group, std::span<const uint8_t> bytes) {
46
347
   return EC_Scalar(group._data()->scalar_from_bytes_with_trunc(bytes));
47
347
}
48
49
201
EC_Scalar EC_Scalar::from_bytes_mod_order(const EC_Group& group, std::span<const uint8_t> bytes) {
50
201
   if(auto s = group._data()->scalar_from_bytes_mod_order(bytes)) {
51
200
      return EC_Scalar(std::move(s));
52
200
   } else {
53
1
      throw Decoding_Error("EC_Scalar::from_bytes_mod_order input invalid");
54
1
   }
55
201
}
56
57
11.0k
EC_Scalar EC_Scalar::random(const EC_Group& group, RandomNumberGenerator& rng) {
58
11.0k
   return EC_Scalar(group._data()->scalar_random(rng));
59
11.0k
}
60
61
0
EC_Scalar EC_Scalar::one(const EC_Group& group) {
62
0
   return EC_Scalar(group._data()->scalar_one());
63
0
}
64
65
21.2k
EC_Scalar EC_Scalar::from_bigint(const EC_Group& group, const BigInt& bn) {
66
21.2k
   if(auto data = group._data()->scalar_from_bigint(bn)) {
67
21.2k
      return EC_Scalar(std::move(data));
68
21.2k
   } else {
69
0
      throw Invalid_Argument("EC_Scalar::from_bigint input out of range");
70
0
   }
71
21.2k
}
72
73
11.4k
BigInt EC_Scalar::to_bigint() const {
74
11.4k
   secure_vector<uint8_t> bytes(m_scalar->bytes());
75
11.4k
   m_scalar->serialize_to(bytes);
76
11.4k
   return BigInt::from_bytes(bytes);
77
11.4k
}
78
79
0
EC_Scalar EC_Scalar::gk_x_mod_order(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) {
80
0
   const auto& group = scalar._inner().group();
81
0
   return EC_Scalar(group->gk_x_mod_order(scalar.inner(), rng, ws));
82
0
}
83
84
0
void EC_Scalar::serialize_to(std::span<uint8_t> bytes) const {
85
0
   inner().serialize_to(bytes);
86
0
}
87
88
0
void EC_Scalar::serialize_pair_to(std::span<uint8_t> bytes, const EC_Scalar& r, const EC_Scalar& s) {
89
0
   BOTAN_ARG_CHECK(r._inner().group() == s._inner().group(), "Curve mismatch");
90
0
   const size_t scalar_bytes = r.bytes();
91
0
   BOTAN_ARG_CHECK(bytes.size() == 2 * scalar_bytes, "Invalid output length");
92
0
   r.serialize_to(bytes.first(scalar_bytes));
93
0
   s.serialize_to(bytes.last(scalar_bytes));
94
0
}
95
96
std::optional<std::pair<EC_Scalar, EC_Scalar>> EC_Scalar::deserialize_pair(const EC_Group& group,
97
759
                                                                           std::span<const uint8_t> bytes) {
98
759
   if(bytes.size() % 2 != 0) {
99
1
      return {};
100
1
   }
101
102
758
   const size_t half = bytes.size() / 2;
103
104
758
   auto r = EC_Scalar::deserialize(group, bytes.first(half));
105
758
   auto s = EC_Scalar::deserialize(group, bytes.last(half));
106
107
758
   if(r && s) {
108
548
      return std::make_pair(r.value(), s.value());
109
548
   } else {
110
210
      return {};
111
210
   }
112
758
}
113
114
1.51k
std::optional<EC_Scalar> EC_Scalar::deserialize(const EC_Group& group, std::span<const uint8_t> bytes) {
115
1.51k
   if(auto v = group._data()->scalar_deserialize(bytes)) {
116
1.13k
      return EC_Scalar(std::move(v));
117
1.13k
   } else {
118
386
      return {};
119
386
   }
120
1.51k
}
121
122
509
EC_Scalar::EC_Scalar(const EC_Group& group, std::span<const uint8_t> bytes) {
123
509
   m_scalar = group._data()->scalar_deserialize(bytes);
124
509
   if(!m_scalar) {
125
105
      throw Decoding_Error("EC_Scalar::from_bytes is not a valid scalar value");
126
105
   }
127
509
}
128
129
1.29k
bool EC_Scalar::is_zero() const {
130
1.29k
   return inner().is_zero();
131
1.29k
}
132
133
547
EC_Scalar EC_Scalar::invert() const {
134
547
   return EC_Scalar(inner().invert());
135
547
}
136
137
200
EC_Scalar EC_Scalar::negate() const {
138
200
   return EC_Scalar(inner().negate());
139
200
}
140
141
0
void EC_Scalar::square_self() {
142
0
   m_scalar->square_self();
143
0
}
144
145
0
EC_Scalar EC_Scalar::add(const EC_Scalar& x) const {
146
0
   return EC_Scalar(inner().add(x.inner()));
147
0
}
148
149
0
EC_Scalar EC_Scalar::sub(const EC_Scalar& x) const {
150
0
   return EC_Scalar(inner().sub(x.inner()));
151
0
}
152
153
1.09k
EC_Scalar EC_Scalar::mul(const EC_Scalar& x) const {
154
1.09k
   return EC_Scalar(inner().mul(x.inner()));
155
1.09k
}
156
157
0
void EC_Scalar::assign(const EC_Scalar& x) {
158
0
   m_scalar->assign(x.inner());
159
0
}
160
161
0
bool EC_Scalar::is_eq(const EC_Scalar& x) const {
162
0
   return inner().is_eq(x.inner());
163
0
}
164
165
}  // namespace Botan