7#ifndef BOTAN_PCURVES_WRAP_H_
8#define BOTAN_PCURVES_WRAP_H_
10#include <botan/internal/pcurves.h>
11#include <botan/internal/pcurves_impl.h>
34 size_t order_bits()
const override {
return C::OrderBits; }
41 return stash(m_mul_by_g.
mul(from_stash(scalar), rng));
46 return stash(tbl.mul(from_stash(scalar), rng));
51 return std::make_unique<PrecomputedMul2TableC>(from_stash(x), from_stash(y));
56 const Scalar& s2)
const override {
60 if(pt.is_identity().as_bool()) {
65 }
catch(std::bad_cast&) {
72 const Scalar& s2)
const override {
77 if(pt.is_identity().as_bool()) {
80 std::array<uint8_t, C::FieldElement::BYTES> x_bytes;
81 pt.
to_affine().x().serialize_to(std::span{x_bytes});
82 return stash(C::Scalar::from_wide_bytes(std::span<const uint8_t, C::FieldElement::BYTES>{x_bytes}));
83 }
catch(std::bad_cast&) {
89 auto pt = m_mul_by_g.
mul(from_stash(scalar), rng);
90 std::array<uint8_t, C::FieldElement::BYTES> x_bytes;
91 pt.
to_affine().x().serialize_to(std::span{x_bytes});
92 return stash(C::Scalar::from_wide_bytes(std::span<const uint8_t, C::FieldElement::BYTES>{x_bytes}));
98 return stash(from_stash(pt).to_affine());
102 return stash(C::ProjectivePoint::from_affine(from_stash(pt)));
108 return stash(from_stash(a) + from_stash(b));
112 return stash(from_stash(a) + from_stash(b));
118 return from_stash(pt).is_identity().as_bool();
122 BOTAN_ARG_CHECK(bytes.size() == C::AffinePoint::BYTES,
"Invalid length for serialize_point");
123 from_stash(pt).serialize_to(bytes.subspan<0, C::AffinePoint::BYTES>());
128 "Invalid length for serialize_point_compressed");
129 from_stash(pt).serialize_compressed_to(bytes.subspan<0, C::AffinePoint::COMPRESSED_BYTES>());
133 BOTAN_ARG_CHECK(bytes.size() == C::FieldElement::BYTES,
"Invalid length for serialize_point_x");
134 from_stash(pt).x().serialize_to(bytes.subspan<0, C::FieldElement::BYTES>());
138 BOTAN_ARG_CHECK(bytes.size() == C::Scalar::BYTES,
"Invalid length to serialize_scalar");
139 return from_stash(scalar).serialize_to(bytes.subspan<0, C::Scalar::BYTES>());
143 if(
auto scalar = C::Scalar::deserialize(bytes)) {
144 if(!scalar->is_zero().as_bool()) {
145 return stash(*scalar);
153 return stash(C::Scalar::from_bits_with_trunc(bytes));
157 if(
auto s = C::Scalar::from_wide_bytes_varlen(bytes)) {
165 if(
auto pt = C::AffinePoint::deserialize(bytes)) {
173 std::span<const uint8_t> input,
174 std::span<const uint8_t> domain_sep,
175 bool random_oracle)
const override {
176 if constexpr(C::ValidForSswuHash) {
179 throw Not_Implemented(
"Hash to curve is not implemented for this curve");
184 return stash(from_stash(a) + from_stash(b));
188 return stash(from_stash(a) - from_stash(b));
192 return stash(from_stash(a) * from_stash(b));
204 return (from_stash(a) == from_stash(b)).as_bool();
217 static std::shared_ptr<const PrimeOrderCurve>
instance() {
218 static auto g_curve = std::make_shared<const PrimeOrderCurveImpl<C>>();
223 static Scalar stash(
const typename C::Scalar& s) {
224 return Scalar::_create(
instance(), s.template stash_value<StorageWords>());
227 static typename C::Scalar from_stash(
const Scalar& s) {
231 return C::Scalar::from_stash(s._value());
234 static AffinePoint stash(
const typename C::AffinePoint& pt) {
235 auto x_w = pt.x().template stash_value<StorageWords>();
236 auto y_w = pt.y().template stash_value<StorageWords>();
237 return AffinePoint::_create(
instance(), x_w, y_w);
240 static typename C::AffinePoint from_stash(
const AffinePoint& pt) {
242 throw Invalid_Argument(
"Curve mismatch");
244 auto x = C::FieldElement::from_stash(pt._x());
245 auto y = C::FieldElement::from_stash(pt._y());
246 return typename C::AffinePoint(x, y);
249 static ProjectivePoint stash(
const typename C::ProjectivePoint& pt) {
250 auto x_w = pt.x().template stash_value<StorageWords>();
251 auto y_w = pt.y().template stash_value<StorageWords>();
252 auto z_w = pt.z().template stash_value<StorageWords>();
253 return ProjectivePoint::_create(
instance(), x_w, y_w, z_w);
256 static typename C::ProjectivePoint from_stash(
const ProjectivePoint& pt) {
258 throw Invalid_Argument(
"Curve mismatch");
260 auto x = C::FieldElement::from_stash(pt._x());
261 auto y = C::FieldElement::from_stash(pt._y());
262 auto z = C::FieldElement::from_stash(pt._z());
263 return typename C::ProjectivePoint(x, y, z);
267 const PrecomputedBaseMulTable<C, 5> m_mul_by_g;
#define BOTAN_ARG_CHECK(expr, msg)
PrecomputedMul2TableC(const typename C::AffinePoint &x, const typename C::AffinePoint &y)
static constexpr size_t WindowBits
const WindowedMul2Table< C, WindowBits > & table() const
size_t field_element_bytes() const override
Scalar scalar_zero() const override
bool scalar_equal(const Scalar &a, const Scalar &b) const override
void serialize_scalar(std::span< uint8_t > bytes, const Scalar &scalar) const override
bool affine_point_is_identity(const AffinePoint &pt) const override
Scalar scalar_from_u32(uint32_t x) const override
ProjectivePoint hash_to_curve(std::string_view hash, std::span< const uint8_t > input, std::span< const uint8_t > domain_sep, bool random_oracle) const override
Scalar scalar_sub(const Scalar &a, const Scalar &b) const override
size_t order_bits() const override
Return the bit length of the group order.
void serialize_point_x(std::span< uint8_t > bytes, const AffinePoint &pt) const override
AffinePoint generator() const override
Return the standard generator.
ProjectivePoint mul_by_g(const Scalar &scalar, RandomNumberGenerator &rng) const override
Scalar scalar_from_bits_with_trunc(std::span< const uint8_t > bytes) const override
size_t scalar_bytes() const override
Return the byte length of the scalar element.
bool scalar_is_zero(const Scalar &s) const override
Scalar scalar_invert(const Scalar &s) const override
Scalar scalar_one() const override
ProjectivePoint point_negate(const ProjectivePoint &pt) const override
std::optional< Scalar > mul2_vartime_x_mod_order(const PrecomputedMul2Table &tableb, const Scalar &s1, const Scalar &s2) const override
static std::shared_ptr< const PrimeOrderCurve > instance()
std::optional< Scalar > scalar_from_wide_bytes(std::span< const uint8_t > bytes) const override
std::unique_ptr< const PrecomputedMul2Table > mul2_setup(const AffinePoint &x, const AffinePoint &y) const override
Setup a table for 2-ary multiplication.
Scalar base_point_mul_x_mod_order(const Scalar &scalar, RandomNumberGenerator &rng) const override
ProjectivePoint point_double(const ProjectivePoint &pt) const override
std::optional< Scalar > deserialize_scalar(std::span< const uint8_t > bytes) const override
Scalar scalar_add(const Scalar &a, const Scalar &b) const override
Scalar scalar_negate(const Scalar &s) const override
std::optional< ProjectivePoint > mul2_vartime(const PrecomputedMul2Table &tableb, const Scalar &s1, const Scalar &s2) const override
std::optional< AffinePoint > deserialize_point(std::span< const uint8_t > bytes) const override
Scalar random_scalar(RandomNumberGenerator &rng) const override
ProjectivePoint point_add(const ProjectivePoint &a, const ProjectivePoint &b) const override
void serialize_point(std::span< uint8_t > bytes, const AffinePoint &pt) const override
Scalar scalar_square(const Scalar &s) const override
ProjectivePoint point_to_projective(const AffinePoint &pt) const override
Scalar scalar_mul(const Scalar &a, const Scalar &b) const override
AffinePoint point_to_affine(const ProjectivePoint &pt) const override
ProjectivePoint point_add_mixed(const ProjectivePoint &a, const AffinePoint &b) const override
ProjectivePoint mul(const AffinePoint &pt, const Scalar &scalar, RandomNumberGenerator &rng) const override
void serialize_point_compressed(std::span< uint8_t > bytes, const AffinePoint &pt) const override
AffinePoint to_affine() const
static const size_t MaximumBitLength
ProjectivePoint mul(const Scalar &s, RandomNumberGenerator &rng) const
ProjectivePoint mul2_vartime(const Scalar &s1, const Scalar &s2) const
int(* final)(unsigned char *, CTX *)
auto hash_to_curve_sswu(std::string_view hash, bool random_oracle, std::span< const uint8_t > pw, std::span< const uint8_t > dst) -> typename C::ProjectivePoint
BigInt square(const BigInt &x)