Botan 3.13.0
Crypto and TLS for C&
Botan::EC_Scalar Class Referencefinal

#include <ec_scalar.h>

Public Member Functions

const EC_Scalar_Data_inner () const
EC_Scalar add (const EC_Scalar &x) const
void assign (const EC_Scalar &x)
size_t bytes () const
 EC_Scalar (const EC_Group &group, std::span< const uint8_t > bytes)
 EC_Scalar (const EC_Scalar &other)
 EC_Scalar (EC_Scalar &&other) noexcept
EC_Scalar invert () const
EC_Scalar invert_vartime () const
bool is_eq (const EC_Scalar &x) const
bool is_nonzero () const
bool is_zero () const
EC_Scalar mul (const EC_Scalar &x) const
EC_Scalar negate () const
EC_Scalaroperator= (const EC_Scalar &other)
EC_Scalaroperator= (EC_Scalar &&other) noexcept
template<concepts::resizable_byte_buffer T = std::vector<uint8_t>>
serialize () const
void serialize_to (std::span< uint8_t > bytes) const
void square_self ()
EC_Scalar sub (const EC_Scalar &x) const
BigInt to_bigint () const
void zeroize ()
 ~EC_Scalar ()

Static Public Member Functions

static EC_Scalar _from_inner (std::unique_ptr< EC_Scalar_Data > inner)
static std::optional< EC_Scalardeserialize (const EC_Group &group, std::span< const uint8_t > bytes)
static std::optional< std::pair< EC_Scalar, EC_Scalar > > deserialize_pair (const EC_Group &group, std::span< const uint8_t > bytes)
static EC_Scalar from_bigint (const EC_Group &group, const BigInt &bn)
static EC_Scalar from_bytes_mod_order (const EC_Group &group, std::span< const uint8_t > bytes)
static EC_Scalar from_bytes_with_trunc (const EC_Group &group, std::span< const uint8_t > bytes)
static EC_Scalar gk_x_mod_order (const EC_Scalar &scalar, RandomNumberGenerator &rng)
static EC_Scalar gk_x_mod_order (const EC_Scalar &scalar, RandomNumberGenerator &rng, std::vector< BigInt > &)
static EC_Scalar hash (const EC_Group &group, std::string_view hash_fn, std::span< const uint8_t > input, std::span< const uint8_t > domain_sep)
static EC_Scalar one (const EC_Group &group)
static EC_Scalar random (const EC_Group &group, RandomNumberGenerator &rng)
template<concepts::resizable_byte_buffer T = std::vector<uint8_t>>
static T serialize_pair (const EC_Scalar &r, const EC_Scalar &s)
static void serialize_pair_to (std::span< uint8_t > bytes, const EC_Scalar &r, const EC_Scalar &s)

Friends

class EC_AffinePoint
EC_Scalar operator* (const EC_Scalar &x, const EC_Scalar &y)
EC_Scalar operator+ (const EC_Scalar &x, const EC_Scalar &y)
EC_Scalar operator- (const EC_Scalar &x, const EC_Scalar &y)
bool operator== (const EC_Scalar &x, const EC_Scalar &y)

Detailed Description

Represents an integer modulo the prime group order of an elliptic curve

Definition at line 28 of file ec_scalar.h.

Constructor & Destructor Documentation

◆ EC_Scalar() [1/3]

Botan::EC_Scalar::EC_Scalar ( const EC_Group & group,
std::span< const uint8_t > bytes )

Convert a bytestring to an EC_Scalar

This is similar to deserialize but instead of returning nullopt if the input is invalid, it will throw an exception.

Definition at line 130 of file ec_scalar.cpp.

130 {
131 m_scalar = group._data()->scalar_deserialize(bytes);
132 if(!m_scalar) {
133 throw Decoding_Error("EC_Scalar::from_bytes is not a valid scalar value");
134 }
135}
size_t bytes() const
Definition ec_scalar.cpp:48

References Botan::EC_Group::_data(), and bytes().

