Botan 3.6.0
Crypto and TLS for C&
pcurves_secp192r1.cpp
Go to the documentation of this file.
1/*
2* (C) 2024 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/internal/pcurves_instance.h>
8
9#include <botan/internal/pcurves_solinas.h>
10#include <botan/internal/pcurves_wrap.h>
11
12namespace Botan::PCurve {
13
14namespace {
15
16namespace secp192r1 {
17
18template <typename Params>
19class Secp192r1Rep final {
20 public:
21 static constexpr auto P = Params::P;
22 static constexpr size_t N = Params::N;
23 typedef typename Params::W W;
24
25 constexpr static std::array<W, N> redc(const std::array<W, 2 * N>& z) {
26 const int64_t X00 = get_uint32(z.data(), 0);
27 const int64_t X01 = get_uint32(z.data(), 1);
28 const int64_t X02 = get_uint32(z.data(), 2);
29 const int64_t X03 = get_uint32(z.data(), 3);
30 const int64_t X04 = get_uint32(z.data(), 4);
31 const int64_t X05 = get_uint32(z.data(), 5);
32 const int64_t X06 = get_uint32(z.data(), 6);
33 const int64_t X07 = get_uint32(z.data(), 7);
34 const int64_t X08 = get_uint32(z.data(), 8);
35 const int64_t X09 = get_uint32(z.data(), 9);
36 const int64_t X10 = get_uint32(z.data(), 10);
37 const int64_t X11 = get_uint32(z.data(), 11);
38
39 const int64_t S0 = X00 + X06 + X10;
40 const int64_t S1 = X01 + X07 + X11;
41 const int64_t S2 = X02 + X06 + X08 + X10;
42 const int64_t S3 = X03 + X07 + X09 + X11;
43 const int64_t S4 = X04 + X08 + X10;
44 const int64_t S5 = X05 + X09 + X11;
45
46 std::array<W, N> r = {};
47
48 SolinasAccum sum(r);
49
50 sum.accum(S0);
51 sum.accum(S1);
52 sum.accum(S2);
53 sum.accum(S3);
54 sum.accum(S4);
55 sum.accum(S5);
56 const auto S = sum.final_carry(0);
57
58 BOTAN_DEBUG_ASSERT(S <= 3);
59
60 const auto correction = p192_mul_mod_192(S);
61 W borrow = bigint_sub2(r.data(), N, correction.data(), N);
62
63 bigint_cnd_add(borrow, r.data(), N, P.data(), N);
64
65 return r;
66 }
67
68 constexpr static std::array<W, N> one() { return std::array<W, N>{1}; }
69
70 constexpr static std::array<W, N> to_rep(const std::array<W, N>& x) { return x; }
71
72 constexpr static std::array<W, N> wide_to_rep(const std::array<W, 2 * N>& x) { return redc(x); }
73
74 constexpr static std::array<W, N> from_rep(const std::array<W, N>& z) { return z; }
75
76 private:
77 // Return (i*P-192) % 2**192
78 //
79 // Assumes i is small
80 constexpr static std::array<W, N> p192_mul_mod_192(W i) {
81 static_assert(WordInfo<W>::bits == 32 || WordInfo<W>::bits == 64);
82
83 // For small i, multiples of P-192 have a simple structure so it's faster to
84 // compute the value directly vs a (constant time) table lookup
85
86 auto r = P;
87
88 if constexpr(WordInfo<W>::bits == 32) {
89 r[2] -= i;
90 r[0] -= i;
91 } else {
92 r[1] -= i;
93 r[0] -= i;
94 }
95 return r;
96 }
97};
98
99// clang-format off
100class Params final : public EllipticCurveParameters<
101 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
102 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
103 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
104 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
105 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
106 "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"> {
107};
108
109// clang-format on
110
111class Curve final : public EllipticCurve<Params, Secp192r1Rep> {};
112
113} // namespace secp192r1
114
115} // namespace
116
117std::shared_ptr<const PrimeOrderCurve> PCurveInstance::secp192r1() {
119}
120
121} // namespace Botan::PCurve
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:98
static std::shared_ptr< const PrimeOrderCurve > secp192r1()
Definition pcurves.cpp:19
static std::shared_ptr< const PrimeOrderCurve > instance()
constexpr void accum(int64_t v)
constexpr W final_carry(int64_t C)
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)
Definition mp_core.h:42
constexpr auto bigint_sub2(W x[], size_t x_size, const W y[], size_t y_size) -> W
Definition mp_core.h:291