Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound 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 Integer NR_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen)
00070 {
00071         Integer h;
00072         if (digestLen*8 < modulusBits)
00073                 h.Decode(digest, digestLen);
00074         else
00075         {
00076                 h.Decode(digest, BitsToBytes(modulusBits));
00077                 h >>= BitsToBytes(modulusBits)*8 - modulusBits + 1;
00078         }
00079         return h;
00080 }
00081 
00082 Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen)
00083 {
00084         Integer h;
00085         if (digestLen*8 <= modulusBits)
00086                 h.Decode(digest, digestLen);
00087         else
00088         {
00089                 h.Decode(digest, BitsToBytes(modulusBits));
00090                 h >>= BitsToBytes(modulusBits)*8 - modulusBits;
00091         }
00092         return h;
00093 }
00094 
00095 bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
00096 {
00097         const Integer &p = GetModulus(), &q = GetSubgroupOrder();
00098 
00099         bool pass = true;
00100         pass = pass && p > Integer::One() && p.IsOdd();
00101         pass = pass && q > Integer::One() && q.IsOdd();
00102 
00103         if (level >= 1)
00104                 pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
00105         if (level >= 2)
00106                 pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
00107 
00108         return pass;
00109 }
00110 
00111 bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
00112 {
00113         const Integer &p = GetModulus(), &q = GetSubgroupOrder();
00114 
00115         bool pass = true;
00116         pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
00117         pass = pass && g < p && !IsIdentity(g);
00118 
00119         if (level >= 1)
00120         {
00121                 if (gpc)
00122                         pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
00123         }
00124         if (level >= 2)
00125         {
00126                 if (GetFieldType() == 2)
00127                         pass = pass && Jacobi(g*g-4, p)==-1;
00128 
00129                 // verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly
00130                 // and at most 1 bit is leaked if it's false
00131                 bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable();
00132 
00133                 if (fullValidate)
00134                         pass = pass && IsIdentity(gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q));
00135                 else if (GetFieldType() == 1)
00136                         pass = pass && Jacobi(g, p) == 1;
00137         }
00138 
00139         return pass;
00140 }
00141 
00142 void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
00143 {
00144         Integer p, q, g;
00145         
00146         if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
00147         {
00148                 q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
00149         }
00150         else
00151         {
00152                 int modulusSize, subgroupOrderSize;
00153 
00154                 if (!alg.GetIntValue("ModulusSize", modulusSize))
00155                         modulusSize = alg.GetIntValueWithDefault("KeySize", 2048);
00156 
00157                 if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize))
00158                         subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize);
00159 
00160                 PrimeAndGenerator pg;
00161                 pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize);
00162                 p = pg.Prime();
00163                 q = pg.SubPrime();
00164                 g = pg.Generator();
00165         }
00166 
00167         Initialize(p, q, g);
00168 }
00169 
00170 Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const
00171 {
00172         Integer g(encoded, GetModulus().ByteCount());
00173         if (!ValidateElement(1, g, NULL))
00174                 throw DL_BadElement();
00175         return g;
00176 }
00177 
00178 void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt)
00179 {
00180         BERSequenceDecoder parameters(bt);
00181                 Integer p(parameters);
00182                 Integer q(parameters);
00183                 Integer g;
00184                 if (parameters.EndReached())
00185                 {
00186                         g = q;
00187                         q = ComputeGroupOrder(p) / 2;
00188                 }
00189                 else
00190                         g.BERDecode(parameters);
00191         parameters.MessageEnd();
00192 
00193         SetModulusAndSubgroupGenerator(p, g);
00194         SetSubgroupOrder(q);
00195 }
00196 
00197 void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const
00198 {
00199         DERSequenceEncoder parameters(bt);
00200                 GetModulus().DEREncode(parameters);
00201                 m_q.DEREncode(parameters);
00202                 GetSubgroupGenerator().DEREncode(parameters);
00203         parameters.MessageEnd();
00204 }
00205 
00206 bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00207 {
00208         return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue)
00209                 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus);
00210 }
00211 
00212 void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source)
00213 {
00214         AssignFromHelper(this, source)
00215                 CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator)
00216                 CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
00217                 ;
00218 }
00219 
00220 OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const
00221 {
00222         return ASN1::id_dsa();
00223 }
00224 
00225 void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
00226 {
00227         ModularArithmetic ma(GetModulus());
00228         ma.SimultaneousExponentiate(results, base, exponents, exponentsCount);
00229 }
00230 
00231 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const
00232 {
00233         return a_times_b_mod_c(a, b, GetModulus());
00234 }
00235 
00236 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
00237 {
00238         ModularArithmetic ma(GetModulus());
00239         return ma.CascadeExponentiate(element1, exponent1, element2, exponent2);
00240 }
00241 
00242 Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const
00243 {
00244         return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount())));
00245 }
00246 
00247 unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
00248 {
00249         return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize);
00250 }
00251 
00252 NAMESPACE_END
00253 
00254 #endif

Generated on Tue Jul 8 23:34:16 2003 for Crypto++ by doxygen 1.3.2