Referenced by _from_inner(), add(), assign(), deserialize(), EC_AffinePoint, EC_Scalar(), EC_Scalar(), from_bigint(), from_bytes_mod_order(), from_bytes_with_trunc(), gk_x_mod_order(), gk_x_mod_order(), hash(), invert(), invert_vartime(), is_eq(), mul(), negate(), one(), operator*, operator+, operator-, operator=(), operator=(), operator==, random(), serialize_pair(), serialize_pair_to(), and sub().

◆ EC_Scalar() [2/3]

Botan::EC_Scalar::EC_Scalar ( const EC_Scalar & other)

Copy constructor

Parameters
otherthe scalar to copy

Definition at line 23 of file ec_scalar.cpp.

23: m_scalar(other.inner().clone()) {}

References EC_Scalar().

◆ EC_Scalar() [3/3]

Botan::EC_Scalar::EC_Scalar ( EC_Scalar && other)
noexcept

Move constructor

Parameters
otherthe scalar to move from

Definition at line 25 of file ec_scalar.cpp.

25: m_scalar(std::move(other.m_scalar)) {}

References EC_Scalar().

◆ ~EC_Scalar()

Botan::EC_Scalar::~EC_Scalar ( )
default

Member Function Documentation

◆ _from_inner()

EC_Scalar Botan::EC_Scalar::_from_inner ( std::unique_ptr< EC_Scalar_Data > inner)
static

For internal use only

Parameters
innerthe inner representation to wrap
Returns
a scalar wrapping the provided inner representation

Definition at line 15 of file ec_scalar.cpp.

15 {
16 return EC_Scalar(std::move(inner));
17}
EC_Scalar(const EC_Group &group, std::span< const uint8_t > bytes)

References EC_Scalar().

◆ _inner()

const EC_Scalar_Data & Botan::EC_Scalar::_inner ( ) const
inline

◆ add()

EC_Scalar Botan::EC_Scalar::add ( const EC_Scalar & x) const

Scalar addition (modulo group order)

Definition at line 157 of file ec_scalar.cpp.

157 {
158 BOTAN_ARG_CHECK(inner().group() == x.inner().group(), "Curve mismatch");
159 return EC_Scalar(inner().add(x.inner()));
160}
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
EC_Scalar add(const EC_Scalar &x) const

References add(), BOTAN_ARG_CHECK, EC_Scalar(), and Botan::EC_Scalar_Data::group().

Referenced by add(), and operator+.

◆ assign()

void Botan::EC_Scalar::assign ( const EC_Scalar & x)

Assign a scalar

Definition at line 172 of file ec_scalar.cpp.

172 {
173 if(this != &x) {
174 if(m_scalar == nullptr || m_scalar->group() != x.inner().group()) {
175 m_scalar = x.inner().clone();
176 } else {
177 m_scalar->assign(x.inner());
178 }
179 }
180}

References Botan::EC_Scalar_Data::clone(), EC_Scalar(), and Botan::EC_Scalar_Data::group().

Referenced by operator=().

◆ bytes()

size_t Botan::EC_Scalar::bytes ( ) const

Return the byte size of this scalar

Definition at line 48 of file ec_scalar.cpp.

48 {
49 return m_scalar->bytes();
50}

References bytes().

Referenced by bytes(), deserialize(), deserialize_pair(), EC_Scalar(), from_bytes_mod_order(), from_bytes_with_trunc(), serialize_pair(), serialize_pair_to(), serialize_to(), and to_bigint().

◆ deserialize()

std::optional< EC_Scalar > Botan::EC_Scalar::deserialize ( const EC_Group & group,
std::span< const uint8_t > bytes )
static

Deserialize a scalar

The span must be exactly bytes() long; this function does not accept either short inputs (eg [1] to encode the integer 1) or inputs with excess leading zero bytes.

Returns nullopt if the length is incorrect or if the integer is not within the range [0,n) where n is the group order.

Definition at line 122 of file ec_scalar.cpp.

122 {
123 if(auto v = group._data()->scalar_deserialize(bytes)) {
124 return EC_Scalar(std::move(v));
125 } else {
126 return {};
127 }
128}

References Botan::EC_Group::_data(), bytes(), and EC_Scalar().

