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