Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

modarith.h

00001 #ifndef CRYPTOPP_MODARITH_H 00002 #define CRYPTOPP_MODARITH_H 00003 00004 // implementations are in integer.cpp 00005 00006 #include "cryptlib.h" 00007 #include "misc.h" 00008 #include "integer.h" 00009 #include "algebra.h" 00010 00011 NAMESPACE_BEGIN(CryptoPP) 00012 00013 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<Integer>; 00014 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing<Integer>; 00015 CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain<Integer>; 00016 00017 //! ring of congruence classes modulo n 00018 /*! \note this implementation represents each congruence class as the smallest non-negative integer in that class */ 00019 class CRYPTOPP_DLL ModularArithmetic : public AbstractRing<Integer> 00020 { 00021 public: 00022 00023 typedef int RandomizationParameter; 00024 typedef Integer Element; 00025 00026 ModularArithmetic(const Integer &modulus = Integer::One()) 00027 : modulus(modulus), result((word)0, modulus.reg.size()) {} 00028 00029 ModularArithmetic(const ModularArithmetic &ma) 00030 : modulus(ma.modulus), result((word)0, modulus.reg.size()) {} 00031 00032 ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters 00033 00034 virtual ModularArithmetic * Clone() const {return new ModularArithmetic(*this);} 00035 00036 void DEREncode(BufferedTransformation &bt) const; 00037 00038 void DEREncodeElement(BufferedTransformation &out, const Element &a) const; 00039 void BERDecodeElement(BufferedTransformation &in, Element &a) const; 00040 00041 const Integer& GetModulus() const {return modulus;} 00042 void SetModulus(const Integer &newModulus) {modulus = newModulus; result.reg.resize(modulus.reg.size());} 00043 00044 virtual bool IsMontgomeryRepresentation() const {return false;} 00045 00046 virtual Integer ConvertIn(const Integer &a) const 00047 {return a%modulus;} 00048 00049 virtual Integer ConvertOut(const Integer &a) const 00050 {return a;} 00051 00052 const Integer& Half(const Integer &a) const; 00053 00054 bool Equal(const Integer &a, const Integer &b) const 00055 {return a==b;} 00056 00057 const Integer& Identity() const 00058 {return Integer::Zero();} 00059 00060 const Integer& Add(const Integer &a, const Integer &b) const; 00061 00062 Integer& Accumulate(Integer &a, const Integer &b) const; 00063 00064 const Integer& Inverse(const Integer &a) const; 00065 00066 const Integer& Subtract(const Integer &a, const Integer &b) const; 00067 00068 Integer& Reduce(Integer &a, const Integer &b) const; 00069 00070 const Integer& Double(const Integer &a) const 00071 {return Add(a, a);} 00072 00073 const Integer& MultiplicativeIdentity() const 00074 {return Integer::One();} 00075 00076 const Integer& Multiply(const Integer &a, const Integer &b) const 00077 {return result1 = a*b%modulus;} 00078 00079 const Integer& Square(const Integer &a) const 00080 {return result1 = a.Squared()%modulus;} 00081 00082 bool IsUnit(const Integer &a) const 00083 {return Integer::Gcd(a, modulus).IsUnit();} 00084 00085 const Integer& MultiplicativeInverse(const Integer &a) const 00086 {return result1 = a.InverseMod(modulus);} 00087 00088 const Integer& Divide(const Integer &a, const Integer &b) const 00089 {return Multiply(a, MultiplicativeInverse(b));} 00090 00091 Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const; 00092 00093 void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; 00094 00095 unsigned int MaxElementBitLength() const 00096 {return (modulus-1).BitCount();} 00097 00098 unsigned int MaxElementByteLength() const 00099 {return (modulus-1).ByteCount();} 00100 00101 Element RandomElement( RandomNumberGenerator &rng , const RandomizationParameter &ignore_for_now = 0 ) const 00102 // left RandomizationParameter arg as ref in case RandomizationParameter becomes a more complicated struct 00103 { 00104 return Element( rng , Integer( (long) 0) , modulus - Integer( (long) 1 ) ) ; 00105 } 00106 00107 bool operator==(const ModularArithmetic &rhs) const 00108 {return modulus == rhs.modulus;} 00109 00110 static const RandomizationParameter DefaultRandomizationParameter ; 00111 00112 protected: 00113 Integer modulus; 00114 mutable Integer result, result1; 00115 00116 }; 00117 00118 // const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ; 00119 00120 //! do modular arithmetics in Montgomery representation for increased speed 00121 /*! \note the Montgomery representation represents each congruence class [a] as a*r%n, where r is a convenient power of 2 */ 00122 class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic 00123 { 00124 public: 00125 MontgomeryRepresentation(const Integer &modulus); // modulus must be odd 00126 00127 virtual ModularArithmetic * Clone() const {return new MontgomeryRepresentation(*this);} 00128 00129 bool IsMontgomeryRepresentation() const {return true;} 00130 00131 Integer ConvertIn(const Integer &a) const 00132 {return (a<<(WORD_BITS*modulus.reg.size()))%modulus;} 00133 00134 Integer ConvertOut(const Integer &a) const; 00135 00136 const Integer& MultiplicativeIdentity() const 00137 {return result1 = Integer::Power2(WORD_BITS*modulus.reg.size())%modulus;} 00138 00139 const Integer& Multiply(const Integer &a, const Integer &b) const; 00140 00141 const Integer& Square(const Integer &a) const; 00142 00143 const Integer& MultiplicativeInverse(const Integer &a) const; 00144 00145 Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const 00146 {return AbstractRing<Integer>::CascadeExponentiate(x, e1, y, e2);} 00147 00148 void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const 00149 {AbstractRing<Integer>::SimultaneousExponentiate(results, base, exponents, exponentsCount);} 00150 00151 private: 00152 Integer u; 00153 mutable SecAlignedWordBlock workspace; 00154 }; 00155 00156 NAMESPACE_END 00157 00158 #endif

Generated on Fri Aug 27 13:36:34 2004 for Crypto++ by doxygen 1.3.8