- Main Page
- Namespaces
- Classes
- Files

- File List
- 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, size_t recoverableMessageLength,
    00071         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
    00072         byte *representative, size_t representativeBitLength) const
    00073 {
    00074         assert(recoverableMessageLength == 0);
    00075         assert(hashIdentifier.second == 0);
    00076         const size_t representativeByteLength = BitsToBytes(representativeBitLength);
    00077         const size_t digestSize = hash.DigestSize();
    00078         const size_t 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, size_t recoverableMessageLength,
    00093         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
    00094         byte *representative, size_t representativeBitLength) const
    00095 {
    00096         assert(recoverableMessageLength == 0);
    00097         assert(hashIdentifier.second == 0);
    00098         const size_t representativeByteLength = BitsToBytes(representativeBitLength);
    00099         const size_t digestSize = hash.DigestSize();
    00100         const size_t 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