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

gfpcrypt.cpp

00001 // dsa.cpp - written and placed in the public domain by Wei Dai 00002 00003 #include "pch.h" 00004 00005 #ifndef CRYPTOPP_IMPORTS 00006 00007 #include "gfpcrypt.h" 00008 #include "asn.h" 00009 #include "oids.h" 00010 #include "nbtheory.h" 00011 00012 NAMESPACE_BEGIN(CryptoPP) 00013 00014 void TestInstantiations_gfpcrypt() 00015 { 00016 GDSA<SHA>::Signer test; 00017 GDSA<SHA>::Verifier test1; 00018 DSA::Signer test5(NullRNG(), 100); 00019 DSA::Signer test2(test5); 00020 NR<SHA>::Signer test3; 00021 NR<SHA>::Verifier test4; 00022 DLIES<>::Encryptor test6; 00023 DLIES<>::Decryptor test7; 00024 } 00025 00026 void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) 00027 { 00028 Integer p, q, g; 00029 00030 if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) 00031 { 00032 q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); 00033 } 00034 else 00035 { 00036 int modulusSize = 1024; 00037 alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); 00038 00039 if (!DSA::IsValidPrimeLength(modulusSize)) 00040 throw InvalidArgument("DSA: not a valid prime length"); 00041 00042 SecByteBlock seed(SHA::DIGESTSIZE); 00043 Integer h; 00044 int c; 00045 00046 do 00047 { 00048 rng.GenerateBlock(seed, SHA::DIGESTSIZE); 00049 } while (!DSA::GeneratePrimes(seed, SHA::DIGESTSIZE*8, c, p, modulusSize, q)); 00050 00051 do 00052 { 00053 h.Randomize(rng, 2, p-2); 00054 g = a_exp_b_mod_c(h, (p-1)/q, p); 00055 } while (g <= 1); 00056 } 00057 00058 Initialize(p, q, g); 00059 } 00060 00061 bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const 00062 { 00063 bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level); 00064 pass = pass && DSA::IsValidPrimeLength(GetModulus().BitCount()); 00065 pass = pass && GetSubgroupOrder().BitCount() == 160; 00066 return pass; 00067 } 00068 00069 void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng, 00070 const byte *recoverableMessage, unsigned int recoverableMessageLength, 00071 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, 00072 byte *representative, unsigned int representativeBitLength) const 00073 { 00074 assert(recoverableMessageLength == 0); 00075 assert(hashIdentifier.second == 0); 00076 const unsigned int representativeByteLength = BitsToBytes(representativeBitLength); 00077 const unsigned int digestSize = hash.DigestSize(); 00078 const unsigned int paddingLength = SaturatingSubtract(representativeByteLength, digestSize); 00079 00080 memset(representative, 0, paddingLength); 00081 hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize)); 00082 00083 if (digestSize*8 > representativeBitLength) 00084 { 00085 Integer h(representative, representativeByteLength); 00086 h >>= representativeByteLength*8 - representativeBitLength; 00087 h.Encode(representative, representativeByteLength); 00088 } 00089 } 00090 00091 void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng, 00092 const byte *recoverableMessage, unsigned int recoverableMessageLength, 00093 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, 00094 byte *representative, unsigned int representativeBitLength) const 00095 { 00096 assert(recoverableMessageLength == 0); 00097 assert(hashIdentifier.second == 0); 00098 const unsigned int representativeByteLength = BitsToBytes(representativeBitLength); 00099 const unsigned int digestSize = hash.DigestSize(); 00100 const unsigned int paddingLength = SaturatingSubtract(representativeByteLength, digestSize); 00101 00102 memset(representative, 0, paddingLength); 00103 hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize)); 00104 00105 if (digestSize*8 >= representativeBitLength) 00106 { 00107 Integer h(representative, representativeByteLength); 00108 h >>= representativeByteLength*8 - representativeBitLength + 1; 00109 h.Encode(representative, representativeByteLength); 00110 } 00111 } 00112 00113 bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const 00114 { 00115 const Integer &p = GetModulus(), &q = GetSubgroupOrder(); 00116 00117 bool pass = true; 00118 pass = pass && p > Integer::One() && p.IsOdd(); 00119 pass = pass && q > Integer::One() && q.IsOdd(); 00120 00121 if (level >= 1) 00122 pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero(); 00123 if (level >= 2) 00124 pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2); 00125 00126 return pass; 00127 } 00128 00129 bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const 00130 { 00131 const Integer &p = GetModulus(), &q = GetSubgroupOrder(); 00132 00133 bool pass = true; 00134 pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative(); 00135 pass = pass && g < p && !IsIdentity(g); 00136 00137 if (level >= 1) 00138 { 00139 if (gpc) 00140 pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g; 00141 } 00142 if (level >= 2) 00143 { 00144 if (GetFieldType() == 2) 00145 pass = pass && Jacobi(g*g-4, p)==-1; 00146 00147 // verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly 00148 // and at most 1 bit is leaked if it's false 00149 bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable(); 00150 00151 if (fullValidate) 00152 pass = pass && IsIdentity(gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q)); 00153 else if (GetFieldType() == 1) 00154 pass = pass && Jacobi(g, p) == 1; 00155 } 00156 00157 return pass; 00158 } 00159 00160 void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) 00161 { 00162 Integer p, q, g; 00163 00164 if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) 00165 { 00166 q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); 00167 } 00168 else 00169 { 00170 int modulusSize, subgroupOrderSize; 00171 00172 if (!alg.GetIntValue("ModulusSize", modulusSize)) 00173 modulusSize = alg.GetIntValueWithDefault("KeySize", 2048); 00174 00175 if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize)) 00176 subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize); 00177 00178 PrimeAndGenerator pg; 00179 pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize); 00180 p = pg.Prime(); 00181 q = pg.SubPrime(); 00182 g = pg.Generator(); 00183 } 00184 00185 Initialize(p, q, g); 00186 } 00187 00188 Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const 00189 { 00190 Integer g(encoded, GetModulus().ByteCount()); 00191 if (!ValidateElement(1, g, NULL)) 00192 throw DL_BadElement(); 00193 return g; 00194 } 00195 00196 void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt) 00197 { 00198 BERSequenceDecoder parameters(bt); 00199 Integer p(parameters); 00200 Integer q(parameters); 00201 Integer g; 00202 if (parameters.EndReached()) 00203 { 00204 g = q; 00205 q = ComputeGroupOrder(p) / 2; 00206 } 00207 else 00208 g.BERDecode(parameters); 00209 parameters.MessageEnd(); 00210 00211 SetModulusAndSubgroupGenerator(p, g); 00212 SetSubgroupOrder(q); 00213 } 00214 00215 void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const 00216 { 00217 DERSequenceEncoder parameters(bt); 00218 GetModulus().DEREncode(parameters); 00219 m_q.DEREncode(parameters); 00220 GetSubgroupGenerator().DEREncode(parameters); 00221 parameters.MessageEnd(); 00222 } 00223 00224 bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const 00225 { 00226 return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue) 00227 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus); 00228 } 00229 00230 void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source) 00231 { 00232 AssignFromHelper(this, source) 00233 CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator) 00234 CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder) 00235 ; 00236 } 00237 00238 OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const 00239 { 00240 return ASN1::id_dsa(); 00241 } 00242 00243 void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const 00244 { 00245 ModularArithmetic ma(GetModulus()); 00246 ma.SimultaneousExponentiate(results, base, exponents, exponentsCount); 00247 } 00248 00249 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const 00250 { 00251 return a_times_b_mod_c(a, b, GetModulus()); 00252 } 00253 00254 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const 00255 { 00256 ModularArithmetic ma(GetModulus()); 00257 return ma.CascadeExponentiate(element1, exponent1, element2, exponent2); 00258 } 00259 00260 Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const 00261 { 00262 return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount()))); 00263 } 00264 00265 unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const 00266 { 00267 return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize); 00268 } 00269 00270 NAMESPACE_END 00271 00272 #endif

Generated on Wed Jul 21 19:15:26 2004 for Crypto++ by doxygen 1.3.7-20040704