00001
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
00148
00149 bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable();
00150
00151 if (fullValidate && pass)
00152 {
00153 Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q);
00154 pass = pass && IsIdentity(gp);
00155 }
00156 else if (GetFieldType() == 1)
00157 pass = pass && Jacobi(g, p) == 1;
00158 }
00159
00160 return pass;
00161 }
00162
00163 void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
00164 {
00165 Integer p, q, g;
00166
00167 if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
00168 {
00169 q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
00170 }
00171 else
00172 {
00173 int modulusSize, subgroupOrderSize;
00174
00175 if (!alg.GetIntValue("ModulusSize", modulusSize))
00176 modulusSize = alg.GetIntValueWithDefault("KeySize", 2048);
00177
00178 if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize))
00179 subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize);
00180
00181 PrimeAndGenerator pg;
00182 pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize);
00183 p = pg.Prime();
00184 q = pg.SubPrime();
00185 g = pg.Generator();
00186 }
00187
00188 Initialize(p, q, g);
00189 }
00190
00191 Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const
00192 {
00193 Integer g(encoded, GetModulus().ByteCount());
00194 if (!ValidateElement(1, g, NULL))
00195 throw DL_BadElement();
00196 return g;
00197 }
00198
00199 void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt)
00200 {
00201 BERSequenceDecoder parameters(bt);
00202 Integer p(parameters);
00203 Integer q(parameters);
00204 Integer g;
00205 if (parameters.EndReached())
00206 {
00207 g = q;
00208 q = ComputeGroupOrder(p) / 2;
00209 }
00210 else
00211 g.BERDecode(parameters);
00212 parameters.MessageEnd();
00213
00214 SetModulusAndSubgroupGenerator(p, g);
00215 SetSubgroupOrder(q);
00216 }
00217
00218 void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const
00219 {
00220 DERSequenceEncoder parameters(bt);
00221 GetModulus().DEREncode(parameters);
00222 m_q.DEREncode(parameters);
00223 GetSubgroupGenerator().DEREncode(parameters);
00224 parameters.MessageEnd();
00225 }
00226
00227 bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00228 {
00229 return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue)
00230 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus);
00231 }
00232
00233 void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source)
00234 {
00235 AssignFromHelper(this, source)
00236 CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator)
00237 CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
00238 ;
00239 }
00240
00241 OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const
00242 {
00243 return ASN1::id_dsa();
00244 }
00245
00246 void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
00247 {
00248 ModularArithmetic ma(GetModulus());
00249 ma.SimultaneousExponentiate(results, base, exponents, exponentsCount);
00250 }
00251
00252 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const
00253 {
00254 return a_times_b_mod_c(a, b, GetModulus());
00255 }
00256
00257 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
00258 {
00259 ModularArithmetic ma(GetModulus());
00260 return ma.CascadeExponentiate(element1, exponent1, element2, exponent2);
00261 }
00262
00263 Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const
00264 {
00265 return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount())));
00266 }
00267
00268 unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
00269 {
00270 return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize);
00271 }
00272
00273 NAMESPACE_END
00274
00275 #endif