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