aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/math/ec_gfp/curve_gfp.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2014-08-09 16:04:13 +0000
committerlloyd <[email protected]>2014-08-09 16:04:13 +0000
commit99ad1cc84bb3099ad236ade3a47d7134a5f85d40 (patch)
treecd2c1222fca296e3f37784438f9b0c226ca0f284 /src/lib/math/ec_gfp/curve_gfp.cpp
parent455bd2557cbb1343e59eefd97cb449f06a702c28 (diff)
Move mul and square operations on a elliptic curve to CurveGFp so we
can use different representations/operations depending on the curve (eg, using a specialized version for P-256 reduction)
Diffstat (limited to 'src/lib/math/ec_gfp/curve_gfp.cpp')
-rw-r--r--src/lib/math/ec_gfp/curve_gfp.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/lib/math/ec_gfp/curve_gfp.cpp b/src/lib/math/ec_gfp/curve_gfp.cpp
new file mode 100644
index 000000000..2fa9f391e
--- /dev/null
+++ b/src/lib/math/ec_gfp/curve_gfp.cpp
@@ -0,0 +1,122 @@
+/*
+* Elliptic curves over GF(p) Montgomery Representation
+* (C) 2014 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/curve_gfp.h>
+#include <botan/internal/mp_core.h>
+
+namespace Botan {
+
+namespace {
+
+class CurveGFp_Montgomery : public CurveGFp_Repr
+ {
+ public:
+ CurveGFp_Montgomery(const BigInt& p, const BigInt& a, const BigInt& b) :
+ m_p(p), m_a(a), m_b(b),
+ m_p_words(m_p.sig_words()),
+ m_p_dash(monty_inverse(m_p.word_at(0)))
+ {
+ const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS);
+
+ m_r2 = (r * r) % p;
+ m_a_r = (m_a * r) % p;
+ m_b_r = (m_b * r) % p;
+ }
+
+ const BigInt& get_a() const override { return m_a; }
+
+ const BigInt& get_b() const override { return m_b; }
+
+ const BigInt& get_p() const override { return m_p; }
+
+ const BigInt& get_a_rep() const override { return m_a_r; }
+
+ const BigInt& get_b_rep() const override { return m_b_r; }
+
+ void to_curve_rep(BigInt& x, secure_vector<word>& ws) const override;
+
+ void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override;
+
+ 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:
+ BigInt m_p, m_a, m_b;
+ size_t m_p_words; // cache of m_p.sig_words()
+
+ // Montgomery parameters
+ BigInt m_r2, m_a_r, m_b_r;
+ word m_p_dash;
+ };
+
+void CurveGFp_Montgomery::to_curve_rep(BigInt& x, secure_vector<word>& ws) const
+ {
+ const BigInt tx = x;
+ curve_mul(x, tx, m_r2, ws);
+ }
+
+void CurveGFp_Montgomery::from_curve_rep(BigInt& x, secure_vector<word>& ws) const
+ {
+ const BigInt tx = x;
+ curve_mul(x, tx, 1, ws);
+ }
+
+void CurveGFp_Montgomery::curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
+ secure_vector<word>& ws) const
+ {
+ if(x.is_zero() || y.is_zero())
+ {
+ z = 0;
+ return;
+ }
+
+ const size_t output_size = 2*m_p_words + 1;
+ ws.resize(2*(m_p_words+2));
+
+ z.grow_to(output_size);
+ z.clear();
+
+ bigint_monty_mul(z.mutable_data(), output_size,
+ x.data(), x.size(), x.sig_words(),
+ y.data(), y.size(), y.sig_words(),
+ m_p.data(), m_p_words, m_p_dash,
+ &ws[0]);
+ }
+
+void CurveGFp_Montgomery::curve_sqr(BigInt& z, const BigInt& x,
+ secure_vector<word>& ws) const
+ {
+ if(x.is_zero())
+ {
+ z = 0;
+ return;
+ }
+
+ const size_t output_size = 2*m_p_words + 1;
+
+ ws.resize(2*(m_p_words+2));
+
+ z.grow_to(output_size);
+ z.clear();
+
+ bigint_monty_sqr(z.mutable_data(), output_size,
+ x.data(), x.size(), x.sig_words(),
+ m_p.data(), m_p_words, m_p_dash,
+ &ws[0]);
+ }
+
+}
+
+std::shared_ptr<CurveGFp_Repr>
+CurveGFp::choose_repr(const BigInt& p, const BigInt& a, const BigInt& b)
+ {
+ return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_Montgomery(p, a, b));
+ }
+
+}