123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- #ifndef CRYPTOPP_XTR_H
- #define CRYPTOPP_XTR_H
- /// \file xtr.h
- /// \brief The XTR public key system
- /// \details The XTR public key system by Arjen K. Lenstra and Eric R. Verheul
- #include "cryptlib.h"
- #include "modarith.h"
- #include "integer.h"
- #include "algebra.h"
- NAMESPACE_BEGIN(CryptoPP)
- /// \brief an element of GF(p^2)
- class GFP2Element
- {
- public:
- GFP2Element() {}
- GFP2Element(const Integer &c1, const Integer &c2) : c1(c1), c2(c2) {}
- GFP2Element(const byte *encodedElement, unsigned int size)
- : c1(encodedElement, size/2), c2(encodedElement+size/2, size/2) {}
- void Encode(byte *encodedElement, unsigned int size)
- {
- c1.Encode(encodedElement, size/2);
- c2.Encode(encodedElement+size/2, size/2);
- }
- bool operator==(const GFP2Element &rhs) const {return c1 == rhs.c1 && c2 == rhs.c2;}
- bool operator!=(const GFP2Element &rhs) const {return !operator==(rhs);}
- void swap(GFP2Element &a)
- {
- c1.swap(a.c1);
- c2.swap(a.c2);
- }
- static const GFP2Element & Zero();
- Integer c1, c2;
- };
- /// \brief GF(p^2), optimal normal basis
- template <class F>
- class GFP2_ONB : public AbstractRing<GFP2Element>
- {
- public:
- typedef F BaseField;
- GFP2_ONB(const Integer &p) : modp(p)
- {
- if (p%3 != 2)
- throw InvalidArgument("GFP2_ONB: modulus must be equivalent to 2 mod 3");
- }
- const Integer& GetModulus() const {return modp.GetModulus();}
- GFP2Element ConvertIn(const Integer &a) const
- {
- t = modp.Inverse(modp.ConvertIn(a));
- return GFP2Element(t, t);
- }
- GFP2Element ConvertIn(const GFP2Element &a) const
- {return GFP2Element(modp.ConvertIn(a.c1), modp.ConvertIn(a.c2));}
- GFP2Element ConvertOut(const GFP2Element &a) const
- {return GFP2Element(modp.ConvertOut(a.c1), modp.ConvertOut(a.c2));}
- bool Equal(const GFP2Element &a, const GFP2Element &b) const
- {
- return modp.Equal(a.c1, b.c1) && modp.Equal(a.c2, b.c2);
- }
- const Element& Identity() const
- {
- return GFP2Element::Zero();
- }
- const Element& Add(const Element &a, const Element &b) const
- {
- result.c1 = modp.Add(a.c1, b.c1);
- result.c2 = modp.Add(a.c2, b.c2);
- return result;
- }
- const Element& Inverse(const Element &a) const
- {
- result.c1 = modp.Inverse(a.c1);
- result.c2 = modp.Inverse(a.c2);
- return result;
- }
- const Element& Double(const Element &a) const
- {
- result.c1 = modp.Double(a.c1);
- result.c2 = modp.Double(a.c2);
- return result;
- }
- const Element& Subtract(const Element &a, const Element &b) const
- {
- result.c1 = modp.Subtract(a.c1, b.c1);
- result.c2 = modp.Subtract(a.c2, b.c2);
- return result;
- }
- Element& Accumulate(Element &a, const Element &b) const
- {
- modp.Accumulate(a.c1, b.c1);
- modp.Accumulate(a.c2, b.c2);
- return a;
- }
- Element& Reduce(Element &a, const Element &b) const
- {
- modp.Reduce(a.c1, b.c1);
- modp.Reduce(a.c2, b.c2);
- return a;
- }
- bool IsUnit(const Element &a) const
- {
- return a.c1.NotZero() || a.c2.NotZero();
- }
- const Element& MultiplicativeIdentity() const
- {
- result.c1 = result.c2 = modp.Inverse(modp.MultiplicativeIdentity());
- return result;
- }
- const Element& Multiply(const Element &a, const Element &b) const
- {
- t = modp.Add(a.c1, a.c2);
- t = modp.Multiply(t, modp.Add(b.c1, b.c2));
- result.c1 = modp.Multiply(a.c1, b.c1);
- result.c2 = modp.Multiply(a.c2, b.c2);
- result.c1.swap(result.c2);
- modp.Reduce(t, result.c1);
- modp.Reduce(t, result.c2);
- modp.Reduce(result.c1, t);
- modp.Reduce(result.c2, t);
- return result;
- }
- const Element& MultiplicativeInverse(const Element &a) const
- {
- return result = Exponentiate(a, modp.GetModulus()-2);
- }
- const Element& Square(const Element &a) const
- {
- const Integer &ac1 = (&a == &result) ? (t = a.c1) : a.c1;
- result.c1 = modp.Multiply(modp.Subtract(modp.Subtract(a.c2, a.c1), a.c1), a.c2);
- result.c2 = modp.Multiply(modp.Subtract(modp.Subtract(ac1, a.c2), a.c2), ac1);
- return result;
- }
- Element Exponentiate(const Element &a, const Integer &e) const
- {
- Integer edivp, emodp;
- Integer::Divide(emodp, edivp, e, modp.GetModulus());
- Element b = PthPower(a);
- return AbstractRing<GFP2Element>::CascadeExponentiate(a, emodp, b, edivp);
- }
- const Element & PthPower(const Element &a) const
- {
- result = a;
- result.c1.swap(result.c2);
- return result;
- }
- void RaiseToPthPower(Element &a) const
- {
- a.c1.swap(a.c2);
- }
- // a^2 - 2a^p
- const Element & SpecialOperation1(const Element &a) const
- {
- CRYPTOPP_ASSERT(&a != &result);
- result = Square(a);
- modp.Reduce(result.c1, a.c2);
- modp.Reduce(result.c1, a.c2);
- modp.Reduce(result.c2, a.c1);
- modp.Reduce(result.c2, a.c1);
- return result;
- }
- // x * z - y * z^p
- const Element & SpecialOperation2(const Element &x, const Element &y, const Element &z) const
- {
- CRYPTOPP_ASSERT(&x != &result && &y != &result && &z != &result);
- t = modp.Add(x.c2, y.c2);
- result.c1 = modp.Multiply(z.c1, modp.Subtract(y.c1, t));
- modp.Accumulate(result.c1, modp.Multiply(z.c2, modp.Subtract(t, x.c1)));
- t = modp.Add(x.c1, y.c1);
- result.c2 = modp.Multiply(z.c2, modp.Subtract(y.c2, t));
- modp.Accumulate(result.c2, modp.Multiply(z.c1, modp.Subtract(t, x.c2)));
- return result;
- }
- protected:
- BaseField modp;
- mutable GFP2Element result;
- mutable Integer t;
- };
- /// \brief Creates primes p,q and generator g for XTR
- void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits);
- GFP2Element XTR_Exponentiate(const GFP2Element &b, const Integer &e, const Integer &p);
- NAMESPACE_END
- #endif
|