Botan 3.6.1
Crypto and TLS for C&
ec_scalar.cpp
Go to the documentation of this file.
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
12namespace Botan {
13
14EC_Scalar EC_Scalar::_from_inner(std::unique_ptr<EC_Scalar_Data> inner) {
15 return EC_Scalar(std::move(inner));
16}
17
18EC_Scalar::EC_Scalar(std::unique_ptr<EC_Scalar_Data> scalar) : m_scalar(std::move(scalar)) {
19 BOTAN_ASSERT_NONNULL(m_scalar);
20}
21
22EC_Scalar::EC_Scalar(const EC_Scalar& other) : m_scalar(other.inner().clone()) {}
23
24EC_Scalar::EC_Scalar(EC_Scalar&& other) noexcept : m_scalar(std::move(other.m_scalar)) {}
25
27 if(this != &other) {
28 this->assign(other);
29 }
30 return (*this);
31}
32
34 BOTAN_ARG_CHECK(_inner().group() == other._inner().group(), "Curve mismatch");
35 std::swap(m_scalar, other.m_scalar);
36 return (*this);
37}
38
39EC_Scalar::~EC_Scalar() = default;
40
41size_t EC_Scalar::bytes() const {
42 return m_scalar->bytes();
43}
44
45EC_Scalar EC_Scalar::from_bytes_with_trunc(const EC_Group& group, std::span<const uint8_t> bytes) {
46 return EC_Scalar(group._data()->scalar_from_bytes_with_trunc(bytes));
47}
48
49EC_Scalar EC_Scalar::from_bytes_mod_order(const EC_Group& group, std::span<const uint8_t> bytes) {
50 if(auto s = group._data()->scalar_from_bytes_mod_order(bytes)) {
51 return EC_Scalar(std::move(s));
52 } else {
53 throw Decoding_Error("EC_Scalar::from_bytes_mod_order input invalid");
54 }
55}
56
58 return EC_Scalar(group._data()->scalar_random(rng));
59}
60
62 return EC_Scalar(group._data()->scalar_one());
63}
64
66 if(auto data = group._data()->scalar_from_bigint(bn)) {
67 return EC_Scalar(std::move(data));
68 } else {
69 throw Invalid_Argument("EC_Scalar::from_bigint input out of range");
70 }
71}
72
74 secure_vector<uint8_t> bytes(m_scalar->bytes());
75 m_scalar->serialize_to(bytes);
77}
78
79EC_Scalar EC_Scalar::gk_x_mod_order(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) {
80 const auto& group = scalar._inner().group();
81 return EC_Scalar(group->gk_x_mod_order(scalar.inner(), rng, ws));
82}
83
84void EC_Scalar::serialize_to(std::span<uint8_t> bytes) const {
85 inner().serialize_to(bytes);
86}
87
88void EC_Scalar::serialize_pair_to(std::span<uint8_t> bytes, const EC_Scalar& r, const EC_Scalar& s) {
89 BOTAN_ARG_CHECK(r._inner().group() == s._inner().group(), "Curve mismatch");
90 const size_t scalar_bytes = r.bytes();
91 BOTAN_ARG_CHECK(bytes.size() == 2 * scalar_bytes, "Invalid output length");
92 r.serialize_to(bytes.first(scalar_bytes));
93 s.serialize_to(bytes.last(scalar_bytes));
94}
95
96std::optional<std::pair<EC_Scalar, EC_Scalar>> EC_Scalar::deserialize_pair(const EC_Group& group,
97 std::span<const uint8_t> bytes) {
98 if(bytes.size() % 2 != 0) {
99 return {};
100 }
101
102 const size_t half = bytes.size() / 2;
103
104 auto r = EC_Scalar::deserialize(group, bytes.first(half));
105 auto s = EC_Scalar::deserialize(group, bytes.last(half));
106
107 if(r && s) {
108 return std::make_pair(r.value(), s.value());
109 } else {
110 return {};
111 }
112}
113
114std::optional<EC_Scalar> EC_Scalar::deserialize(const EC_Group& group, std::span<const uint8_t> bytes) {
115 if(auto v = group._data()->scalar_deserialize(bytes)) {
116 return EC_Scalar(std::move(v));
117 } else {
118 return {};
119 }
120}
121
122EC_Scalar::EC_Scalar(const EC_Group& group, std::span<const uint8_t> bytes) {
123 m_scalar = group._data()->scalar_deserialize(bytes);
124 if(!m_scalar) {
125 throw Decoding_Error("EC_Scalar::from_bytes is not a valid scalar value");
126 }
127}
128
129bool EC_Scalar::is_zero() const {
130 return inner().is_zero();
131}
132
134 return EC_Scalar(inner().invert());
135}
136
138 return EC_Scalar(inner().negate());
139}
140
142 m_scalar->square_self();
143}
144
146 return EC_Scalar(inner().add(x.inner()));
147}
148
150 return EC_Scalar(inner().sub(x.inner()));
151}
152
154 return EC_Scalar(inner().mul(x.inner()));
155}
156
158 m_scalar->assign(x.inner());
159}
160
161bool EC_Scalar::is_eq(const EC_Scalar& x) const {
162 return inner().is_eq(x.inner());
163}
164
165} // namespace Botan
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:95
const std::shared_ptr< EC_Group_Data > & _data() const
Definition ec_group.h:370
virtual const std::shared_ptr< const EC_Group_Data > & group() const =0
virtual void serialize_to(std::span< uint8_t > bytes) const =0
virtual bool is_eq(const EC_Scalar_Data &y) const =0
virtual bool is_zero() const =0
static EC_Scalar one(const EC_Group &group)
Definition ec_scalar.cpp:61
BigInt to_bigint() const
Definition ec_scalar.cpp:73
const EC_Scalar_Data & _inner() const
Definition ec_scalar.h:211
void assign(const EC_Scalar &x)
bool is_eq(const EC_Scalar &x) const
static std::optional< EC_Scalar > deserialize(const EC_Group &group, std::span< const uint8_t > bytes)
EC_Scalar mul(const EC_Scalar &x) const
EC_Scalar add(const EC_Scalar &x) const
void serialize_to(std::span< uint8_t > bytes) const
Definition ec_scalar.cpp:84
bool is_zero() const
size_t bytes() const
Definition ec_scalar.cpp:41
static EC_Scalar from_bigint(const EC_Group &group, const BigInt &bn)
Definition ec_scalar.cpp:65
EC_Scalar & operator=(const EC_Scalar &other)
Definition ec_scalar.cpp:26
EC_Scalar invert() const
static void serialize_pair_to(std::span< uint8_t > bytes, const EC_Scalar &r, const EC_Scalar &s)
Definition ec_scalar.cpp:88
EC_Scalar(const EC_Group &group, std::span< const uint8_t > bytes)
static EC_Scalar from_bytes_mod_order(const EC_Group &group, std::span< const uint8_t > bytes)
Definition ec_scalar.cpp:49
static EC_Scalar gk_x_mod_order(const EC_Scalar &scalar, RandomNumberGenerator &rng, std::vector< BigInt > &ws)
Definition ec_scalar.cpp:79
static EC_Scalar random(const EC_Group &group, RandomNumberGenerator &rng)
Definition ec_scalar.cpp:57
static EC_Scalar _from_inner(std::unique_ptr< EC_Scalar_Data > inner)
Definition ec_scalar.cpp:14
EC_Scalar negate() const
EC_Scalar sub(const EC_Scalar &x) const
static std::optional< std::pair< EC_Scalar, EC_Scalar > > deserialize_pair(const EC_Group &group, std::span< const uint8_t > bytes)
Definition ec_scalar.cpp:96
static EC_Scalar from_bytes_with_trunc(const EC_Group &group, std::span< const uint8_t > bytes)
Definition ec_scalar.cpp:45
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61