7#include <botan/ec_scalar.h>
9#include <botan/ec_group.h>
10#include <botan/internal/ec_inner_data.h>
12#if defined(BOTAN_HAS_XMD)
13 #include <botan/internal/xmd.h>
39 std::swap(m_scalar, other.m_scalar);
46 return m_scalar->
bytes();
54 if(
auto s = group.
_data()->scalar_from_bytes_mod_order(
bytes)) {
57 throw Decoding_Error(
"EC_Scalar::from_bytes_mod_order input invalid");
70 if(
auto data = group.
_data()->scalar_from_bigint(bn)) {
79 m_scalar->serialize_to(
bytes);
85 return EC_Scalar(group->gk_x_mod_order(scalar.inner(), rng));
89 inner().serialize_to(
bytes);
94 const size_t scalar_bytes = r.
bytes();
101 std::span<const uint8_t>
bytes) {
102 if(
bytes.size() % 2 != 0) {
106 const size_t half =
bytes.size() / 2;
112 return std::make_pair(r.value(), s.value());
119 if(
auto v = group.
_data()->scalar_deserialize(
bytes)) {
127 m_scalar = group.
_data()->scalar_deserialize(
bytes);
129 throw Decoding_Error(
"EC_Scalar::from_bytes is not a valid scalar value");
134 return inner().is_zero();
150 m_scalar->square_self();
166 m_scalar->assign(x.inner());
174 return inner().is_eq(x.inner());
179 std::string_view hash_fn,
180 std::span<const uint8_t> input,
181 std::span<const uint8_t> domain_sep) {
182#if defined(BOTAN_HAS_XMD)
187 if(hash_fn.starts_with(
"SHAKE")) {
188 throw Not_Implemented(
"Hash to scalar currently does not support expand_message_xof");
192 const size_t security_level = (scalar_bits + 1) / 2;
199 throw Not_Implemented(
"EC_Scalar::hash not available due to missing XMD");
#define BOTAN_ASSERT_NONNULL(ptr)
#define BOTAN_ARG_CHECK(expr, msg)
static BigInt from_bytes(std::span< const uint8_t > bytes)
const std::shared_ptr< EC_Group_Data > & _data() const
size_t get_order_bits() const
virtual const std::shared_ptr< const EC_Group_Data > & group() const =0
static EC_Scalar one(const EC_Group &group)
const EC_Scalar_Data & _inner() const
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)
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
static EC_Scalar gk_x_mod_order(const EC_Scalar &scalar, RandomNumberGenerator &rng)
void serialize_to(std::span< uint8_t > bytes) const
static EC_Scalar from_bigint(const EC_Group &group, const BigInt &bn)
EC_Scalar & operator=(const EC_Scalar &other)
EC_Scalar invert_vartime() const
static void serialize_pair_to(std::span< uint8_t > bytes, const EC_Scalar &r, const EC_Scalar &s)
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)
static EC_Scalar random(const EC_Group &group, RandomNumberGenerator &rng)
static EC_Scalar _from_inner(std::unique_ptr< EC_Scalar_Data > inner)
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)
static EC_Scalar from_bytes_with_trunc(const EC_Group &group, std::span< const uint8_t > bytes)
void expand_message_xmd(std::string_view hash_fn, std::span< uint8_t > output, std::span< const uint8_t > input, std::span< const uint8_t > domain_sep)
std::vector< T, secure_allocator< T > > secure_vector