00001 #ifndef CRYPTOPP_XTR_H
00002 #define CRYPTOPP_XTR_H
00003
00008 #include "modarith.h"
00009
00010 NAMESPACE_BEGIN(CryptoPP)
00011
00013 class GFP2Element
00014 {
00015 public:
00016 GFP2Element() {}
00017 GFP2Element(const Integer &c1, const Integer &c2) : c1(c1), c2(c2) {}
00018 GFP2Element(const byte *encodedElement, unsigned int size)
00019 : c1(encodedElement, size/2), c2(encodedElement+size/2, size/2) {}
00020
00021 void Encode(byte *encodedElement, unsigned int size)
00022 {
00023 c1.Encode(encodedElement, size/2);
00024 c2.Encode(encodedElement+size/2, size/2);
00025 }
00026
00027 bool operator==(const GFP2Element &rhs) {return c1 == rhs.c1 && c2 == rhs.c2;}
00028 bool operator!=(const GFP2Element &rhs) {return !operator==(rhs);}
00029
00030 void swap(GFP2Element &a)
00031 {
00032 c1.swap(a.c1);
00033 c2.swap(a.c2);
00034 }
00035
00036 static GFP2Element & Zero();
00037
00038 Integer c1, c2;
00039 };
00040
00042 template <class F>
00043 class GFP2_ONB : public AbstractRing<GFP2Element>
00044 {
00045 public:
00046 typedef F BaseField;
00047
00048 GFP2_ONB(const Integer &p) : modp(p) {assert(p%3 == 2);}
00049
00050 const Integer& GetModulus() const {return modp.GetModulus();}
00051
00052 GFP2Element ConvertIn(const Integer &a) const
00053 {
00054 t = modp.Inverse(modp.ConvertIn(a));
00055 return GFP2Element(t, t);
00056 }
00057
00058 GFP2Element ConvertIn(const GFP2Element &a) const
00059 {return GFP2Element(modp.ConvertIn(a.c1), modp.ConvertIn(a.c2));}
00060
00061 GFP2Element ConvertOut(const GFP2Element &a) const
00062 {return GFP2Element(modp.ConvertOut(a.c1), modp.ConvertOut(a.c2));}
00063
00064 bool Equal(const GFP2Element &a, const GFP2Element &b) const
00065 {
00066 return modp.Equal(a.c1, b.c1) && modp.Equal(a.c2, b.c2);
00067 }
00068
00069 const Element& Zero() const
00070 {
00071 return GFP2Element::Zero();
00072 }
00073
00074 const Element& Add(const Element &a, const Element &b) const
00075 {
00076 result.c1 = modp.Add(a.c1, b.c1);
00077 result.c2 = modp.Add(a.c2, b.c2);
00078 return result;
00079 }
00080
00081 const Element& Inverse(const Element &a) const
00082 {
00083 result.c1 = modp.Inverse(a.c1);
00084 result.c2 = modp.Inverse(a.c2);
00085 return result;
00086 }
00087
00088 const Element& Double(const Element &a) const
00089 {
00090 result.c1 = modp.Double(a.c1);
00091 result.c2 = modp.Double(a.c2);
00092 return result;
00093 }
00094
00095 const Element& Subtract(const Element &a, const Element &b) const
00096 {
00097 result.c1 = modp.Subtract(a.c1, b.c1);
00098 result.c2 = modp.Subtract(a.c2, b.c2);
00099 return result;
00100 }
00101
00102 Element& Accumulate(Element &a, const Element &b) const
00103 {
00104 modp.Accumulate(a.c1, b.c1);
00105 modp.Accumulate(a.c2, b.c2);
00106 return a;
00107 }
00108
00109 Element& Reduce(Element &a, const Element &b) const
00110 {
00111 modp.Reduce(a.c1, b.c1);
00112 modp.Reduce(a.c2, b.c2);
00113 return a;
00114 }
00115
00116 bool IsUnit(const Element &a) const
00117 {
00118 return a.c1.NotZero() || a.c2.NotZero();
00119 }
00120
00121 const Element& One() const
00122 {
00123 result.c1 = result.c2 = modp.Inverse(modp.One());
00124 return result;
00125 }
00126
00127 const Element& Multiply(const Element &a, const Element &b) const
00128 {
00129 t = modp.Add(a.c1, a.c2);
00130 t = modp.Multiply(t, modp.Add(b.c1, b.c2));
00131 result.c1 = modp.Multiply(a.c1, b.c1);
00132 result.c2 = modp.Multiply(a.c2, b.c2);
00133 result.c1.swap(result.c2);
00134 modp.Reduce(t, result.c1);
00135 modp.Reduce(t, result.c2);
00136 modp.Reduce(result.c1, t);
00137 modp.Reduce(result.c2, t);
00138 return result;
00139 }
00140
00141 const Element& MultiplicativeInverse(const Element &a) const
00142 {
00143 return result = Exponentiate(a, modp.GetModulus()-2);
00144 }
00145
00146 const Element& Square(const Element &a) const
00147 {
00148 const Integer &ac1 = (&a == &result) ? (t = a.c1) : a.c1;
00149 result.c1 = modp.Multiply(modp.Subtract(modp.Subtract(a.c2, a.c1), a.c1), a.c2);
00150 result.c2 = modp.Multiply(modp.Subtract(modp.Subtract(ac1, a.c2), a.c2), ac1);
00151 return result;
00152 }
00153
00154 Element Exponentiate(const Element &a, const Integer &e) const
00155 {
00156 Integer edivp, emodp;
00157 Integer::Divide(emodp, edivp, e, modp.GetModulus());
00158 Element b = PthPower(a);
00159 return AbstractRing<GFP2Element>::CascadeExponentiate(a, emodp, b, edivp);
00160 }
00161
00162 const Element & PthPower(const Element &a) const
00163 {
00164 result = a;
00165 result.c1.swap(result.c2);
00166 return result;
00167 }
00168
00169 void RaiseToPthPower(Element &a) const
00170 {
00171 a.c1.swap(a.c2);
00172 }
00173
00174
00175 const Element & SpecialOperation1(const Element &a) const
00176 {
00177 assert(&a != &result);
00178 result = Square(a);
00179 modp.Reduce(result.c1, a.c2);
00180 modp.Reduce(result.c1, a.c2);
00181 modp.Reduce(result.c2, a.c1);
00182 modp.Reduce(result.c2, a.c1);
00183 return result;
00184 }
00185
00186
00187 const Element & SpecialOperation2(const Element &x, const Element &y, const Element &z) const
00188 {
00189 assert(&x != &result && &y != &result && &z != &result);
00190 t = modp.Add(x.c2, y.c2);
00191 result.c1 = modp.Multiply(z.c1, modp.Subtract(y.c1, t));
00192 modp.Accumulate(result.c1, modp.Multiply(z.c2, modp.Subtract(t, x.c1)));
00193 t = modp.Add(x.c1, y.c1);
00194 result.c2 = modp.Multiply(z.c2, modp.Subtract(y.c2, t));
00195 modp.Accumulate(result.c2, modp.Multiply(z.c1, modp.Subtract(t, x.c2)));
00196 return result;
00197 }
00198
00199 protected:
00200 BaseField modp;
00201 mutable GFP2Element result;
00202 mutable Integer t;
00203 };
00204
00205 void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits);
00206
00207 GFP2Element XTR_Exponentiate(const GFP2Element &b, const Integer &e, const Integer &p);
00208
00209 NAMESPACE_END
00210
00211 #endif