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