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 Sun Mar 14 20:44:26 2004 for Crypto++ by doxygen 1.3.6-20040222