File indexing completed on 2025-01-18 09:55:06
0001
0002
0003
0004
0005
0006 #ifndef CRYPTOPP_POLYNOMI_H
0007 #define CRYPTOPP_POLYNOMI_H
0008
0009 #include "cryptlib.h"
0010 #include "secblock.h"
0011 #include "algebra.h"
0012 #include "misc.h"
0013
0014 #include <iosfwd>
0015 #include <vector>
0016
0017 NAMESPACE_BEGIN(CryptoPP)
0018
0019
0020
0021 template <class T> class PolynomialOver
0022 {
0023 public:
0024
0025
0026
0027 class DivideByZero : public Exception
0028 {
0029 public:
0030 DivideByZero() : Exception(OTHER_ERROR, "PolynomialOver<T>: division by zero") {}
0031 };
0032
0033
0034 class RandomizationParameter
0035 {
0036 public:
0037 RandomizationParameter(unsigned int coefficientCount, const typename T::RandomizationParameter &coefficientParameter )
0038 : m_coefficientCount(coefficientCount), m_coefficientParameter(coefficientParameter) {}
0039
0040 private:
0041 unsigned int m_coefficientCount;
0042 typename T::RandomizationParameter m_coefficientParameter;
0043 friend class PolynomialOver<T>;
0044 };
0045
0046 typedef T Ring;
0047 typedef typename T::Element CoefficientType;
0048
0049
0050
0051
0052
0053 PolynomialOver() {}
0054
0055
0056 PolynomialOver(const Ring &ring, unsigned int count)
0057 : m_coefficients((size_t)count, ring.Identity()) {}
0058
0059
0060 PolynomialOver(const PolynomialOver<Ring> &t)
0061 : m_coefficients(t.m_coefficients.size()) {*this = t;}
0062
0063
0064 PolynomialOver(const CoefficientType &element)
0065 : m_coefficients(1, element) {}
0066
0067
0068 template <typename Iterator> PolynomialOver(Iterator begin, Iterator end)
0069 : m_coefficients(begin, end) {}
0070
0071
0072 PolynomialOver(const char *str, const Ring &ring) {FromStr(str, ring);}
0073
0074
0075 PolynomialOver(const byte *encodedPolynomialOver, unsigned int byteCount);
0076
0077
0078 explicit PolynomialOver(const byte *BEREncodedPolynomialOver);
0079
0080
0081 explicit PolynomialOver(BufferedTransformation &bt);
0082
0083
0084 PolynomialOver(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring)
0085 {Randomize(rng, parameter, ring);}
0086
0087
0088
0089
0090
0091 int Degree(const Ring &ring) const {return int(CoefficientCount(ring))-1;}
0092
0093 unsigned int CoefficientCount(const Ring &ring) const;
0094
0095 CoefficientType GetCoefficient(unsigned int i, const Ring &ring) const;
0096
0097
0098
0099
0100
0101 PolynomialOver<Ring>& operator=(const PolynomialOver<Ring>& t);
0102
0103
0104 void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring);
0105
0106
0107 void SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring);
0108
0109
0110 void Negate(const Ring &ring);
0111
0112
0113 void swap(PolynomialOver<Ring> &t);
0114
0115
0116
0117
0118
0119 bool Equals(const PolynomialOver<Ring> &t, const Ring &ring) const;
0120 bool IsZero(const Ring &ring) const {return CoefficientCount(ring)==0;}
0121
0122 PolynomialOver<Ring> Plus(const PolynomialOver<Ring>& t, const Ring &ring) const;
0123 PolynomialOver<Ring> Minus(const PolynomialOver<Ring>& t, const Ring &ring) const;
0124 PolynomialOver<Ring> Inverse(const Ring &ring) const;
0125
0126 PolynomialOver<Ring> Times(const PolynomialOver<Ring>& t, const Ring &ring) const;
0127 PolynomialOver<Ring> DividedBy(const PolynomialOver<Ring>& t, const Ring &ring) const;
0128 PolynomialOver<Ring> Modulo(const PolynomialOver<Ring>& t, const Ring &ring) const;
0129 PolynomialOver<Ring> MultiplicativeInverse(const Ring &ring) const;
0130 bool IsUnit(const Ring &ring) const;
0131
0132 PolynomialOver<Ring>& Accumulate(const PolynomialOver<Ring>& t, const Ring &ring);
0133 PolynomialOver<Ring>& Reduce(const PolynomialOver<Ring>& t, const Ring &ring);
0134
0135
0136 PolynomialOver<Ring> Doubled(const Ring &ring) const {return Plus(*this, ring);}
0137
0138 PolynomialOver<Ring> Squared(const Ring &ring) const {return Times(*this, ring);}
0139
0140 CoefficientType EvaluateAt(const CoefficientType &x, const Ring &ring) const;
0141
0142 PolynomialOver<Ring>& ShiftLeft(unsigned int n, const Ring &ring);
0143 PolynomialOver<Ring>& ShiftRight(unsigned int n, const Ring &ring);
0144
0145
0146 static void Divide(PolynomialOver<Ring> &r, PolynomialOver<Ring> &q, const PolynomialOver<Ring> &a, const PolynomialOver<Ring> &d, const Ring &ring);
0147
0148
0149
0150
0151 std::istream& Input(std::istream &in, const Ring &ring);
0152 std::ostream& Output(std::ostream &out, const Ring &ring) const;
0153
0154
0155 private:
0156 void FromStr(const char *str, const Ring &ring);
0157
0158 std::vector<CoefficientType> m_coefficients;
0159 };
0160
0161
0162
0163 template <class T, int instance> class PolynomialOverFixedRing : private PolynomialOver<T>
0164 {
0165 typedef PolynomialOver<T> B;
0166 typedef PolynomialOverFixedRing<T, instance> ThisType;
0167
0168 public:
0169 typedef T Ring;
0170 typedef typename T::Element CoefficientType;
0171 typedef typename B::DivideByZero DivideByZero;
0172 typedef typename B::RandomizationParameter RandomizationParameter;
0173
0174
0175
0176
0177 PolynomialOverFixedRing(unsigned int count = 0) : B(ms_fixedRing, count) {}
0178
0179
0180 PolynomialOverFixedRing(const ThisType &t) : B(t) {}
0181
0182 explicit PolynomialOverFixedRing(const B &t) : B(t) {}
0183
0184
0185 PolynomialOverFixedRing(const CoefficientType &element) : B(element) {}
0186
0187
0188 template <typename Iterator> PolynomialOverFixedRing(Iterator first, Iterator last)
0189 : B(first, last) {}
0190
0191
0192 explicit PolynomialOverFixedRing(const char *str) : B(str, ms_fixedRing) {}
0193
0194
0195 PolynomialOverFixedRing(const byte *encodedPoly, unsigned int byteCount) : B(encodedPoly, byteCount) {}
0196
0197
0198 explicit PolynomialOverFixedRing(const byte *BEREncodedPoly) : B(BEREncodedPoly) {}
0199
0200
0201 explicit PolynomialOverFixedRing(BufferedTransformation &bt) : B(bt) {}
0202
0203
0204 PolynomialOverFixedRing(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) : B(rng, parameter, ms_fixedRing) {}
0205
0206 static const ThisType &Zero();
0207 static const ThisType &One();
0208
0209
0210
0211
0212
0213 int Degree() const {return B::Degree(ms_fixedRing);}
0214
0215 unsigned int CoefficientCount() const {return B::CoefficientCount(ms_fixedRing);}
0216
0217 CoefficientType GetCoefficient(unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);}
0218
0219 CoefficientType operator[](unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);}
0220
0221
0222
0223
0224
0225 ThisType& operator=(const ThisType& t) {B::operator=(t); return *this;}
0226
0227 ThisType& operator+=(const ThisType& t) {Accumulate(t, ms_fixedRing); return *this;}
0228
0229 ThisType& operator-=(const ThisType& t) {Reduce(t, ms_fixedRing); return *this;}
0230
0231 ThisType& operator*=(const ThisType& t) {return *this = *this*t;}
0232
0233 ThisType& operator/=(const ThisType& t) {return *this = *this/t;}
0234
0235 ThisType& operator%=(const ThisType& t) {return *this = *this%t;}
0236
0237
0238 ThisType& operator<<=(unsigned int n) {ShiftLeft(n, ms_fixedRing); return *this;}
0239
0240 ThisType& operator>>=(unsigned int n) {ShiftRight(n, ms_fixedRing); return *this;}
0241
0242
0243 void SetCoefficient(unsigned int i, const CoefficientType &value) {B::SetCoefficient(i, value, ms_fixedRing);}
0244
0245
0246 void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) {B::Randomize(rng, parameter, ms_fixedRing);}
0247
0248
0249 void Negate() {B::Negate(ms_fixedRing);}
0250
0251 void swap(ThisType &t) {B::swap(t);}
0252
0253
0254
0255
0256
0257 bool operator!() const {return CoefficientCount()==0;}
0258
0259 ThisType operator+() const {return *this;}
0260
0261 ThisType operator-() const {return ThisType(Inverse(ms_fixedRing));}
0262
0263
0264
0265
0266
0267 friend ThisType operator>>(ThisType a, unsigned int n) {return ThisType(a>>=n);}
0268
0269 friend ThisType operator<<(ThisType a, unsigned int n) {return ThisType(a<<=n);}
0270
0271
0272
0273
0274
0275 ThisType MultiplicativeInverse() const {return ThisType(B::MultiplicativeInverse(ms_fixedRing));}
0276
0277 bool IsUnit() const {return B::IsUnit(ms_fixedRing);}
0278
0279
0280 ThisType Doubled() const {return ThisType(B::Doubled(ms_fixedRing));}
0281
0282 ThisType Squared() const {return ThisType(B::Squared(ms_fixedRing));}
0283
0284 CoefficientType EvaluateAt(const CoefficientType &x) const {return B::EvaluateAt(x, ms_fixedRing);}
0285
0286
0287 static void Divide(ThisType &r, ThisType &q, const ThisType &a, const ThisType &d)
0288 {B::Divide(r, q, a, d, ms_fixedRing);}
0289
0290
0291
0292
0293
0294 friend std::istream& operator>>(std::istream& in, ThisType &a)
0295 {return a.Input(in, ms_fixedRing);}
0296
0297 friend std::ostream& operator<<(std::ostream& out, const ThisType &a)
0298 {return a.Output(out, ms_fixedRing);}
0299
0300
0301 private:
0302 struct NewOnePolynomial
0303 {
0304 ThisType * operator()() const
0305 {
0306 return new ThisType(ms_fixedRing.MultiplicativeIdentity());
0307 }
0308 };
0309
0310 static const Ring ms_fixedRing;
0311 };
0312
0313
0314 template <class T> class RingOfPolynomialsOver : public AbstractEuclideanDomain<PolynomialOver<T> >
0315 {
0316 public:
0317 typedef T CoefficientRing;
0318 typedef PolynomialOver<T> Element;
0319 typedef typename Element::CoefficientType CoefficientType;
0320 typedef typename Element::RandomizationParameter RandomizationParameter;
0321
0322 RingOfPolynomialsOver(const CoefficientRing &ring) : m_ring(ring) {}
0323
0324 Element RandomElement(RandomNumberGenerator &rng, const RandomizationParameter ¶meter)
0325 {return Element(rng, parameter, m_ring);}
0326
0327 bool Equal(const Element &a, const Element &b) const
0328 {return a.Equals(b, m_ring);}
0329
0330 const Element& Identity() const
0331 {return this->result = m_ring.Identity();}
0332
0333 const Element& Add(const Element &a, const Element &b) const
0334 {return this->result = a.Plus(b, m_ring);}
0335
0336 Element& Accumulate(Element &a, const Element &b) const
0337 {a.Accumulate(b, m_ring); return a;}
0338
0339 const Element& Inverse(const Element &a) const
0340 {return this->result = a.Inverse(m_ring);}
0341
0342 const Element& Subtract(const Element &a, const Element &b) const
0343 {return this->result = a.Minus(b, m_ring);}
0344
0345 Element& Reduce(Element &a, const Element &b) const
0346 {return a.Reduce(b, m_ring);}
0347
0348 const Element& Double(const Element &a) const
0349 {return this->result = a.Doubled(m_ring);}
0350
0351 const Element& MultiplicativeIdentity() const
0352 {return this->result = m_ring.MultiplicativeIdentity();}
0353
0354 const Element& Multiply(const Element &a, const Element &b) const
0355 {return this->result = a.Times(b, m_ring);}
0356
0357 const Element& Square(const Element &a) const
0358 {return this->result = a.Squared(m_ring);}
0359
0360 bool IsUnit(const Element &a) const
0361 {return a.IsUnit(m_ring);}
0362
0363 const Element& MultiplicativeInverse(const Element &a) const
0364 {return this->result = a.MultiplicativeInverse(m_ring);}
0365
0366 const Element& Divide(const Element &a, const Element &b) const
0367 {return this->result = a.DividedBy(b, m_ring);}
0368
0369 const Element& Mod(const Element &a, const Element &b) const
0370 {return this->result = a.Modulo(b, m_ring);}
0371
0372 void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const
0373 {Element::Divide(r, q, a, d, m_ring);}
0374
0375 class InterpolationFailed : public Exception
0376 {
0377 public:
0378 InterpolationFailed() : Exception(OTHER_ERROR, "RingOfPolynomialsOver<T>: interpolation failed") {}
0379 };
0380
0381 Element Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const;
0382
0383
0384 CoefficientType InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const;
0385
0386
0387
0388
0389
0390 protected:
0391 void CalculateAlpha(std::vector<CoefficientType> &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const;
0392
0393 CoefficientRing m_ring;
0394 };
0395
0396 template <class Ring, class Element>
0397 void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n);
0398 template <class Ring, class Element>
0399 void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n);
0400 template <class Ring, class Element>
0401 Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n);
0402
0403
0404 template <class T, int instance>
0405 inline bool operator==(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0406 {return a.Equals(b, a.ms_fixedRing);}
0407
0408 template <class T, int instance>
0409 inline bool operator!=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0410 {return !(a==b);}
0411
0412
0413 template <class T, int instance>
0414 inline bool operator> (const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0415 {return a.Degree() > b.Degree();}
0416
0417 template <class T, int instance>
0418 inline bool operator>=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0419 {return a.Degree() >= b.Degree();}
0420
0421 template <class T, int instance>
0422 inline bool operator< (const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0423 {return a.Degree() < b.Degree();}
0424
0425 template <class T, int instance>
0426 inline bool operator<=(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0427 {return a.Degree() <= b.Degree();}
0428
0429
0430 template <class T, int instance>
0431 inline CryptoPP::PolynomialOverFixedRing<T, instance> operator+(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0432 {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Plus(b, a.ms_fixedRing));}
0433
0434 template <class T, int instance>
0435 inline CryptoPP::PolynomialOverFixedRing<T, instance> operator-(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0436 {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Minus(b, a.ms_fixedRing));}
0437
0438 template <class T, int instance>
0439 inline CryptoPP::PolynomialOverFixedRing<T, instance> operator*(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0440 {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Times(b, a.ms_fixedRing));}
0441
0442 template <class T, int instance>
0443 inline CryptoPP::PolynomialOverFixedRing<T, instance> operator/(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0444 {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.DividedBy(b, a.ms_fixedRing));}
0445
0446 template <class T, int instance>
0447 inline CryptoPP::PolynomialOverFixedRing<T, instance> operator%(const CryptoPP::PolynomialOverFixedRing<T, instance> &a, const CryptoPP::PolynomialOverFixedRing<T, instance> &b)
0448 {return CryptoPP::PolynomialOverFixedRing<T, instance>(a.Modulo(b, a.ms_fixedRing));}
0449
0450 NAMESPACE_END
0451
0452 NAMESPACE_BEGIN(std)
0453 template<class T> inline void swap(CryptoPP::PolynomialOver<T> &a, CryptoPP::PolynomialOver<T> &b)
0454 {
0455 a.swap(b);
0456 }
0457 template<class T, int i> inline void swap(CryptoPP::PolynomialOverFixedRing<T,i> &a, CryptoPP::PolynomialOverFixedRing<T,i> &b)
0458 {
0459 a.swap(b);
0460 }
0461 NAMESPACE_END
0462
0463 #endif