Referenced by Botan::SPAKE2p::RegistrationRecord::deserialize(), and deserialize_pair().

◆ deserialize_pair()

std::optional< std::pair< EC_Scalar, EC_Scalar > > Botan::EC_Scalar::deserialize_pair ( const EC_Group & group,
std::span< const uint8_t > bytes )
static

Deserialize a pair of scalars

Returns nullopt if the length is not 2*bytes(), or if either scalar is out of range or zero

Definition at line 104 of file ec_scalar.cpp.

105 {
106 if(bytes.size() % 2 != 0) {
107 return {};
108 }
109
110 const size_t half = bytes.size() / 2;
111
112 auto r = EC_Scalar::deserialize(group, bytes.first(half));
113 auto s = EC_Scalar::deserialize(group, bytes.last(half));
114
115 if(r && s) {
116 return std::make_pair(r.value(), s.value());
117 } else {
118 return {};
119 }
120}
static std::optional< EC_Scalar > deserialize(const EC_Group &group, std::span< const uint8_t > bytes)

References bytes(), and deserialize().

Referenced by Botan::SPAKE2p::ProverSecret::deserialize().

◆ from_bigint()

EC_Scalar Botan::EC_Scalar::from_bigint ( const EC_Group & group,
const BigInt & bn )
static

Convert from the argument BigInt to a EC_Scalar

Throws an exception if the provided bn is negative or too large

Definition at line 72 of file ec_scalar.cpp.

72 {
73 if(auto data = group._data()->scalar_from_bigint(bn)) {
74 return EC_Scalar(std::move(data));
75 } else {
76 throw Invalid_Argument("EC_Scalar::from_bigint input out of range");
77 }
78}

References Botan::EC_Group::_data(), and EC_Scalar().

Referenced by botan_ec_scalar_from_mp(), Botan::EC_Group::cube_mod_order(), Botan::ECIES_KA_Operation::derive_secret(), Botan::EC_PrivateKey::EC_PrivateKey(), Botan::EC_Group::inverse_mod_order(), Botan::EC_Group::multiply_mod_order(), Botan::EC_Group::multiply_mod_order(), and Botan::EC_Group::square_mod_order().

◆ from_bytes_mod_order()

EC_Scalar Botan::EC_Scalar::from_bytes_mod_order ( const EC_Group & group,
std::span< const uint8_t > bytes )
static

Convert a bytestring to an EC_Scalar

This reduces the bytes modulo the group order. The input can be at most 2*bytes() long

Definition at line 56 of file ec_scalar.cpp.

56 {
57 if(auto s = group._data()->scalar_from_bytes_mod_order(bytes)) {
58 return EC_Scalar(std::move(s));
59 } else {
60 throw Decoding_Error("EC_Scalar::from_bytes_mod_order input invalid");
61 }
62}

References Botan::EC_Group::_data(), bytes(), and EC_Scalar().

Referenced by hash(), and Botan::EC_Group::mod_order().

◆ from_bytes_with_trunc()

EC_Scalar Botan::EC_Scalar::from_bytes_with_trunc ( const EC_Group & group,
std::span< const uint8_t > bytes )
static

Convert a bytestring to an EC_Scalar

This uses the truncation rules from ECDSA

Definition at line 52 of file ec_scalar.cpp.

52 {
53 return EC_Scalar(group._data()->scalar_from_bytes_with_trunc(bytes));
54}

References Botan::EC_Group::_data(), bytes(), and EC_Scalar().

◆ gk_x_mod_order() [1/2]

EC_Scalar Botan::EC_Scalar::gk_x_mod_order ( const EC_Scalar & scalar,
RandomNumberGenerator & rng )
static

Compute the elliptic curve scalar multiplication (g*k) where g is the standard base point on the curve. Then extract the x coordinate of the resulting point, and reduce it modulo the group order.

Definition at line 87 of file ec_scalar.cpp.

87 {
88 const auto& group = scalar._inner().group();
89 return EC_Scalar(group->gk_x_mod_order(scalar.inner(), rng));
90}

