diff options
author | Jack Lloyd <[email protected]> | 2015-08-08 12:41:26 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2015-08-08 12:41:26 -0400 |
commit | 549aaeccca01671ca94b422fe589c772349983ff (patch) | |
tree | 27bb784b27c7ac85717b9a3ff7cda4d8ea6c4523 /src/lib/math/ec_gfp/curve_gfp.cpp | |
parent | 63c1958b841d26184c526b54c531b0188c34ab0a (diff) |
Expose the NIST prime values and reduction operations as plain functions.
Previously they were hidden away as private functions on the CurveGFp
types. This allows directly testing the reduction functions against
other computational methods.
Diffstat (limited to 'src/lib/math/ec_gfp/curve_gfp.cpp')
-rw-r--r-- | src/lib/math/ec_gfp/curve_gfp.cpp | 172 |
1 files changed, 144 insertions, 28 deletions
diff --git a/src/lib/math/ec_gfp/curve_gfp.cpp b/src/lib/math/ec_gfp/curve_gfp.cpp index 64d45572d..96fe873af 100644 --- a/src/lib/math/ec_gfp/curve_gfp.cpp +++ b/src/lib/math/ec_gfp/curve_gfp.cpp @@ -1,12 +1,12 @@ /* * Elliptic curves over GF(p) Montgomery Representation -* (C) 2014 Jack Lloyd +* (C) 2014,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include <botan/curve_gfp.h> -#include <botan/internal/curve_nistp.h> +#include <botan/curve_nistp.h> #include <botan/internal/mp_core.h> #include <botan/internal/mp_asmi.h> @@ -115,54 +115,170 @@ void CurveGFp_Montgomery::curve_sqr(BigInt& z, const BigInt& x, ws.data()); } -} +class CurveGFp_NIST : public CurveGFp_Repr + { + public: + CurveGFp_NIST(size_t p_bits, const BigInt& a, const BigInt& b) : + m_a(a), m_b(b), m_p_words((p_bits + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS) + { + } + + const BigInt& get_a() const override { return m_a; } + + const BigInt& get_b() const override { return m_b; } + + size_t get_p_words() const override { return m_p_words; } + + const BigInt& get_a_rep() const override { return m_a; } + + const BigInt& get_b_rep() const override { return m_b; } + + void to_curve_rep(BigInt& x, secure_vector<word>& ws) const override + { redc(x, ws); } + + void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override + { redc(x, ws); } + + void curve_mul(BigInt& z, const BigInt& x, const BigInt& y, + secure_vector<word>& ws) const override; + + void curve_sqr(BigInt& z, const BigInt& x, + secure_vector<word>& ws) const override; + private: + virtual void redc(BigInt& x, secure_vector<word>& ws) const = 0; + + // Curve parameters + BigInt m_a, m_b; + size_t m_p_words; // cache of m_p.sig_words() + }; -// Default implementation -void CurveGFp_Repr::normalize(BigInt& x, secure_vector<word>& ws, size_t bound) const +void CurveGFp_NIST::curve_mul(BigInt& z, const BigInt& x, const BigInt& y, + secure_vector<word>& ws) const { - const BigInt& p = get_p(); - const word* prime = p.data(); + if(x.is_zero() || y.is_zero()) + { + z = 0; + return; + } + const size_t p_words = get_p_words(); + const size_t output_size = 2*p_words + 1; + ws.resize(2*(p_words+2)); - while(x.is_negative()) - x += p; + z.grow_to(output_size); + z.clear(); - x.grow_to(p_words + 1); + bigint_mul(z.mutable_data(), output_size, ws.data(), + x.data(), x.size(), x.sig_words(), + y.data(), y.size(), y.sig_words()); - if(ws.size() < p_words + 1) - ws.resize(p_words + 1); + this->redc(z, ws); + } - for(size_t i = 0; bound == 0 || i < bound; ++i) +void CurveGFp_NIST::curve_sqr(BigInt& z, const BigInt& x, + secure_vector<word>& ws) const + { + if(x.is_zero()) { - const word* xd = x.data(); - word borrow = 0; + z = 0; + return; + } + + const size_t p_words = get_p_words(); + const size_t output_size = 2*p_words + 1; - for(size_t i = 0; i != p_words; ++i) - ws[i] = word_sub(xd[i], prime[i], &borrow); - ws[p_words] = word_sub(xd[p_words], 0, &borrow); + ws.resize(2*(p_words+2)); - if(borrow) - break; + z.grow_to(output_size); + z.clear(); - x.swap_reg(ws); - } + bigint_sqr(z.mutable_data(), output_size, ws.data(), + x.data(), x.size(), x.sig_words()); + + this->redc(z, ws); } +#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32) + +/** +* The NIST P-192 curve +*/ +class CurveGFp_P192 : public CurveGFp_NIST + { + public: + CurveGFp_P192(const BigInt& a, const BigInt& b) : CurveGFp_NIST(192, a, b) {} + const BigInt& get_p() const override { return prime_p192(); } + private: + void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p192(x, ws); } + }; + +/** +* The NIST P-224 curve +*/ +class CurveGFp_P224 : public CurveGFp_NIST + { + public: + CurveGFp_P224(const BigInt& a, const BigInt& b) : CurveGFp_NIST(224, a, b) {} + const BigInt& get_p() const override { return prime_p224(); } + private: + void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p224(x, ws); } + }; + +/** +* The NIST P-256 curve +*/ +class CurveGFp_P256 : public CurveGFp_NIST + { + public: + CurveGFp_P256(const BigInt& a, const BigInt& b) : CurveGFp_NIST(256, a, b) {} + const BigInt& get_p() const override { return prime_p256(); } + private: + void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p256(x, ws); } + }; + +/** +* The NIST P-384 curve +*/ +class CurveGFp_P384 : public CurveGFp_NIST + { + public: + CurveGFp_P384(const BigInt& a, const BigInt& b) : CurveGFp_NIST(384, a, b) {} + const BigInt& get_p() const override { return prime_p384(); } + private: + void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p384(x, ws); } + }; + +#endif + +/** +* The NIST P-521 curve +*/ +class CurveGFp_P521 : public CurveGFp_NIST + { + public: + CurveGFp_P521(const BigInt& a, const BigInt& b) : CurveGFp_NIST(521, a, b) {} + const BigInt& get_p() const override { return prime_p521(); } + private: + void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p521(x, ws); } + }; + +} + std::shared_ptr<CurveGFp_Repr> CurveGFp::choose_repr(const BigInt& p, const BigInt& a, const BigInt& b) { -#if defined(BOTAN_HAS_CURVEGFP_NISTP_M32) - if(p == CurveGFp_P192::prime()) +#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32) + if(p == prime_p192()) return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P192(a, b)); - if(p == CurveGFp_P224::prime()) + if(p == prime_p224()) return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P224(a, b)); - if(p == CurveGFp_P256::prime()) + if(p == prime_p256()) return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P256(a, b)); - if(p == CurveGFp_P384::prime()) + if(p == prime_p384()) return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P384(a, b)); #endif - if(p == CurveGFp_P521::prime()) + if(p == prime_p521()) return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P521(a, b)); return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_Montgomery(p, a, b)); |