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

Generated on Wed Jul 28 08:07:07 2004 for Crypto++ by doxygen 1.3.7