7#ifndef BOTAN_PCURVES_IMPL_H_ 
    8#define BOTAN_PCURVES_IMPL_H_ 
   11#include <botan/internal/ct_utils.h> 
   12#include <botan/internal/loadstor.h> 
   13#include <botan/internal/pcurves_algos.h> 
   14#include <botan/internal/pcurves_mul.h> 
   15#include <botan/internal/pcurves_util.h> 
   16#include <botan/internal/stl_util.h> 
   58template <
typename Params>
 
   63      static constexpr auto P = Params::P;
 
   64      static constexpr size_t N = Params::N;
 
   65      typedef typename Params::W 
W;
 
   67      static_assert(
N > 0 && (Params::P[0] & 1) == 1, 
"Invalid Montgomery modulus");
 
   78      constexpr static std::array<W, N> 
one() { 
return R1; }
 
   83      constexpr static std::array<W, N> 
redc(
const std::array<W, 2 * N>& z) {
 
   84         if constexpr(
P_dash == 1) {
 
 
   94      constexpr static std::array<W, N> 
to_rep(
const std::array<W, N>& x) {
 
   95         std::array<W, 2 * N> z;  
 
 
  106      constexpr static std::array<W, N> 
wide_to_rep(
const std::array<W, 2 * N>& x) {
 
  108         std::array<W, 2 * N> z;  
 
 
  116      constexpr static std::array<W, N> 
from_rep(
const std::array<W, N>& z) {
 
  117         std::array<W, 2 * N> ze = {};
 
  118         copy_mem(std::span{ze}.template first<N>(), z);
 
 
 
  141template <
typename Rep>
 
  144      static constexpr auto P = Rep::P;
 
  145      static constexpr size_t N = Rep::N;
 
  146      typedef typename Rep::W W;
 
  148      static constexpr auto P_MINUS_2 = 
p_minus<2>(P);
 
  191         if constexpr(L == N) {
 
  192            return Self(Rep::to_rep(w));
 
  194            static_assert(L < N);
 
  195            std::array<W, N> ew = {};
 
  196            copy_mem(std::span{ew}.template first<L>(), w);
 
  197            return Self(Rep::to_rep(ew));
 
 
  220         auto v = Rep::from_rep(m_val);
 
 
  228         const auto flip = (even != this->
is_even());
 
 
  248         for(
size_t i = 0; i != N; ++i) {
 
 
  263         for(
size_t i = 0; i != N; ++i) {
 
 
  281         std::array<W, N> t = value();
 
 
  292         std::array<W, N> t = value();
 
 
  313         std::array<W, 2 * N> z;  
 
  315         return Self(Rep::redc(z));
 
 
  322         std::array<W, 2 * N> z;  
 
  324         m_val = Rep::redc(z);
 
 
  336         for(
size_t i = 0; i != N; ++i) {
 
 
  349         for(
size_t i = 0; i != N; ++i) {
 
 
  364         for(
size_t i = 0; i != N; ++i) {
 
 
  379         for(
size_t i = 0; i != N; ++i) {
 
 
  393         std::array<W, 2 * N> z;  
 
  395         return Self(Rep::redc(z));
 
 
  406         std::array<W, 2 * N> z;  
 
  407         for(
size_t i = 0; i != n; ++i) {
 
  409            m_val = Rep::redc(z);
 
 
  419         const W x_is_zero = 
~CT::all_zeros(this->data(), N).value();
 
  423         for(
size_t i = 0; i != N; ++i) {
 
 
  444         constexpr size_t WindowBits = (
Self::BITS <= 256) ? 4 : 5;
 
  445         constexpr size_t WindowElements = (1 << WindowBits) - 1;
 
  447         constexpr size_t Windows = (
Self::BITS + WindowBits - 1) / WindowBits;
 
  455         std::array<Self, WindowElements> tbl;
 
  459         for(
size_t i = 1; i != WindowElements; ++i) {
 
  462               tbl[i] = tbl[i / 2].square();
 
  464               tbl[i] = tbl[i - 1] * tbl[0];
 
  477         for(
size_t i = 1; i != Windows; ++i) {
 
  478            r.square_n(WindowBits);
 
 
  517         while((a.m_val[0] & 1) != 1) {
 
 
  566         if(this->
is_zero().as_bool()) {
 
  570         auto x = 
Self(std::array<W, N>{1});  
 
  585            if(a.m_val == b.m_val) {
 
  590               r.m_val = Rep::to_rep(r.m_val);
 
 
  637            const CT::Choice correct = (z.square() == *
this);
 
  657            const Self& x = (*this);
 
  666            for(
size_t i = C1_C2.first; i >= 2; i--) {
 
  669               z.conditional_assign(!e, z * c);
 
  671               t.conditional_assign(!e, t * c);
 
  676            const CT::Choice correct = (z.square() == *
this);
 
 
  689         return CT::is_equal(this->data(), other.data(), N).as_choice();
 
 
  700      constexpr std::array<W, Self::N> 
to_words()
 const { 
return Rep::from_rep(m_val); }
 
  705      constexpr void serialize_to(std::span<uint8_t, Self::BYTES> bytes)
 const {
 
  706         auto v = Rep::from_rep(m_val);
 
  707         std::reverse(v.begin(), v.end());
 
  713            const auto padded_bytes = 
store_be(v);
 
  715            copy_mem(bytes, std::span{padded_bytes}.template subspan<extra, Self::BYTES>());
 
 
  726         static_assert(L >= N);
 
  727         std::array<W, L> stash = {};
 
  728         for(
size_t i = 0; i != N; ++i) {
 
 
  741         static_assert(L >= N);
 
  742         std::array<W, N> val = {};
 
  743         for(
size_t i = 0; i != N; ++i) {
 
 
  758      static std::optional<Self> 
deserialize(std::span<const uint8_t> bytes) {
 
 
  784         std::array<uint8_t, 2 * BYTES> padded_bytes = {};
 
  785         copy_mem(std::span{padded_bytes}.template last<L>(), bytes);
 
 
  801         std::array<uint8_t, 2 * Self::BYTES> padded_bytes = {};
 
  802         copy_mem(std::span{padded_bytes}.last(bytes.size()), bytes);
 
 
  818         constexpr size_t MAX_ATTEMPTS = 1000;
 
  820         std::array<uint8_t, Self::BYTES> buf{};
 
  822         for(
size_t i = 0; i != MAX_ATTEMPTS; ++i) {
 
  828               constexpr uint8_t mask = 0xFF >> (8 - (
Self::BITS % 8));
 
  834               if(s.value().is_nonzero().as_bool()) {
 
  840         throw Internal_Error(
"Failed to generate random Scalar within bounded number of attempts");
 
 
  849         std::array<W, 1> v{};
 
  850         v[0] = (x >= 0) ? x : -x;
 
  852         return (x >= 0) ? s : s.negate();
 
 
  860      constexpr const std::array<W, N>& value()
 const { 
return m_val; }
 
  862      constexpr const W* data()
 const { 
return m_val.data(); }
 
  864      explicit constexpr IntMod(std::array<W, N> v) : m_val(v) {}
 
  866      std::array<W, N> m_val;
 
 
  874template <
typename FieldElement, 
typename Params>
 
  877      static constexpr size_t BYTES = 1 + 2 * FieldElement::BYTES;
 
  887      static constexpr Self identity() { 
return Self(FieldElement::zero(), FieldElement::zero()); }
 
  891         return Self(FieldElement::zero(), FieldElement::zero());
 
 
  907      constexpr void serialize_to(std::span<uint8_t, Self::BYTES> bytes)
 const {
 
  911         x().serialize_to(pack.next<FieldElement::BYTES>());
 
  912         y().serialize_to(pack.next<FieldElement::BYTES>());
 
 
  921      static constexpr auto ct_select(std::span<const Self> pts, 
size_t idx) {
 
  925         const size_t idx1 = 
static_cast<size_t>(idx - 1);
 
  926         for(
size_t i = 0; i != pts.size(); ++i) {
 
  928            result.conditional_assign(found, pts[i]);
 
 
  937      constexpr const FieldElement& 
x()
 const { 
return m_x; }
 
  942      constexpr const FieldElement& 
y()
 const { 
return m_y; }
 
  948         FieldElement::conditional_assign(m_x, m_y, cond, pt.
x(), pt.
y());
 
 
 
  965template <
typename FieldElement, 
typename Params>
 
  971      static constexpr FieldElement 
A = FieldElement::from_words(Params::AW);
 
  974      static constexpr bool A_is_minus_3 = (
A == FieldElement::constant(-3)).as_bool();
 
  994         auto z = FieldElement::one();
 
 
 1004      static constexpr Self identity() { 
return Self(FieldElement::zero(), FieldElement::one(), FieldElement::zero()); }
 
 1010            m_x(FieldElement::zero()), m_y(FieldElement::one()), m_z(FieldElement::zero()) {}
 
 
 1016            m_x(
x), m_y(
y), m_z(FieldElement::one()) {}
 
 
 1022            m_x(
x), m_y(
y), m_z(
z) {}
 
 
 1037         (*this) = (*this) + other;
 
 
 1042         (*this) = (*this) + other;
 
 
 1051         FieldElement::conditional_assign(m_x, m_y, m_z, cond, pt.
x(), pt.
y(), pt.
z());
 
 
 1114            auto r = FieldElement::random(rng);
 
 1116            auto r2 = r.square();
 
 
 1128      constexpr const FieldElement& 
x()
 const { 
return m_x; }
 
 1133      constexpr const FieldElement& 
y()
 const { 
return m_y; }
 
 1138      constexpr const FieldElement& 
z()
 const { 
return m_z; }
 
 
 1156template <StringLiteral PS,
 
 1174      static constexpr int8_t 
Z = ZI;
 
 
 1180template <WordType WI, 
size_t NI, std::array<WI, NI> PI>
 
 1184      static constexpr size_t N = NI;
 
 1185      static constexpr auto P = PI;
 
 
 1193template <
typename Params, 
template <
typename FieldParamsT> 
typename FieldRep = 
MontgomeryRep>
 
 1196      typedef typename Params::W 
W;
 
 1200      static constexpr auto PW = Params::PW;
 
 1201      static constexpr auto NW = Params::NW;
 
 1202      static constexpr auto AW = Params::AW;
 
 1205      static_assert(
PW.size() == 
NW.size());
 
 1226      static_assert(
B.is_nonzero().as_bool(), 
"B must be non-zero");
 
 
 1258template <
typename C, 
size_t WindowBits>
 
 1261      typedef typename C::W W;
 
 1263      static constexpr bool BlindingEnabled = 
true;
 
 1272      static constexpr size_t blinding_bits(
size_t sb) {
 
 1275         static_assert(wb == 32 || wb == 64, 
"Unexpected W size");
 
 1283            return blinding_bits(512);
 
 1286            return ((sb / 4 + wb - 1) / wb) * wb;
 
 1290      static constexpr size_t BlindingBits = blinding_bits(C::OrderBits);
 
 1293      static_assert(BlindingBits < C::Scalar::BITS);
 
 1296      static constexpr size_t Bits = C::Scalar::BITS + (BlindingEnabled ? BlindingBits : 0);
 
 1302         if constexpr(BlindingEnabled) {
 
 1306            constexpr size_t n_words = C::Words;
 
 1308            uint8_t maskb[mask_bytes] = {0};
 
 1319               std::array<uint8_t, C::Scalar::BYTES> sbytes = {};
 
 1320               scalar.serialize_to(sbytes);
 
 1321               for(
size_t i = 0; i != sbytes.size(); ++i) {
 
 1322                  maskb[i % mask_bytes] ^= sbytes[i];
 
 1326            W mask[n_words] = {0};
 
 1327            load_le(mask, maskb, mask_words);
 
 1331            W mask_n[2 * n_words] = {0};
 
 1333            const auto sw = scalar.to_words();
 
 1337            bigint_add2(mask_n, 2 * n_words, sw.data(), sw.size());
 
 1339            std::reverse(mask_n, mask_n + 2 * n_words);
 
 1342            static_assert(
Bytes == C::Scalar::BYTES);
 
 1343            m_bytes.resize(
Bytes);
 
 1344            scalar.serialize_to(std::span{m_bytes}.template first<Bytes>());
 
 
 1367      std::vector<uint8_t> m_bytes;
 
 
 1370template <
typename C, 
size_t WindowBits>
 
 1373      static constexpr size_t Bits = C::Scalar::BITS;
 
 1383      std::array<uint8_t, C::Scalar::BYTES> m_bytes;
 
 
 1386template <
typename C, 
size_t W>
 
 1409      std::vector<AffinePoint> m_table;
 
 
 1417template <
typename C, 
size_t W>
 
 1444      std::vector<AffinePoint> m_table;
 
 
 1450template <
typename C, 
size_t W>
 
 1466            return (sb - 1) / wb;
 
 
 1478            return sb - (sb / wb) * wb;
 
 
 1495         auto accum = ProjectivePoint::identity();
 
 1502            const auto [tidx, tneg] = booth_recode<WindowBits>(w_i);
 
 1506               accum = ProjectivePoint::from_affine(m_table.ct_select(tidx));
 
 1507               accum.conditional_assign(tneg, accum.negate());
 
 1509               accum = ProjectivePoint::add_or_sub(accum, m_table.ct_select(tidx), tneg);
 
 1516               accum.randomize_rep(rng);
 
 1522         const auto [tidx, tneg] = booth_recode<WindowBits>(w_l << 1);
 
 1523         accum = ProjectivePoint::add_or_sub(accum, m_table.ct_select(tidx), tneg);
 
 
 1530      template <
size_t B, std::
unsigned_
integral T>
 
 1531      static constexpr std::pair<size_t, CT::Choice> booth_recode(T x) {
 
 1532         static_assert(B < 
sizeof(T) * 8 - 2, 
"Invalid B");
 
 1535         const T neg_x = (1 << (B + 1)) - x - 1;
 
 1536         T d = s_mask.select(neg_x, x);
 
 1537         d = (d >> 1) + (d & 1);
 
 1539         return std::make_pair(
static_cast<size_t>(d), s_mask.as_choice());
 
 1542      AffinePointTable<C> m_table;
 
 
 1545template <
typename C, 
size_t W>
 
 1549      static_assert(W >= 1 && W <= 4);
 
 1562         BlindedScalar bits1(s1, rng);
 
 1563         BlindedScalar bits2(s2, rng);
 
 
 
 1572template <
typename C, 
size_t W>
 
 1576      static_assert(W >= 1 && W <= 4);
 
 1602         bool s1_is_zero = s1.is_zero().as_bool();
 
 1603         bool s2_is_zero = s2.is_zero().as_bool();
 
 1606         if(s1_is_zero && s2_is_zero) {
 
 1607            return ProjectivePoint::identity();
 
 1610         auto [w_0, first_nonempty_window] = [&]() {
 
 1611            for(
size_t i = 0; i != Windows; ++i) {
 
 1614               const size_t window = w_1 + (w_2 << 
WindowBits);
 
 1617                  return std::make_pair(window, i);
 
 1625         auto accum = ProjectivePoint::from_affine(m_table[w_0 - 1]);
 
 1627         for(
size_t i = first_nonempty_window + 1; i < Windows; ++i) {
 
 1633            const size_t window = w_1 + (w_2 << 
WindowBits);
 
 1637               accum += m_table[window - 1];
 
 
 1645      std::vector<AffinePoint> m_table;
 
 
 1653template <
typename C>
 
 1655   requires C::ValidForSswuHash
 
 
 1667template <
typename C>
 
 1669   requires C::ValidForSswuHash
 
 1673   static const typename C::FieldElement C1 = (
SSWU_C2<C>() * C::SSWU_Z).negate();
 
 
 1682template <
typename C>
 
 1685   const auto z_u2 = C::SSWU_Z * u.square();  
 
 1686   const auto z2_u4 = z_u2.square();
 
 1688   auto x1 = 
SSWU_C1<C>() * (C::FieldElement::one() + tv1);
 
 1689   x1.conditional_assign(tv1.is_zero(), 
SSWU_C2<C>());
 
 1690   const auto x2 = z_u2 * x1;
 
 1698   auto x = C::FieldElement::choose(use_y1, x1, x2);
 
 1699   auto y = C::FieldElement::choose(use_y1, y1.
value_or(C::FieldElement::zero()), y2.
value_or(C::FieldElement::zero()));
 
 1701   auto pt = 
typename C::AffinePoint(x, y.correct_sign(u.is_even()));
 
 
 1718template <
typename C, 
bool RO, std::invocable<std::span<u
int8_t>> ExpandMsg>
 
 1719   requires C::ValidForSswuHash
 
 1721   -> std::conditional_t<RO, typename C::ProjectivePoint, typename C::AffinePoint> {
 
 1722   constexpr size_t SecurityLevel = (C::OrderBits + 1) / 2;
 
 1723   constexpr size_t L = (C::PrimeFieldBits + SecurityLevel + 7) / 8;
 
 1724   constexpr size_t Cnt = RO ? 2 : 1;
 
 1726   std::array<uint8_t, L * Cnt> uniform_bytes = {};
 
 1727   expand_message(uniform_bytes);
 
 1730      const auto u0 = C::FieldElement::from_wide_bytes(std::span<const uint8_t, L>(uniform_bytes.data(), L));
 
 1731      const auto u1 = C::FieldElement::from_wide_bytes(std::span<const uint8_t, L>(uniform_bytes.data() + L, L));
 
 1737      const auto u = C::FieldElement::from_wide_bytes(std::span<const uint8_t, L>(uniform_bytes.data(), L));
 
 
#define BOTAN_ASSERT_NOMSG(expr)
 
#define BOTAN_DEBUG_ASSERT(expr)
 
#define BOTAN_STATE_CHECK(expr)
 
#define BOTAN_ASSERT_UNREACHABLE()
 
constexpr const FieldElement & y() const
 
static constexpr size_t BYTES
 
AffineCurvePoint & operator=(const Self &other)=default
 
static constexpr Self identity(const Self &)
 
static constexpr Self identity()
 
constexpr const FieldElement & x() const
 
constexpr AffineCurvePoint(const FieldElement &x, const FieldElement &y)
 
static constexpr auto ct_select(std::span< const Self > pts, size_t idx)
 
AffineCurvePoint & operator=(Self &&other)=default
 
~AffineCurvePoint()=default
 
constexpr Self negate() const
 
constexpr CT::Choice is_identity() const
 
constexpr void conditional_assign(CT::Choice cond, const Self &pt)
 
constexpr void _const_time_unpoison() const
 
AffineCurvePoint(const Self &other)=default
 
AffineCurvePoint(Self &&other)=default
 
constexpr void serialize_to(std::span< uint8_t, Self::BYTES > bytes) const
 
constexpr void _const_time_poison() const
 
AffineCurvePoint< FieldElement, Params > Self
 
constexpr AffineCurvePoint()
 
BlindedScalarBits(const BlindedScalarBits &other)=delete
 
BlindedScalarBits & operator=(BlindedScalarBits &&other)=delete
 
size_t get_window(size_t offset) const
 
BlindedScalarBits(BlindedScalarBits &&other)=delete
 
static constexpr size_t Bytes
 
BlindedScalarBits(const typename C::Scalar &scalar, RandomNumberGenerator &rng)
 
constexpr size_t bits() const
 
static constexpr size_t Bits
 
BlindedScalarBits & operator=(const BlindedScalarBits &other)=delete
 
Helper class to ease in-place marshalling of concatenated fixed-length values.
 
static constexpr Choice from_int(T v)
 
static constexpr Mask< T > expand(T v)
 
static constexpr Mask< T > from_choice(Choice c)
 
static constexpr Mask< T > is_equal(T x, T y)
 
constexpr Choice has_value() const
Return true if this Option contains a value.
 
constexpr T value_or(T other) const
 
static constexpr int8_t Z
 
static constexpr auto GXW
 
static constexpr auto GYW
 
static constexpr size_t PrimeFieldBits
 
static constexpr FieldElement SSWU_Z
 
IntMod< MontgomeryRep< ScalarParams > > Scalar
 
static constexpr bool ValidForSswuHash
 
static constexpr FieldElement x3_ax_b(const FieldElement &x)
 
static constexpr FieldElement A
 
static constexpr bool OrderIsLessThanField
 
static constexpr size_t Words
 
AffineCurvePoint< FieldElement, Params > AffinePoint
 
ProjectiveCurvePoint< FieldElement, Params > ProjectivePoint
 
static constexpr size_t OrderBits
 
static constexpr AffinePoint G
 
IntMod< FieldRep< FieldParams > > FieldElement
 
static constexpr FieldElement B
 
constexpr Self & operator*=(const Self &other)
 
static constexpr auto P_MOD_4
 
static constexpr void conditional_assign(Self &x, Self &y, CT::Choice cond, const Self &nx, const Self &ny)
 
friend constexpr Self operator*(const Self &a, const Self &b)
 
static constexpr std::optional< Self > from_wide_bytes_varlen(std::span< const uint8_t > bytes)
 
constexpr void serialize_to(std::span< uint8_t, Self::BYTES > bytes) const
 
static constexpr size_t BITS
 
constexpr CT::Choice is_zero() const
 
static constexpr void _invert_vartime_div2_helper(Self &a, Self &x)
 
std::array< W, L > stash_value() const
 
constexpr CT::Choice is_nonzero() const
 
constexpr void _const_time_unpoison() const
 
friend constexpr Self operator-(const Self &a, const Self &b)
 
IntMod(const Self &other)=default
 
constexpr Self correct_sign(CT::Choice even) const
 
constexpr void conditional_assign(CT::Choice cond, const Self &nx)
 
constexpr Self negate() const
 
constexpr Self invert_vartime() const
 
static consteval Self constant(int8_t x)
 
constexpr std::array< W, Self::N > to_words() const
 
static constexpr Self zero()
 
static Self from_stash(const std::array< W, L > &stash)
 
IntMod(Self &&other)=default
 
static std::optional< Self > deserialize(std::span< const uint8_t > bytes)
 
constexpr Self mul8() const
Return (*this) multiplied by 8.
 
constexpr Self pow_vartime(const std::array< W, N > &exp) const
 
constexpr void square_n(size_t n)
 
constexpr CT::Option< Self > sqrt() const
 
constexpr void _const_time_poison() const
 
friend constexpr Self operator+(const Self &a, const Self &b)
 
static constexpr size_t BYTES
 
static constexpr Self one()
 
static constexpr Self choose(CT::Choice choice, const Self &x, const Self &y)
 
constexpr CT::Choice operator==(const Self &other) const
 
constexpr Self invert() const
 
constexpr Self mul3() const
Return (*this) multiplied by 3.
 
static constexpr void conditional_assign(Self &x, Self &y, Self &z, CT::Choice cond, const Self &nx, const Self &ny, const Self &nz)
 
constexpr CT::Choice is_even() const
 
IntMod & operator=(const Self &other)=default
 
static constexpr Self from_words(std::array< W, L > w)
 
IntMod & operator=(Self &&other)=default
 
constexpr Self mul4() const
Return (*this) multiplied by 4.
 
constexpr Self mul2() const
Return (*this) multiplied by 2.
 
static constexpr Self from_wide_bytes(std::span< const uint8_t, L > bytes)
 
static Self random(RandomNumberGenerator &rng)
 
constexpr CT::Choice is_one() const
 
static constexpr void conditional_swap(CT::Choice cond, Self &x, Self &y)
 
constexpr Self square() const
 
constexpr CT::Choice operator!=(const Self &other) const
 
static constexpr std::array< W, N > wide_to_rep(const std::array< W, 2 *N > &x)
 
static constexpr auto P_dash
 
static constexpr std::array< W, N > from_rep(const std::array< W, N > &z)
 
static constexpr size_t N
 
MontgomeryRep< Params > Self
 
static constexpr std::array< W, N > one()
 
static constexpr std::array< W, N > to_rep(const std::array< W, N > &x)
 
static constexpr std::array< W, N > redc(const std::array< W, 2 *N > &z)
 
C::AffinePoint AffinePoint
 
static constexpr size_t Windows
 
static constexpr size_t WindowBits
 
PrecomputedBaseMulTable(const AffinePoint &p)
 
BlindedScalarBits< C, WindowBits > BlindedScalar
 
C::ProjectivePoint ProjectivePoint
 
ProjectivePoint mul(const Scalar &s, RandomNumberGenerator &rng) const
 
static constexpr Self add_or_sub(const Self &a, const AffinePoint &b, CT::Choice sub)
 
ProjectiveCurvePoint< FieldElement, Params > Self
 
~ProjectiveCurvePoint()=default
 
ProjectiveCurvePoint(const Self &other)=default
 
friend constexpr Self operator+(const AffinePoint &a, const Self &b)
 
ProjectiveCurvePoint(Self &&other)=default
 
static constexpr bool A_is_zero
 
ProjectiveCurvePoint & operator=(Self &&other)=default
 
constexpr const FieldElement & x() const
 
constexpr ProjectiveCurvePoint()
 
friend constexpr Self operator-(const Self &a, const Self &b)
 
friend constexpr Self operator+(const Self &a, const AffinePoint &b)
 
static constexpr bool A_is_minus_3
 
ProjectiveCurvePoint & operator=(const Self &other)=default
 
static constexpr Self from_affine(const AffinePoint &pt)
 
static constexpr Self add(const Self &a, const Self &b)
 
constexpr Self & operator+=(const AffinePoint &other)
 
constexpr void conditional_assign(CT::Choice cond, const Self &pt)
 
constexpr void _const_time_unpoison() const
 
constexpr const FieldElement & z() const
 
constexpr const FieldElement & y() const
 
void randomize_rep(RandomNumberGenerator &rng)
 
constexpr CT::Choice is_identity() const
 
constexpr Self negate() const
 
friend constexpr Self operator+(const Self &a, const Self &b)
 
static constexpr FieldElement A
 
AffineCurvePoint< FieldElement, Params > AffinePoint
 
constexpr ProjectiveCurvePoint(const FieldElement &x, const FieldElement &y)
 
static constexpr Self add_mixed(const Self &a, const AffinePoint &b)
 
static constexpr Self identity()
 
constexpr void _const_time_poison() const
 
constexpr Self dbl_n(size_t n) const
 
constexpr ProjectiveCurvePoint(const FieldElement &x, const FieldElement &y, const FieldElement &z)
 
constexpr Self dbl() const
 
constexpr Self & operator+=(const Self &other)
 
void randomize(std::span< uint8_t > output)
 
virtual bool is_seeded() const =0
 
static constexpr size_t Bits
 
UnblindedScalarBits(const typename C::Scalar &scalar)
 
size_t get_window(size_t offset) const
 
static constexpr size_t WindowBits
 
typename C::AffinePoint AffinePoint
 
VartimeMul2Table(const AffinePoint &p, const AffinePoint &q)
 
typename C::Scalar Scalar
 
typename C::ProjectivePoint ProjectivePoint
 
ProjectivePoint mul2_vartime(const Scalar &s1, const Scalar &s2) const
 
static constexpr size_t TableSize
 
WindowedBoothMulTable(const AffinePoint &p)
 
C::ProjectivePoint ProjectivePoint
 
static constexpr size_t WindowBits
 
BlindedScalarBits< C, WindowBits+1 > BlindedScalar
 
static constexpr size_t InitialShift
 
ProjectivePoint mul(const Scalar &s, RandomNumberGenerator &rng) const
 
static constexpr size_t FullWindows
 
static constexpr size_t compute_full_windows(size_t sb, size_t wb)
 
static constexpr size_t TableBits
 
static constexpr size_t compute_initial_shift(size_t sb, size_t wb)
 
C::AffinePoint AffinePoint
 
ProjectivePoint mul2(const Scalar &s1, const Scalar &s2, RandomNumberGenerator &rng) const
 
C::ProjectivePoint ProjectivePoint
 
C::AffinePoint AffinePoint
 
WindowedMul2Table(const AffinePoint &p, const AffinePoint &q)
 
C::ProjectivePoint ProjectivePoint
 
static constexpr size_t Windows
 
WindowedMulTable(const AffinePoint &p)
 
BlindedScalarBits< C, WindowBits > BlindedScalar
 
static constexpr size_t TableSize
 
C::AffinePoint AffinePoint
 
ProjectivePoint mul(const Scalar &s, RandomNumberGenerator &rng) const
 
static constexpr size_t WindowBits
 
constexpr void poison_all(const Ts &... ts)
 
constexpr void unpoison_all(const Ts &... ts)
 
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
 
constexpr void unpoison(const T *p, size_t n)
 
constexpr CT::Mask< T > all_zeros(const T elem[], size_t len)
 
constexpr void poison(const T *p, size_t n)
 
C::ProjectivePoint varpoint_exec(const AffinePointTable< C > &table, const BlindedScalar &scalar, RandomNumberGenerator &rng)
 
constexpr auto bigint_add2(W x[], size_t x_size, const W y[], size_t y_size) -> W
 
auto map_to_curve_sswu(const typename C::FieldElement &u) -> typename C::AffinePoint
 
consteval std::array< W, N > shanks_tonelli_c3(const std::array< W, N > &c2)
 
auto to_affine_batch(std::span< const typename C::ProjectivePoint > projective)
 
consteval std::array< W, N > p_plus_1_over_4(const std::array< W, N > &p)
 
constexpr auto bytes_to_words(std::span< const uint8_t, L > bytes)
 
constexpr W shift_left(std::array< W, N > &x)
 
constexpr auto word_sub(W x, W y, W *carry) -> W
 
consteval std::array< W, N > p_minus_1_over_2(const std::array< W, N > &p)
 
constexpr CT::Option< typename C::FieldElement > sqrt_field_element(const typename C::FieldElement &fe)
 
constexpr auto word_add(W x, W y, W *carry) -> W
 
constexpr void copy_mem(T *out, const T *in, size_t n)
 
constexpr ProjectivePoint dbl_n_generic(const ProjectivePoint &pt, const FieldElement &A, size_t n)
 
constexpr void comba_sqr(W z[2 *N], const W x[N])
 
consteval auto shanks_tonelli_c4(const std::array< W, N > &p_minus_1_over_2) -> Z
 
constexpr size_t read_window_bits(std::span< const W, N > words, size_t offset)
 
constexpr ProjectivePoint dbl_a_minus_3(const ProjectivePoint &pt)
 
constexpr void comba_mul(W z[2 *N], const W x[N], const W y[N])
 
C::ProjectivePoint mul2_exec(const AffinePointTable< C > &table, const BlindedScalar &x, const BlindedScalar &y, RandomNumberGenerator &rng)
 
consteval std::array< W, N > p_div_2_plus_1(const std::array< W, N > &p)
 
constexpr auto monty_redc(const std::array< W, 2 *N > &z, const std::array< W, N > &p, W p_dash) -> std::array< W, N >
 
constexpr auto bigint_sub3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W
 
constexpr auto monty_inverse(W a) -> W
 
constexpr ProjectivePoint dbl_n_a_zero(const ProjectivePoint &pt, size_t n)
 
constexpr ProjectivePoint dbl_a_zero(const ProjectivePoint &pt)
 
C::ProjectivePoint basemul_exec(std::span< const typename C::AffinePoint > table, const BlindedScalar &scalar, RandomNumberGenerator &rng)
 
std::vector< typename C::ProjectivePoint > mul2_setup(const typename C::AffinePoint &p, const typename C::AffinePoint &q)
 
auto hash_to_curve_sswu(const ExpandMsg &expand_message) -> std::conditional_t< RO, typename C::ProjectivePoint, typename C::AffinePoint >
 
void secure_scrub_memory(void *ptr, size_t n)
 
consteval std::array< W, N > mul_mod(const std::array< W, N > &x, const std::array< W, N > &y, const std::array< W, N > &p)
 
constexpr int32_t bigint_cmp(const W x[], size_t x_size, const W y[], size_t y_size)
 
constexpr ProjectivePoint point_add_mixed(const ProjectivePoint &a, const AffinePoint &b, const FieldElement &one)
 
constexpr W bigint_cnd_add(W cnd, W x[], const W y[], size_t size)
 
constexpr ProjectivePoint point_add_or_sub_mixed(const ProjectivePoint &a, const AffinePoint &b, CT::Choice sub, const FieldElement &one)
 
constexpr void bigint_monty_maybe_sub(size_t N, W z[], W x0, const W x[], const W p[])
 
constexpr auto invert_field_element(const typename C::FieldElement &fe)
 
void carry(int64_t &h0, int64_t &h1)
 
BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b)
 
constexpr ProjectivePoint dbl_n_a_minus_3(const ProjectivePoint &pt, size_t n)
 
AffinePointTable< C > varpoint_setup(const typename C::AffinePoint &p)
 
constexpr auto load_le(ParamTs &&... params)
 
constexpr auto bigint_ct_is_lt(const W x[], size_t x_size, const W y[], size_t y_size, bool lt_or_equal=false) -> CT::Mask< W >
 
constexpr auto hex_to_words(const char(&s)[N])
 
constexpr ProjectivePoint dbl_generic(const ProjectivePoint &pt, const FieldElement &A)
 
consteval std::array< W, N > p_minus(const std::array< W, N > &p)
 
std::vector< typename C::AffinePoint > basemul_setup(const typename C::AffinePoint &p, size_t max_scalar_bits)
 
constexpr ProjectivePoint point_add(const ProjectivePoint &a, const ProjectivePoint &b)
 
std::conditional_t< HasNative64BitRegisters, std::uint64_t, uint32_t > word
 
consteval size_t count_bits(const std::array< W, N > &p)
 
constexpr auto store_be(ParamTs &&... params)
 
constexpr auto monty_redc_pdash1(const std::array< W, 2 *N > &z, const std::array< W, N > &p) -> std::array< W, N >
 
consteval std::array< W, N > montygomery_r(const std::array< W, N > &p)
 
constexpr W shift_right(std::array< W, N > &x)
 
consteval std::pair< size_t, std::array< W, N > > shanks_tonelli_c1c2(const std::array< W, N > &p)
 
static constexpr size_t N