curve_gfp.cpp 4.34 KB
Newer Older
kh1's avatar
kh1 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/******
* Elliptic curves over GF(p)
*
* (C) 2007 Martin Doering
*          Christoph Ludwig
*          Falko Strenzke
*     2008 Jack Lloyd
******/

#include <botan/curve_gfp.h>
#include <botan/bigint.h>
#include <assert.h>
#include <ostream>

namespace Botan {

17
void CurveGFp::set_shrd_mod(const SharedPointer<GFpModulus> mod)
kh1's avatar
kh1 committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
   {
   mp_mod = mod;
   mA.turn_off_sp_red_mul();// m.m. is not needed, must be trf. back
   mB.turn_off_sp_red_mul();// m.m. is not needed, must be trf. back
   //ok, above we destroy any evantually computated montg. mult. values,
   // but that won't influence performance in usual applications
   mA.set_shrd_mod(mod);
   mB.set_shrd_mod(mod);
   }

CurveGFp::CurveGFp(const GFpElement& a, const GFpElement& b,
                   const BigInt& p)
   : 	mA(a),
        mB(b)
   {
   if(!((p == mA.get_p()) && (p == mB.get_p())))
      {
      throw Invalid_Argument("could not construct curve: moduli of arguments differ");
      }
37
   SharedPointer<GFpModulus> p_mod = SharedPointer<GFpModulus>(new GFpModulus(p));
kh1's avatar
kh1 committed
38 39 40 41 42 43 44 45 46
   // the above is the creation of the GFpModuls object which will be shared point-wide
   // (in the context of a point of course)
   set_shrd_mod(p_mod);
   }
// copy constructor
CurveGFp::CurveGFp(const CurveGFp& other)
   :	mA(other.get_a()),
        mB(other.get_b())
   {
47
   mp_mod = SharedPointer<GFpModulus>(new GFpModulus(*other.mp_mod));
kh1's avatar
kh1 committed
48 49 50 51 52
   assert(mp_mod->p_equal_to(mA.get_p()));
   assert(mp_mod->p_equal_to(mB.get_p()));
   set_shrd_mod(mp_mod);
   if(other.mp_mres_a.get())
      {
53
      mp_mres_a = SharedPointer<GFpElement>(new GFpElement(*other.mp_mres_a));
kh1's avatar
kh1 committed
54 55 56
      }
   if(other.mp_mres_b.get())
      {
57
      mp_mres_b = SharedPointer<GFpElement>(new GFpElement(*other.mp_mres_b));
kh1's avatar
kh1 committed
58 59 60
      }
   if(other.mp_mres_one.get())
      {
61
      mp_mres_one = SharedPointer<GFpElement>(new GFpElement(*other.mp_mres_one));
kh1's avatar
kh1 committed
62 63 64 65 66 67 68 69 70 71 72 73 74
      }

   }

// assignment operator
const CurveGFp& CurveGFp::operator=(const CurveGFp& other)
   {
   // for exception safety...
   GFpElement a_tmp = other.mA;
   GFpElement b_tmp = other.mB;
   mA.swap(a_tmp);
   mB.swap(b_tmp);

75
   SharedPointer<GFpModulus> p_mod = SharedPointer<GFpModulus>(new GFpModulus(*other.mp_mod));
kh1's avatar
kh1 committed
76 77 78 79 80
   set_shrd_mod(p_mod);

   // exception safety note: no problem if we have a throw from here on...
   if(other.mp_mres_a.get())
      {
81
      mp_mres_a = SharedPointer<GFpElement>(new GFpElement(*other.mp_mres_a));
kh1's avatar
kh1 committed
82 83 84
      }
   if(other.mp_mres_b.get())
      {
85
      mp_mres_b = SharedPointer<GFpElement>(new GFpElement(*other.mp_mres_b));
kh1's avatar
kh1 committed
86 87 88
      }
   if(other.mp_mres_one.get())
      {
89
      mp_mres_one = SharedPointer<GFpElement>(new GFpElement(*other.mp_mres_one));
kh1's avatar
kh1 committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
      }
   return *this;
   }

// getters
const GFpElement& CurveGFp::get_a() const
   {
   return mA;
   }

const GFpElement& CurveGFp::get_b() const
   {
   return mB;
   }

const BigInt CurveGFp::get_p() const
   {
   assert(mp_mod.get() != 0);
   return mp_mod->get_p();
   }

// swaps the states of *this and other, does not throw
void CurveGFp::swap(CurveGFp& other)
   {
   mA.swap(other.mA);
   mB.swap(other.mB);
   mp_mod.swap(other.mp_mod);
   std::swap(mp_mres_a, other.mp_mres_a);
   std::swap(mp_mres_b, other.mp_mres_b);
   std::swap(mp_mres_one, other.mp_mres_one);
   }

GFpElement const CurveGFp::get_mres_a() const
   {
   if(mp_mres_a.get() == 0)
      {
126
      mp_mres_a = SharedPointer<GFpElement>(new GFpElement(mA));
kh1's avatar
kh1 committed
127 128 129 130 131 132 133 134 135 136
      mp_mres_a->turn_on_sp_red_mul();
      mp_mres_a->get_mres();
      }
   return GFpElement(*mp_mres_a);
   }

GFpElement const CurveGFp::get_mres_b() const
   {
   if(mp_mres_b.get() == 0)
      {
137
      mp_mres_b = SharedPointer<GFpElement>(new GFpElement(mB));
kh1's avatar
kh1 committed
138 139 140 141 142 143
      mp_mres_b->turn_on_sp_red_mul();
      mp_mres_b->get_mres();
      }
   return GFpElement(*mp_mres_b);
   }

144
SharedPointer<GFpElement const> const CurveGFp::get_mres_one() const
kh1's avatar
kh1 committed
145 146 147
   {
   if(mp_mres_one.get() == 0)
      {
148
      mp_mres_one = SharedPointer<GFpElement>(new GFpElement(mp_mod->get_p(), 1));
kh1's avatar
kh1 committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
      mp_mres_one->turn_on_sp_red_mul();
      mp_mres_one->get_mres();
      }
   return mp_mres_one;
   }

bool operator==(const CurveGFp& lhs, const CurveGFp& rhs)
   {
   return (lhs.get_p() == rhs.get_p() && lhs.get_a() == rhs.get_a() && lhs.get_b() == rhs.get_b());
   }

std::ostream& operator<<(std::ostream& output, const CurveGFp& elem)
   {
   return output << "y^2f = x^3 + (" << elem.get_a() << ")x + (" << elem.get_b() << ")";
   }

}