References _inner(), EC_Scalar(), and Botan::EC_Scalar_Data::group().

Referenced by gk_x_mod_order().

◆ gk_x_mod_order() [2/2]

EC_Scalar Botan::EC_Scalar::gk_x_mod_order ( const EC_Scalar & scalar,
RandomNumberGenerator & rng,
std::vector< BigInt > &  )
inlinestatic

Compute the elliptic curve scalar multiplication (g*k) where g is the standard base point on the curve. Then extract the x coordinate of the resulting point, and reduce it modulo the group order.

Parameters
scalarthe scalar k to multiply the base point by
Random Number Generatorsa random number generator, used for blinding
Returns
the x coordinate of g*k reduced modulo the group order

Definition at line 119 of file ec_scalar.h.

119 {
120 return EC_Scalar::gk_x_mod_order(scalar, rng);
121 }
static EC_Scalar gk_x_mod_order(const EC_Scalar &scalar, RandomNumberGenerator &rng)
Definition ec_scalar.cpp:87

References EC_Scalar(), and gk_x_mod_order().

◆ hash()

EC_Scalar Botan::EC_Scalar::hash ( const EC_Group & group,
std::string_view hash_fn,
std::span< const uint8_t > input,
std::span< const uint8_t > domain_sep )
static

Hash to scalar following RFC 9380

This requires XMD. Unlike hash2curve, any group is supported

Definition at line 195 of file ec_scalar.cpp.

198 {
199 /*
200 RFC 9380 Section 5.2
201 L = ceil((ceil(log2(p)) + k) / 8), where k is the security
202 parameter of the suite (e.g., k = 128)
203 */
204 const size_t scalar_bits = group.get_order_bits();
205 const size_t security_level = std::min<size_t>((scalar_bits + 1) / 2, 256);
206 secure_vector<uint8_t> uniform_bytes((scalar_bits + security_level + 7) / 8);
207
208 h2c_expand_message(hash_fn, scalar_bits, input, domain_sep)(uniform_bytes);
209
210 return EC_Scalar::from_bytes_mod_order(group, uniform_bytes);
211}
static EC_Scalar from_bytes_mod_order(const EC_Group &group, std::span< const uint8_t > bytes)
Definition ec_scalar.cpp:56
std::function< void(std::span< uint8_t >)> h2c_expand_message(std::string_view hash_fn, size_t order_bits, std::span< const uint8_t > input, std::span< const uint8_t > domain_sep)
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128

References EC_Scalar(), from_bytes_mod_order(), Botan::EC_Group::get_order_bits(), and Botan::h2c_expand_message().

◆ invert()

EC_Scalar Botan::EC_Scalar::invert ( ) const

Constant time modular inversion

Return the modular inverse of this EC_Scalar

If *this is zero, then invert() returns zero

Definition at line 141 of file ec_scalar.cpp.

141 {
142 return EC_Scalar(inner().invert());
143}
EC_Scalar invert() const

References EC_Scalar(), and invert().

Referenced by invert().

◆ invert_vartime()

EC_Scalar Botan::EC_Scalar::invert_vartime ( ) const

Variable time modular inversion

Return the modular inverse of this EC_Scalar

If *this is zero, then invert_vartime() returns zero

Definition at line 145 of file ec_scalar.cpp.

145 {
146 return EC_Scalar(inner().invert_vartime());
147}
EC_Scalar invert_vartime() const

References EC_Scalar(), and invert_vartime().

Referenced by invert_vartime().

◆ is_eq()

bool Botan::EC_Scalar::is_eq ( const EC_Scalar & x) const

Test for equality

Definition at line 186 of file ec_scalar.cpp.

186 {
187 if(inner().group() != x.inner().group()) {
188 return false;
189 }
190
191 return inner().is_eq(x.inner());
192}

References EC_Scalar(), and Botan::EC_Scalar_Data::group().

Referenced by operator==.

◆ is_nonzero()

bool Botan::EC_Scalar::is_nonzero ( ) const
inline

Return true if this EC_Scalar is not zero

Definition at line 170 of file ec_scalar.h.

170{ return !is_zero(); }
bool is_zero() const

