00001
00002
00003 #include "pch.h"
00004 #include "config.h"
00005
00006
00007 #if CRYPTOPP_MSC_VERSION
00008 # pragma warning(disable: 4189 4589)
00009 #endif
00010
00011 #ifndef CRYPTOPP_IMPORTS
00012
00013 #include "gfpcrypt.h"
00014 #include "nbtheory.h"
00015 #include "modarith.h"
00016 #include "integer.h"
00017 #include "asn.h"
00018 #include "oids.h"
00019 #include "misc.h"
00020
00021 NAMESPACE_BEGIN(CryptoPP)
00022
00023 #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
00024 void TestInstantiations_gfpcrypt()
00025 {
00026 GDSA<SHA>::Signer test;
00027 GDSA<SHA>::Verifier test1;
00028 DSA::Signer test5(NullRNG(), 100);
00029 DSA::Signer test2(test5);
00030 NR<SHA>::Signer test3;
00031 NR<SHA>::Verifier test4;
00032 DLIES<>::Encryptor test6;
00033 DLIES<>::Decryptor test7;
00034 }
00035 #endif
00036
00037 void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
00038 {
00039 Integer p, q, g;
00040
00041 if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
00042 {
00043 q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
00044 Initialize(p, q, g);
00045 }
00046 else
00047 {
00048 int modulusSize = 1024, defaultSubgroupOrderSize;
00049 alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
00050
00051 switch (modulusSize)
00052 {
00053 case 1024:
00054 defaultSubgroupOrderSize = 160;
00055 break;
00056 case 2048:
00057 defaultSubgroupOrderSize = 224;
00058 break;
00059 case 3072:
00060 defaultSubgroupOrderSize = 256;
00061 break;
00062 default:
00063 throw InvalidArgument("DSA: not a valid prime length");
00064 }
00065
00066 DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false)));
00067 }
00068 }
00069
00070 bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
00071 {
00072 bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level);
00073 int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount();
00074 pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256));
00075 return pass;
00076 }
00077
00078 void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng,
00079 const byte *recoverableMessage, size_t recoverableMessageLength,
00080 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00081 byte *representative, size_t representativeBitLength) const
00082 {
00083 CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
00084 CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
00085 assert(recoverableMessageLength == 0);
00086 assert(hashIdentifier.second == 0);
00087
00088 const size_t representativeByteLength = BitsToBytes(representativeBitLength);
00089 const size_t digestSize = hash.DigestSize();
00090 const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
00091
00092 memset(representative, 0, paddingLength);
00093 hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
00094
00095 if (digestSize*8 > representativeBitLength)
00096 {
00097 Integer h(representative, representativeByteLength);
00098 h >>= representativeByteLength*8 - representativeBitLength;
00099 h.Encode(representative, representativeByteLength);
00100 }
00101 }
00102
00103 void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng,
00104 const byte *recoverableMessage, size_t recoverableMessageLength,
00105 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00106 byte *representative, size_t representativeBitLength) const
00107 {
00108 CRYPTOPP_UNUSED(rng);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
00109 CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
00110 CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength);
00111
00112 assert(recoverableMessageLength == 0);
00113 assert(hashIdentifier.second == 0);
00114 const size_t representativeByteLength = BitsToBytes(representativeBitLength);
00115 const size_t digestSize = hash.DigestSize();
00116 const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
00117
00118 memset(representative, 0, paddingLength);
00119 hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
00120
00121 if (digestSize*8 >= representativeBitLength)
00122 {
00123 Integer h(representative, representativeByteLength);
00124 h >>= representativeByteLength*8 - representativeBitLength + 1;
00125 h.Encode(representative, representativeByteLength);
00126 }
00127 }
00128
00129 bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
00130 {
00131 const Integer &p = GetModulus(), &q = GetSubgroupOrder();
00132
00133 bool pass = true;
00134 pass = pass && p > Integer::One() && p.IsOdd();
00135 pass = pass && q > Integer::One() && q.IsOdd();
00136
00137 if (level >= 1)
00138 pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
00139 if (level >= 2)
00140 pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
00141
00142 return pass;
00143 }
00144
00145 bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
00146 {
00147 const Integer &p = GetModulus(), &q = GetSubgroupOrder();
00148
00149 bool pass = true;
00150 pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
00151 pass = pass && g < p && !IsIdentity(g);
00152
00153 if (level >= 1)
00154 {
00155 if (gpc)
00156 pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
00157 }
00158 if (level >= 2)
00159 {
00160 if (GetFieldType() == 2)
00161 pass = pass && Jacobi(g*g-4, p)==-1;
00162
00163
00164
00165 bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable();
00166
00167 if (fullValidate && pass)
00168 {
00169 Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q);
00170 pass = pass && IsIdentity(gp);
00171 }
00172 else if (GetFieldType() == 1)
00173 pass = pass && Jacobi(g, p) == 1;
00174 }
00175
00176 return pass;
00177 }
00178
00179 void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
00180 {
00181 Integer p, q, g;
00182
00183 if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
00184 {
00185 q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
00186 }
00187 else
00188 {
00189 int modulusSize, subgroupOrderSize;
00190
00191 if (!alg.GetIntValue("ModulusSize", modulusSize))
00192 modulusSize = alg.GetIntValueWithDefault("KeySize", 2048);
00193
00194 if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize))
00195 subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize);
00196
00197 PrimeAndGenerator pg;
00198 pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize);
00199 p = pg.Prime();
00200 q = pg.SubPrime();
00201 g = pg.Generator();
00202 }
00203
00204 Initialize(p, q, g);
00205 }
00206
00207 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
00208 void DL_GroupParameters_IntegerBased::EncodeElement(bool reversible, const Element &element, byte *encoded) const
00209 {
00210 CRYPTOPP_UNUSED(reversible);
00211 element.Encode(encoded, GetModulus().ByteCount());
00212 }
00213
00214 unsigned int DL_GroupParameters_IntegerBased::GetEncodedElementSize(bool reversible) const
00215 {
00216 CRYPTOPP_UNUSED(reversible);
00217 return GetModulus().ByteCount();
00218 }
00219 #endif
00220
00221 Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const
00222 {
00223 CRYPTOPP_UNUSED(checkForGroupMembership);
00224 Integer g(encoded, GetModulus().ByteCount());
00225 if (!ValidateElement(1, g, NULL))
00226 throw DL_BadElement();
00227 return g;
00228 }
00229
00230 void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt)
00231 {
00232 BERSequenceDecoder parameters(bt);
00233 Integer p(parameters);
00234 Integer q(parameters);
00235 Integer g;
00236 if (parameters.EndReached())
00237 {
00238 g = q;
00239 q = ComputeGroupOrder(p) / 2;
00240 }
00241 else
00242 g.BERDecode(parameters);
00243 parameters.MessageEnd();
00244
00245 SetModulusAndSubgroupGenerator(p, g);
00246 SetSubgroupOrder(q);
00247 }
00248
00249 void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const
00250 {
00251 DERSequenceEncoder parameters(bt);
00252 GetModulus().DEREncode(parameters);
00253 m_q.DEREncode(parameters);
00254 GetSubgroupGenerator().DEREncode(parameters);
00255 parameters.MessageEnd();
00256 }
00257
00258 bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00259 {
00260 return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue)
00261 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus);
00262 }
00263
00264 void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source)
00265 {
00266 AssignFromHelper(this, source)
00267 CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator)
00268 CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
00269 ;
00270 }
00271
00272 OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const
00273 {
00274 return ASN1::id_dsa();
00275 }
00276
00277 void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
00278 {
00279 ModularArithmetic ma(GetModulus());
00280 ma.SimultaneousExponentiate(results, base, exponents, exponentsCount);
00281 }
00282
00283 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const
00284 {
00285 return a_times_b_mod_c(a, b, GetModulus());
00286 }
00287
00288 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
00289 {
00290 ModularArithmetic ma(GetModulus());
00291 return ma.CascadeExponentiate(element1, exponent1, element2, exponent2);
00292 }
00293
00294 Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const
00295 {
00296 return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount())));
00297 }
00298
00299 unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
00300 {
00301 return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize);
00302 }
00303
00304 NAMESPACE_END
00305
00306 #endif