Botan  1.11.15
src/lib/math/ec_gfp/curve_gfp.h
Go to the documentation of this file.
00001 /*
00002 * Elliptic curves over GF(p)
00003 *
00004 * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
00005 *     2010-2011,2012,2014 Jack Lloyd
00006 *
00007 * Botan is released under the Simplified BSD License (see license.txt)
00008 */
00009 
00010 #ifndef BOTAN_GFP_CURVE_H__
00011 #define BOTAN_GFP_CURVE_H__
00012 
00013 #include <botan/numthry.h>
00014 #include <memory>
00015 
00016 namespace Botan {
00017 
00018 class CurveGFp_Repr
00019    {
00020    public:
00021       virtual ~CurveGFp_Repr() {}
00022 
00023       virtual const BigInt& get_p() const = 0;
00024       virtual const BigInt& get_a() const = 0;
00025       virtual const BigInt& get_b() const = 0;
00026 
00027       virtual size_t get_p_words() const = 0;
00028 
00029       /*
00030       * Returns to_curve_rep(get_a())
00031       */
00032       virtual const BigInt& get_a_rep() const = 0;
00033 
00034       /*
00035       * Returns to_curve_rep(get_b())
00036       */
00037       virtual const BigInt& get_b_rep() const = 0;
00038 
00039       virtual void to_curve_rep(BigInt& x, secure_vector<word>& ws) const = 0;
00040 
00041       virtual void from_curve_rep(BigInt& x, secure_vector<word>& ws) const = 0;
00042 
00043       virtual void curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
00044                              secure_vector<word>& ws) const = 0;
00045 
00046       virtual void curve_sqr(BigInt& z, const BigInt& x,
00047                              secure_vector<word>& ws) const = 0;
00048 
00049       virtual void normalize(BigInt& x,
00050                              secure_vector<word>& ws,
00051                              size_t bound) const;
00052    };
00053 
00054 /**
00055 * This class represents an elliptic curve over GF(p)
00056 */
00057 class BOTAN_DLL CurveGFp
00058    {
00059    public:
00060 
00061       /**
00062       * Create an uninitialized CurveGFp
00063       */
00064       CurveGFp() {}
00065 
00066       /**
00067       * Construct the elliptic curve E: y^2 = x^3 + ax + b over GF(p)
00068       * @param p prime number of the field
00069       * @param a first coefficient
00070       * @param b second coefficient
00071       */
00072       CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) :
00073          m_repr(choose_repr(p, a, b))
00074          {
00075          }
00076 
00077       CurveGFp(const CurveGFp&) = default;
00078 
00079       CurveGFp& operator=(const CurveGFp&) = default;
00080 
00081       /**
00082       * @return curve coefficient a
00083       */
00084       const BigInt& get_a() const { return m_repr->get_a(); }
00085 
00086       /**
00087       * @return curve coefficient b
00088       */
00089       const BigInt& get_b() const { return m_repr->get_b(); }
00090 
00091       /**
00092       * Get prime modulus of the field of the curve
00093       * @return prime modulus of the field of the curve
00094       */
00095       const BigInt& get_p() const { return m_repr->get_p(); }
00096 
00097       const BigInt& get_a_rep() const { return m_repr->get_a_rep(); }
00098 
00099       const BigInt& get_b_rep() const { return m_repr->get_b_rep(); }
00100 
00101       void to_rep(BigInt& x, secure_vector<word>& ws) const
00102          {
00103          m_repr->to_curve_rep(x, ws);
00104          }
00105 
00106       void from_rep(BigInt& x, secure_vector<word>& ws) const
00107          {
00108          m_repr->from_curve_rep(x, ws);
00109          }
00110 
00111       BigInt from_rep(const BigInt& x, secure_vector<word>& ws) const
00112          {
00113          BigInt xt(x);
00114          m_repr->from_curve_rep(xt, ws);
00115          return xt;
00116          }
00117 
00118       // TODO: from_rep taking && ref
00119 
00120       void mul(BigInt& z, const BigInt& x, const BigInt& y, secure_vector<word>& ws) const
00121          {
00122          m_repr->curve_mul(z, x, y, ws);
00123          }
00124 
00125       BigInt mul(const BigInt& x, const BigInt& y, secure_vector<word>& ws) const
00126          {
00127          BigInt z;
00128          m_repr->curve_mul(z, x, y, ws);
00129          return z;
00130          }
00131 
00132       void sqr(BigInt& z, const BigInt& x, secure_vector<word>& ws) const
00133          {
00134          m_repr->curve_sqr(z, x, ws);
00135          }
00136 
00137       BigInt sqr(const BigInt& x, secure_vector<word>& ws) const
00138          {
00139          BigInt z;
00140          m_repr->curve_sqr(z, x, ws);
00141          return z;
00142          }
00143 
00144       /**
00145       * Adjust x to be in [0,p)
00146       * @param bound if greater than zero, assume that no more than bound
00147       *        additions or subtractions are required to move x into range.
00148       */
00149       void normalize(BigInt& x, secure_vector<word>& ws, size_t bound = 0) const
00150          {
00151          m_repr->normalize(x, ws, bound);
00152          }
00153 
00154       void swap(CurveGFp& other)
00155          {
00156          std::swap(m_repr, other.m_repr);
00157          }
00158 
00159    private:
00160       static std::shared_ptr<CurveGFp_Repr>
00161          choose_repr(const BigInt& p, const BigInt& a, const BigInt& b);
00162 
00163       std::shared_ptr<CurveGFp_Repr> m_repr;
00164    };
00165 
00166 /**
00167 * Equality operator
00168 * @param lhs a curve
00169 * @param rhs a curve
00170 * @return true iff lhs is the same as rhs
00171 */
00172 inline bool operator==(const CurveGFp& lhs, const CurveGFp& rhs)
00173    {
00174    return (lhs.get_p() == rhs.get_p()) &&
00175           (lhs.get_a() == rhs.get_a()) &&
00176           (lhs.get_b() == rhs.get_b());
00177    }
00178 
00179 inline bool operator!=(const CurveGFp& lhs, const CurveGFp& rhs)
00180    {
00181    return !(lhs == rhs);
00182    }
00183 
00184 }
00185 
00186 namespace std {
00187 
00188 template<> inline
00189 void swap<Botan::CurveGFp>(Botan::CurveGFp& curve1,
00190                            Botan::CurveGFp& curve2) noexcept
00191    {
00192    curve1.swap(curve2);
00193    }
00194 
00195 } // namespace std
00196 
00197 #endif