References is_zero().

◆ is_zero()

bool Botan::EC_Scalar::is_zero ( ) const

Return true if this EC_Scalar is zero

Definition at line 137 of file ec_scalar.cpp.

137 {
138 return inner().is_zero();
139}

Referenced by is_nonzero().

◆ mul()

EC_Scalar Botan::EC_Scalar::mul ( const EC_Scalar & x) const

Scalar multiplication (modulo group order)

Definition at line 167 of file ec_scalar.cpp.

167 {
168 BOTAN_ARG_CHECK(inner().group() == x.inner().group(), "Curve mismatch");
169 return EC_Scalar(inner().mul(x.inner()));
170}
EC_Scalar mul(const EC_Scalar &x) const

References BOTAN_ARG_CHECK, EC_Scalar(), Botan::EC_Scalar_Data::group(), and mul().

Referenced by mul(), and operator*.

◆ negate()

EC_Scalar Botan::EC_Scalar::negate ( ) const

Return the additive inverse of *this

Definition at line 149 of file ec_scalar.cpp.

149 {
150 return EC_Scalar(inner().negate());
151}
EC_Scalar negate() const

References EC_Scalar(), and negate().

Referenced by negate(), and Botan::EC_Group::verify_group().

◆ one()

EC_Scalar Botan::EC_Scalar::one ( const EC_Group & group)
static

Return the scalar value 1

Definition at line 68 of file ec_scalar.cpp.

68 {
69 return EC_Scalar(group._data()->scalar_one());
70}

References Botan::EC_Group::_data(), and EC_Scalar().

Referenced by Botan::EC_Group::verify_group().

◆ operator=() [1/2]

EC_Scalar & Botan::EC_Scalar::operator= ( const EC_Scalar & other)

Copy assignment

Parameters
otherthe scalar to copy
Returns
reference to this

Definition at line 27 of file ec_scalar.cpp.

27 {
28 if(this != &other) {
29 if(m_scalar == nullptr || m_scalar->group() != other.inner().group()) {
30 m_scalar = other.inner().clone();
31 } else {
32 this->assign(other);
33 }
34 }
35 return (*this);
36}
void assign(const EC_Scalar &x)

References assign(), Botan::EC_Scalar_Data::clone(), EC_Scalar(), and Botan::EC_Scalar_Data::group().

◆ operator=() [2/2]

EC_Scalar & Botan::EC_Scalar::operator= ( EC_Scalar && other)
noexcept

Move assignment

Parameters
otherthe scalar to move from
Returns
reference to this

Definition at line 38 of file ec_scalar.cpp.

38 {
39 if(this != &other) {
40 // Even a cross-curve swap is accepted here
41 std::swap(m_scalar, other.m_scalar);
42 }
43 return (*this);
44}

References EC_Scalar().

◆ random()

EC_Scalar Botan::EC_Scalar::random ( const EC_Group & group,
RandomNumberGenerator & rng )
static

◆ serialize()

template<concepts::resizable_byte_buffer T = std::vector<uint8_t>>
T Botan::EC_Scalar::serialize ( ) const
inline

Return the bytes of the encoded scalar in a container

Definition at line 139 of file ec_scalar.h.

139 {
140 T s(this->bytes());
141 this->serialize_to(s);
142 return s;
143 }
void serialize_to(std::span< uint8_t > bytes) const
Definition ec_scalar.cpp:92

References serialize_to().

◆ serialize_pair()

template<concepts::resizable_byte_buffer T = std::vector<uint8_t>>
T Botan::EC_Scalar::serialize_pair ( const EC_Scalar & r,
const EC_Scalar & s )
inlinestatic

Return the bytes of the encoded scalar in a container

Definition at line 156 of file ec_scalar.h.

156 {
157 T bytes(r.bytes() + s.bytes());
159 return bytes;
160 }
static void serialize_pair_to(std::span< uint8_t > bytes, const EC_Scalar &r, const EC_Scalar &s)
Definition ec_scalar.cpp:96

References bytes(), EC_Scalar(), and serialize_pair_to().

