File indexing completed on 2025-01-18 09:54:53
0001
0002
0003
0004
0005
0006 #ifndef CRYPTOPP_ALGEBRA_H
0007 #define CRYPTOPP_ALGEBRA_H
0008
0009 #include "config.h"
0010 #include "integer.h"
0011 #include "misc.h"
0012
0013 NAMESPACE_BEGIN(CryptoPP)
0014
0015 class Integer;
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 template <class T> class CRYPTOPP_NO_VTABLE AbstractGroup
0027 {
0028 public:
0029 typedef T Element;
0030
0031 virtual ~AbstractGroup() {}
0032
0033
0034
0035
0036
0037
0038 virtual bool Equal(const Element &a, const Element &b) const =0;
0039
0040
0041
0042 virtual const Element& Identity() const =0;
0043
0044
0045
0046
0047
0048 virtual const Element& Add(const Element &a, const Element &b) const =0;
0049
0050
0051
0052
0053 virtual const Element& Inverse(const Element &a) const =0;
0054
0055
0056
0057 virtual bool InversionIsFast() const {return false;}
0058
0059
0060
0061
0062 virtual const Element& Double(const Element &a) const;
0063
0064
0065
0066
0067
0068 virtual const Element& Subtract(const Element &a, const Element &b) const;
0069
0070
0071
0072
0073
0074 virtual Element& Accumulate(Element &a, const Element &b) const;
0075
0076
0077
0078
0079
0080 virtual Element& Reduce(Element &a, const Element &b) const;
0081
0082
0083
0084
0085
0086 virtual Element ScalarMultiply(const Element &a, const Integer &e) const;
0087
0088
0089
0090
0091
0092
0093
0094 virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 virtual void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
0107 };
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 template <class T> class CRYPTOPP_NO_VTABLE AbstractRing : public AbstractGroup<T>
0119 {
0120 public:
0121 typedef T Element;
0122
0123
0124 AbstractRing() {m_mg.m_pRing = this;}
0125
0126
0127
0128 AbstractRing(const AbstractRing &source)
0129 {CRYPTOPP_UNUSED(source); m_mg.m_pRing = this;}
0130
0131
0132
0133 AbstractRing& operator=(const AbstractRing &source)
0134 {CRYPTOPP_UNUSED(source); return *this;}
0135
0136
0137
0138
0139 virtual bool IsUnit(const Element &a) const =0;
0140
0141
0142
0143 virtual const Element& MultiplicativeIdentity() const =0;
0144
0145
0146
0147
0148
0149 virtual const Element& Multiply(const Element &a, const Element &b) const =0;
0150
0151
0152
0153 virtual const Element& MultiplicativeInverse(const Element &a) const =0;
0154
0155
0156
0157
0158 virtual const Element& Square(const Element &a) const;
0159
0160
0161
0162
0163
0164 virtual const Element& Divide(const Element &a, const Element &b) const;
0165
0166
0167
0168
0169
0170 virtual Element Exponentiate(const Element &a, const Integer &e) const;
0171
0172
0173
0174
0175
0176
0177
0178 virtual Element CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const;
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
0191
0192
0193
0194 virtual const AbstractGroup<T>& MultiplicativeGroup() const
0195 {return m_mg;}
0196
0197 private:
0198 class MultiplicativeGroupT : public AbstractGroup<T>
0199 {
0200 public:
0201 const AbstractRing<T>& GetRing() const
0202 {return *m_pRing;}
0203
0204 bool Equal(const Element &a, const Element &b) const
0205 {return GetRing().Equal(a, b);}
0206
0207 const Element& Identity() const
0208 {return GetRing().MultiplicativeIdentity();}
0209
0210 const Element& Add(const Element &a, const Element &b) const
0211 {return GetRing().Multiply(a, b);}
0212
0213 Element& Accumulate(Element &a, const Element &b) const
0214 {return a = GetRing().Multiply(a, b);}
0215
0216 const Element& Inverse(const Element &a) const
0217 {return GetRing().MultiplicativeInverse(a);}
0218
0219 const Element& Subtract(const Element &a, const Element &b) const
0220 {return GetRing().Divide(a, b);}
0221
0222 Element& Reduce(Element &a, const Element &b) const
0223 {return a = GetRing().Divide(a, b);}
0224
0225 const Element& Double(const Element &a) const
0226 {return GetRing().Square(a);}
0227
0228 Element ScalarMultiply(const Element &a, const Integer &e) const
0229 {return GetRing().Exponentiate(a, e);}
0230
0231 Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
0232 {return GetRing().CascadeExponentiate(x, e1, y, e2);}
0233
0234 void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
0235 {GetRing().SimultaneousExponentiate(results, base, exponents, exponentsCount);}
0236
0237 const AbstractRing<T> *m_pRing;
0238 };
0239
0240 MultiplicativeGroupT m_mg;
0241 };
0242
0243
0244
0245
0246
0247
0248 template <class T, class E = Integer>
0249 struct BaseAndExponent
0250 {
0251 public:
0252 BaseAndExponent() {}
0253 BaseAndExponent(const T &base, const E &exponent) : base(base), exponent(exponent) {}
0254 bool operator<(const BaseAndExponent<T, E> &rhs) const {return exponent < rhs.exponent;}
0255 T base;
0256 E exponent;
0257 };
0258
0259
0260 template <class Element, class Iterator>
0261 Element GeneralCascadeMultiplication(const AbstractGroup<Element> &group, Iterator begin, Iterator end);
0262 template <class Element, class Iterator>
0263 Element GeneralCascadeExponentiation(const AbstractRing<Element> &ring, Iterator begin, Iterator end);
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 template <class T> class CRYPTOPP_NO_VTABLE AbstractEuclideanDomain : public AbstractRing<T>
0277 {
0278 public:
0279 typedef T Element;
0280
0281
0282
0283
0284
0285
0286 virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0;
0287
0288
0289
0290
0291
0292 virtual const Element& Mod(const Element &a, const Element &b) const =0;
0293
0294
0295
0296
0297
0298 virtual const Element& Gcd(const Element &a, const Element &b) const;
0299
0300 protected:
0301 mutable Element result;
0302 };
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 template <class T> class EuclideanDomainOf : public AbstractEuclideanDomain<T>
0316 {
0317 public:
0318 typedef T Element;
0319
0320 EuclideanDomainOf() {}
0321
0322 bool Equal(const Element &a, const Element &b) const
0323 {return a==b;}
0324
0325 const Element& Identity() const
0326 {return Element::Zero();}
0327
0328 const Element& Add(const Element &a, const Element &b) const
0329 {return result = a+b;}
0330
0331 Element& Accumulate(Element &a, const Element &b) const
0332 {return a+=b;}
0333
0334 const Element& Inverse(const Element &a) const
0335 {return result = -a;}
0336
0337 const Element& Subtract(const Element &a, const Element &b) const
0338 {return result = a-b;}
0339
0340 Element& Reduce(Element &a, const Element &b) const
0341 {return a-=b;}
0342
0343 const Element& Double(const Element &a) const
0344 {return result = a.Doubled();}
0345
0346 const Element& MultiplicativeIdentity() const
0347 {return Element::One();}
0348
0349 const Element& Multiply(const Element &a, const Element &b) const
0350 {return result = a*b;}
0351
0352 const Element& Square(const Element &a) const
0353 {return result = a.Squared();}
0354
0355 bool IsUnit(const Element &a) const
0356 {return a.IsUnit();}
0357
0358 const Element& MultiplicativeInverse(const Element &a) const
0359 {return result = a.MultiplicativeInverse();}
0360
0361 const Element& Divide(const Element &a, const Element &b) const
0362 {return result = a/b;}
0363
0364 const Element& Mod(const Element &a, const Element &b) const
0365 {return result = a%b;}
0366
0367 void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const
0368 {Element::Divide(r, q, a, d);}
0369
0370 bool operator==(const EuclideanDomainOf<T> &rhs) const
0371 {CRYPTOPP_UNUSED(rhs); return true;}
0372
0373 private:
0374 mutable Element result;
0375 };
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 template <class T> class QuotientRing : public AbstractRing<typename T::Element>
0387 {
0388 public:
0389 typedef T EuclideanDomain;
0390 typedef typename T::Element Element;
0391
0392 QuotientRing(const EuclideanDomain &domain, const Element &modulus)
0393 : m_domain(domain), m_modulus(modulus) {}
0394
0395 const EuclideanDomain & GetDomain() const
0396 {return m_domain;}
0397
0398 const Element& GetModulus() const
0399 {return m_modulus;}
0400
0401 bool Equal(const Element &a, const Element &b) const
0402 {return m_domain.Equal(m_domain.Mod(m_domain.Subtract(a, b), m_modulus), m_domain.Identity());}
0403
0404 const Element& Identity() const
0405 {return m_domain.Identity();}
0406
0407 const Element& Add(const Element &a, const Element &b) const
0408 {return m_domain.Add(a, b);}
0409
0410 Element& Accumulate(Element &a, const Element &b) const
0411 {return m_domain.Accumulate(a, b);}
0412
0413 const Element& Inverse(const Element &a) const
0414 {return m_domain.Inverse(a);}
0415
0416 const Element& Subtract(const Element &a, const Element &b) const
0417 {return m_domain.Subtract(a, b);}
0418
0419 Element& Reduce(Element &a, const Element &b) const
0420 {return m_domain.Reduce(a, b);}
0421
0422 const Element& Double(const Element &a) const
0423 {return m_domain.Double(a);}
0424
0425 bool IsUnit(const Element &a) const
0426 {return m_domain.IsUnit(m_domain.Gcd(a, m_modulus));}
0427
0428 const Element& MultiplicativeIdentity() const
0429 {return m_domain.MultiplicativeIdentity();}
0430
0431 const Element& Multiply(const Element &a, const Element &b) const
0432 {return m_domain.Mod(m_domain.Multiply(a, b), m_modulus);}
0433
0434 const Element& Square(const Element &a) const
0435 {return m_domain.Mod(m_domain.Square(a), m_modulus);}
0436
0437 const Element& MultiplicativeInverse(const Element &a) const;
0438
0439 bool operator==(const QuotientRing<T> &rhs) const
0440 {return m_domain == rhs.m_domain && m_modulus == rhs.m_modulus;}
0441
0442 protected:
0443 EuclideanDomain m_domain;
0444 Element m_modulus;
0445 };
0446
0447 NAMESPACE_END
0448
0449 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
0450 #include "algebra.cpp"
0451 #endif
0452
0453 #endif