7#include <botan/internal/pcurves_instance.h>
9#include <botan/internal/pcurves_solinas.h>
10#include <botan/internal/pcurves_wrap.h>
16template <
typename Params>
17class Secp256r1Rep
final {
19 static constexpr auto P = Params::P;
20 static constexpr size_t N = Params::N;
21 typedef typename Params::W W;
24 static constexpr auto P256_4 =
27 constexpr static std::array<W, N> redc(
const std::array<W, 2 * N>& z) {
46 const int64_t S0 = P256_4[0] + X00 + X08 + X09 - (X11 + X12 + X13 + X14);
47 const int64_t S1 = P256_4[1] + X01 + X09 + X10 - (X12 + X13 + X14 + X15);
48 const int64_t S2 = P256_4[2] + X02 + X10 + X11 - (X13 + X14 + X15);
49 const int64_t S3 = P256_4[3] + X03 + 2 * (X11 + X12) + X13 - (X15 + X08 + X09);
50 const int64_t S4 = P256_4[4] + X04 + 2 * (X12 + X13) + X14 - (X09 + X10);
51 const int64_t S5 = P256_4[5] + X05 + 2 * (X13 + X14) + X15 - (X10 + X11);
52 const int64_t S6 = P256_4[6] + X06 + X13 + X14 * 3 + X15 * 2 - (X08 + X09);
53 const int64_t S7 = P256_4[7] + X07 + X15 * 3 + X08 - (X10 + X11 + X12 + X13);
54 const int64_t S8 = P256_4[8];
56 std::array<W, N> r = {};
68 const auto S = sum.final_carry(S8);
72 const auto correction = p256_mul_mod_256(S);
73 W borrow =
bigint_sub2(r.data(), N, correction.data(), N);
80 constexpr static std::array<W, N> one() {
return std::array<W, N>{1}; }
82 constexpr static std::array<W, N> to_rep(
const std::array<W, N>& x) {
return x; }
84 constexpr static std::array<W, N> wide_to_rep(
const std::array<W, 2 * N>& x) {
return redc(x); }
86 constexpr static std::array<W, N> from_rep(
const std::array<W, N>& z) {
return z; }
92 constexpr static std::array<W, N> p256_mul_mod_256(W i) {
93 static_assert(WordInfo<W>::bits == 32 || WordInfo<W>::bits == 64);
99 if constexpr(WordInfo<W>::bits == 32) {
105 const uint64_t i32 =
static_cast<uint64_t
>(i) << 32;
118class Params
final :
public EllipticCurveParameters<
119 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
120 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
121 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
122 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
123 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
124 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
130class Curve
final :
public EllipticCurve<Params, Secp256r1Rep> {
133 static FieldElement fe_invert2(
const FieldElement& x) {
166 static Scalar scalar_invert(
const Scalar& x) {
167 auto t1 = x.square();
168 auto t5 = t1.square();
173 auto t9 = t3.square();
#define BOTAN_DEBUG_ASSERT(expr)
static std::shared_ptr< const PrimeOrderCurve > secp256r1()
static std::shared_ptr< const PrimeOrderCurve > instance()
int(* final)(unsigned char *, CTX *)
constexpr uint32_t get_uint32(const W xw[], size_t i)
constexpr W bigint_cnd_add(W cnd, W x[], size_t x_size, const W y[], size_t y_size)
constexpr auto bigint_sub2(W x[], size_t x_size, const W y[], size_t y_size) -> W
constexpr auto hex_to_words(const char(&s)[N])