Botan
1.11.15
|
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