Skip to content

Commit

Permalink
Merge pull request #4251 from randombit/jack/numsp512d1
Browse files Browse the repository at this point in the history
Add NUMS curve numsp512d1
  • Loading branch information
randombit authored Aug 3, 2024
2 parents 0d4969a + d7d565b commit 2c3fabb
Show file tree
Hide file tree
Showing 13 changed files with 563 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/build-data/oids.txt
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,7 @@
1.2.643.7.1.2.1.2.2 = gost_512B
1.2.643.2.2.35.1 = gost_256A
1.2.643.2.2.36.0 = gost_256A

1.3.6.1.4.1.25258.4.1 = numsp256d1
1.3.6.1.4.1.25258.4.2 = numsp384d1
1.3.6.1.4.1.25258.4.3 = numsp512d1
6 changes: 6 additions & 0 deletions src/lib/asn1/oid_maps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ std::unordered_map<std::string, std::string> OID_Map::load_oid2str_map() {
{"1.3.6.1.4.1.25258.3.4.7", "Camellia-192/SIV"},
{"1.3.6.1.4.1.25258.3.4.8", "Camellia-256/SIV"},
{"1.3.6.1.4.1.25258.3.4.9", "SM4/SIV"},
{"1.3.6.1.4.1.25258.4.1", "numsp256d1"},
{"1.3.6.1.4.1.25258.4.2", "numsp384d1"},
{"1.3.6.1.4.1.25258.4.3", "numsp512d1"},
{"1.3.6.1.4.1.3029.1.2.1", "ElGamal"},
{"1.3.6.1.4.1.3029.1.5.1", "OpenPGP.Curve25519"},
{"1.3.6.1.4.1.311.20.2.2", "Microsoft SmartcardLogon"},
Expand Down Expand Up @@ -582,6 +585,9 @@ std::unordered_map<std::string, OID> OID_Map::load_str2oid_map() {
{"gost_256B", OID({1, 2, 643, 7, 1, 2, 1, 1, 2})},
{"gost_512A", OID({1, 2, 643, 7, 1, 2, 1, 2, 1})},
{"gost_512B", OID({1, 2, 643, 7, 1, 2, 1, 2, 2})},
{"numsp256d1", OID({1, 3, 6, 1, 4, 1, 25258, 4, 1})},
{"numsp384d1", OID({1, 3, 6, 1, 4, 1, 25258, 4, 2})},
{"numsp512d1", OID({1, 3, 6, 1, 4, 1, 25258, 4, 3})},
{"secp160k1", OID({1, 3, 132, 0, 9})},
{"secp160r1", OID({1, 3, 132, 0, 8})},
{"secp160r2", OID({1, 3, 132, 0, 30})},
Expand Down
14 changes: 14 additions & 0 deletions src/lib/math/pcurves/pcurves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ std::shared_ptr<const PrimeOrderCurve> PCurveInstance::sm2p256v1() {
}
#endif

#if !defined(BOTAN_HAS_PCURVES_NUMSP512D1)
//static
std::shared_ptr<const PrimeOrderCurve> PCurveInstance::numsp512d1() {
return nullptr;
}
#endif

std::shared_ptr<const PrimeOrderCurve> PrimeOrderCurve::from_id(PrimeOrderCurveId id) {
switch(id.code()) {
case PrimeOrderCurveId::secp192r1:
Expand All @@ -106,6 +113,8 @@ std::shared_ptr<const PrimeOrderCurve> PrimeOrderCurve::from_id(PrimeOrderCurveI
return PCurveInstance::frp256v1();
case PrimeOrderCurveId::sm2p256v1:
return PCurveInstance::sm2p256v1();
case PrimeOrderCurveId::numsp512d1:
return PCurveInstance::numsp512d1();
}
return {};
}
Expand All @@ -122,6 +131,7 @@ std::vector<PrimeOrderCurveId> PrimeOrderCurveId::all() {
PrimeOrderCurveId::brainpool512r1,
PrimeOrderCurveId::frp256v1,
PrimeOrderCurveId::sm2p256v1,
PrimeOrderCurveId::numsp512d1,
};
}

Expand All @@ -147,6 +157,8 @@ std::string PrimeOrderCurveId::to_string() const {
return "frp256v1";
case PrimeOrderCurveId::sm2p256v1:
return "sm2p256v1";
case PrimeOrderCurveId::numsp512d1:
return "numsp512d1";
}

return "unknown";
Expand Down Expand Up @@ -174,6 +186,8 @@ std::optional<PrimeOrderCurveId> PrimeOrderCurveId::from_string(std::string_view
return PCurve::PrimeOrderCurveId::frp256v1;
} else if(name == "sm2p256v1") {
return PCurve::PrimeOrderCurveId::sm2p256v1;
} else if(name == "numsp512d1") {
return PCurve::PrimeOrderCurveId::numsp512d1;
} else {
return {};
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/math/pcurves/pcurves_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class BOTAN_TEST_API PrimeOrderCurveId final {
brainpool512r1,
frp256v1,
sm2p256v1,
numsp512d1,
};

using enum Code;
Expand Down
12 changes: 9 additions & 3 deletions src/lib/math/pcurves/pcurves_impl/pcurves_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -657,8 +657,10 @@ class ProjectiveCurvePoint {
const auto H = U2 - a.x();
const auto r = S2 - a.y();

// If r is zero then we are in the doubling case
if(r.is_zero().as_bool()) {
// If r == H == 0 then we are in the doubling case
// For a == -b we compute the correct result because
// H will be zero, leading to Z3 being zero also
if((r.is_zero() && H.is_zero()).as_bool()) {
return a.dbl();
}

Expand Down Expand Up @@ -687,6 +689,7 @@ class ProjectiveCurvePoint {
constexpr static Self add(const Self& a, const Self& b) {
const auto a_is_identity = a.is_identity();
const auto b_is_identity = b.is_identity();

if((a_is_identity && b_is_identity).as_bool()) {
return Self::identity();
}
Expand All @@ -706,7 +709,10 @@ class ProjectiveCurvePoint {
const auto H = U2 - U1;
const auto r = S2 - S1;

if(r.is_zero().as_bool()) {
// If a == -b then H == 0 && r != 0, in which case
// at the end we'll set z = a.z * b.z * H = 0, resulting
// in the correct output (point at infinity)
if((r.is_zero() && H.is_zero()).as_bool()) {
return a.dbl();
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib/math/pcurves/pcurves_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class PCurveInstance final {
static std::shared_ptr<const PrimeOrderCurve> frp256v1();

static std::shared_ptr<const PrimeOrderCurve> sm2p256v1();

static std::shared_ptr<const PrimeOrderCurve> numsp512d1();
};

} // namespace Botan::PCurve
Expand Down
12 changes: 12 additions & 0 deletions src/lib/math/pcurves/pcurves_numsp512d1/info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<defines>
PCURVES_NUMSP512D1 -> 20240723
</defines>

<module_info>
name -> "PCurve numsp512d1"
brief -> "numsp512d1"
</module_info>

<requires>
pcurves_impl
</requires>
105 changes: 105 additions & 0 deletions src/lib/math/pcurves/pcurves_numsp512d1/pcurves_numsp512d1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* (C) 2024 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/internal/pcurves_instance.h>

#include <botan/internal/pcurves_wrap.h>

namespace Botan::PCurve {

namespace {

namespace numsp512d1 {

template <typename Params>
class Numsp512d1Rep final {
public:
static constexpr auto P = Params::P;
static constexpr size_t N = Params::N;
typedef typename Params::W W;

static constexpr W C = 569;

constexpr static std::array<W, N> one() { return std::array<W, N>{1}; }

constexpr static std::array<W, N> redc(const std::array<W, 2 * N>& z) {
return redc_crandall<W, N, C>(std::span{z});
}

constexpr static std::array<W, N> to_rep(const std::array<W, N>& x) { return x; }

constexpr static std::array<W, N> wide_to_rep(const std::array<W, 2 * N>& x) { return redc(x); }

constexpr static std::array<W, N> from_rep(const std::array<W, N>& z) { return z; }
};

// clang-format off
class Params final : public EllipticCurveParameters<
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4",
"1D99B",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B3CA4FB94E7831B4FC258ED97D0BDC63B568B36607CD243CE153F390433555D",
"2",
"1C282EB23327F9711952C250EA61AD53FCC13031CF6DD336E0B9328433AFBDD8CC5A1C1F0C716FDC724DDE537C2B0ADB00BB3D08DC83755B205CC30D7F83CF28"> {
};

// clang-format on

class Curve final : public EllipticCurve<Params, Numsp512d1Rep> {
public:
static FieldElement fe_invert2(const FieldElement& x) {
// Generated by https://github.com/mmcloughlin/addchain
auto z = x.square();
z *= x;
z = z.square();
z *= x;
auto t0 = z;
t0.square_n(3);
t0 *= z;
t0.square_n(3);
auto t1 = t0 * z;
t0 = t1;
t0.square_n(9);
t0 *= t1;
t0.square_n(3);
t0 *= z;
auto t2 = t0;
t2.square_n(9);
t1 *= t2;
t2 = t1;
t2.square_n(30);
t1 *= t2;
t2 = t1;
t2.square_n(60);
t1 *= t2;
t2 = t1;
t2.square_n(120);
t1 *= t2;
t2 = t1;
t2.square_n(240);
t1 *= t2;
t1.square_n(21);
t0 *= t1;
t0 = t0.square();
t0 *= x;
t0.square_n(4);
z *= t0;
z.square_n(4);
z *= x;
z.square_n(2);
return z;
}
};

} // namespace numsp512d1

} // namespace

std::shared_ptr<const PrimeOrderCurve> PCurveInstance::numsp512d1() {
return PrimeOrderCurveImpl<numsp512d1::Curve>::instance();
}

} // namespace Botan::PCurve
17 changes: 17 additions & 0 deletions src/lib/pubkey/ec_group/ec_named.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,18 @@ std::shared_ptr<EC_Group_Data> EC_Group::EC_group_info(const OID& oid) {
oid);
}

// numsp512d1
if(oid == OID{1, 3, 6, 1, 4, 1, 25258, 4, 3}) {
return load_EC_group_info(
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7",
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4",
"0x1D99B",
"0x2",
"0x1C282EB23327F9711952C250EA61AD53FCC13031CF6DD336E0B9328433AFBDD8CC5A1C1F0C716FDC724DDE537C2B0ADB00BB3D08DC83755B205CC30D7F83CF28",
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B3CA4FB94E7831B4FC258ED97D0BDC63B568B36607CD243CE153F390433555D",
oid);
}

return std::shared_ptr<EC_Group_Data>();
}

Expand Down Expand Up @@ -453,6 +465,10 @@ OID EC_Group::EC_group_identity_from_order(const BigInt& order)
return OID{1, 2, 840, 10045, 3, 1, 6};
}

if(low_bits == 0x0433555D && order == BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B3CA4FB94E7831B4FC258ED97D0BDC63B568B36607CD243CE153F390433555D")) {
return OID{1, 3, 6, 1, 4, 1, 25258, 4, 3};
}

return OID();
}

Expand All @@ -469,6 +485,7 @@ const std::set<std::string>& EC_Group::known_named_groups() {
"frp256v1",
"gost_256A",
"gost_512A",
"numsp512d1",
"secp160k1",
"secp160r1",
"secp160r2",
Expand Down
Loading

0 comments on commit 2c3fabb

Please sign in to comment.