Referenced by Botan::SPAKE2p::ProverSecret::serialize().

◆ serialize_pair_to()

void Botan::EC_Scalar::serialize_pair_to ( std::span< uint8_t > bytes,
const EC_Scalar & r,
const EC_Scalar & s )
static

Write the fixed length serialization to bytes

The provided span must be exactly 2*bytes() long

Definition at line 96 of file ec_scalar.cpp.

96 {
97 BOTAN_ARG_CHECK(r._inner().group() == s._inner().group(), "Curve mismatch");
98 const size_t scalar_bytes = r.bytes();
99 BOTAN_ARG_CHECK(bytes.size() == 2 * scalar_bytes, "Invalid output length");
100 r.serialize_to(bytes.first(scalar_bytes));
101 s.serialize_to(bytes.last(scalar_bytes));
102}

References _inner(), BOTAN_ARG_CHECK, bytes(), EC_Scalar(), Botan::EC_Scalar_Data::group(), and serialize_to().

Referenced by serialize_pair().

◆ serialize_to()

void Botan::EC_Scalar::serialize_to ( std::span< uint8_t > bytes) const

Write the fixed length serialization to bytes

The provided span must be exactly bytes() long

Definition at line 92 of file ec_scalar.cpp.

92 {
93 inner().serialize_to(bytes);
94}

References bytes().

Referenced by serialize(), and serialize_pair_to().

◆ square_self()

void Botan::EC_Scalar::square_self ( )

Set *this to its own square modulo the group order

Definition at line 153 of file ec_scalar.cpp.

153 {
154 m_scalar->square_self();
155}

◆ sub()

EC_Scalar Botan::EC_Scalar::sub ( const EC_Scalar & x) const

Scalar subtraction (modulo group order)

Definition at line 162 of file ec_scalar.cpp.

162 {
163 BOTAN_ARG_CHECK(inner().group() == x.inner().group(), "Curve mismatch");
164 return EC_Scalar(inner().sub(x.inner()));
165}
EC_Scalar sub(const EC_Scalar &x) const

References BOTAN_ARG_CHECK, EC_Scalar(), Botan::EC_Scalar_Data::group(), and sub().

Referenced by operator-, and sub().

◆ to_bigint()

BigInt Botan::EC_Scalar::to_bigint ( ) const

Convert *this to a BigInt

Definition at line 80 of file ec_scalar.cpp.

80 {
81 secure_vector<uint8_t> bytes(m_scalar->bytes());
82 m_scalar->serialize_to(bytes);
84}
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83

References bytes(), and Botan::BigInt::from_bytes().

◆ zeroize()

void Botan::EC_Scalar::zeroize ( )

Equivalent to assigning a zero value, but also does so in a way that attempts to ensure the write always occurs even if a compiler can deduce the assignment is otherwise unnecessary.

Definition at line 182 of file ec_scalar.cpp.

182 {
183 m_scalar->zeroize();
184}

◆ EC_AffinePoint

friend class EC_AffinePoint
friend

Definition at line 287 of file ec_scalar.h.

References EC_AffinePoint, and EC_Scalar().

Referenced by EC_AffinePoint.

◆ operator*

EC_Scalar operator* ( const EC_Scalar & x,
const EC_Scalar & y )
friend

Definition at line 241 of file ec_scalar.h.

241{ return x.mul(y); }

References EC_Scalar(), and mul().

◆ operator+

EC_Scalar operator+ ( const EC_Scalar & x,
const EC_Scalar & y )
friend

Definition at line 237 of file ec_scalar.h.

237{ return x.add(y); }

References add(), and EC_Scalar().

◆ operator-

EC_Scalar operator- ( const EC_Scalar & x,
const EC_Scalar & y )
friend

Definition at line 239 of file ec_scalar.h.

239{ return x.sub(y); }

References EC_Scalar(), and sub().

◆ operator==

bool operator== ( const EC_Scalar & x,
const EC_Scalar & y )
friend

Definition at line 243 of file ec_scalar.h.

243{ return x.is_eq(y); }

References EC_Scalar(), and is_eq().


The documentation for this class was generated from the following files: