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 Initialize(p, q, g);
00034 }
00035 else
00036 {
00037 int modulusSize = 1024, defaultSubgroupOrderSize;
00038 alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
00039
00040 switch (modulusSize)
00041 {
00042 case 1024:
00043 defaultSubgroupOrderSize = 160;
00044 break;
00045 case 2048:
00046 defaultSubgroupOrderSize = 224;
00047 break;
00048 case 3072:
00049 defaultSubgroupOrderSize = 256;
00050 break;
00051 default:
00052 throw InvalidArgument("DSA: not a valid prime length");
00053 }
00054
00055 DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false)));
00056 }
00057 }
00058
00059 bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
00060 {
00061 bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level);
00062 int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount();
00063 pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256));
00064 return pass;
00065 }
00066
00067 void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng,
00068 const byte *recoverableMessage, size_t recoverableMessageLength,
00069 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00070 byte *representative, size_t representativeBitLength) const
00071 {
00072 assert(recoverableMessageLength == 0);
00073 assert(hashIdentifier.second == 0);
00074 const size_t representativeByteLength = BitsToBytes(representativeBitLength);
00075 const size_t digestSize = hash.DigestSize();
00076 const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
00077
00078 memset(representative, 0, paddingLength);
00079 hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
00080
00081 if (digestSize*8 > representativeBitLength)
00082 {
00083 Integer h(representative, representativeByteLength);
00084 h >>= representativeByteLength*8 - representativeBitLength;
00085 h.Encode(representative, representativeByteLength);
00086 }
00087 }
00088
00089 void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng,
00090 const byte *recoverableMessage, size_t recoverableMessageLength,
00091 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00092 byte *representative, size_t representativeBitLength) const
00093 {
00094 assert(recoverableMessageLength == 0);
00095 assert(hashIdentifier.second == 0);
00096 const size_t representativeByteLength = BitsToBytes(representativeBitLength);
00097 const size_t digestSize = hash.DigestSize();
00098 const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
00099
00100 memset(representative, 0, paddingLength);
00101 hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
00102
00103 if (digestSize*8 >= representativeBitLength)
00104 {
00105 Integer h(representative, representativeByteLength);
00106 h >>= representativeByteLength*8 - representativeBitLength + 1;
00107 h.Encode(representative, representativeByteLength);
00108 }
00109 }
00110
00111 bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
00112 {
00113 const Integer &p = GetModulus(), &q = GetSubgroupOrder();
00114
00115 bool pass = true;
00116 pass = pass && p > Integer::One() && p.IsOdd();
00117 pass = pass && q > Integer::One() && q.IsOdd();
00118
00119 if (level >= 1)
00120 pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
00121 if (level >= 2)
00122 pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
00123
00124 return pass;
00125 }
00126
00127 bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
00128 {
00129 const Integer &p = GetModulus(), &q = GetSubgroupOrder();
00130
00131 bool pass = true;
00132 pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
00133 pass = pass && g < p && !IsIdentity(g);
00134
00135 if (level >= 1)
00136 {
00137 if (gpc)
00138 pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
00139 }
00140 if (level >= 2)
00141 {
00142 if (GetFieldType() == 2)
00143 pass = pass && Jacobi(g*g-4, p)==-1;
00144
00145
00146
00147 bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable();
00148
00149 if (fullValidate && pass)
00150 {
00151 Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q);
00152 pass = pass && IsIdentity(gp);
00153 }
00154 else if (GetFieldType() == 1)
00155 pass = pass && Jacobi(g, p) == 1;
00156 }
00157
00158 return pass;
00159 }
00160
00161 void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
00162 {
00163 Integer p, q, g;
00164
00165 if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
00166 {
00167 q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
00168 }
00169 else
00170 {
00171 int modulusSize, subgroupOrderSize;
00172
00173 if (!alg.GetIntValue("ModulusSize", modulusSize))
00174 modulusSize = alg.GetIntValueWithDefault("KeySize", 2048);
00175
00176 if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize))
00177 subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize);
00178
00179 PrimeAndGenerator pg;
00180 pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize);
00181 p = pg.Prime();
00182 q = pg.SubPrime();
00183 g = pg.Generator();
00184 }
00185
00186 Initialize(p, q, g);
00187 }
00188
00189 Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const
00190 {
00191 Integer g(encoded, GetModulus().ByteCount());
00192 if (!ValidateElement(1, g, NULL))
00193 throw DL_BadElement();
00194 return g;
00195 }
00196
00197 void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt)
00198 {
00199 BERSequenceDecoder parameters(bt);
00200 Integer p(parameters);
00201 Integer q(parameters);
00202 Integer g;
00203 if (parameters.EndReached())
00204 {
00205 g = q;
00206 q = ComputeGroupOrder(p) / 2;
00207 }
00208 else
00209 g.BERDecode(parameters);
00210 parameters.MessageEnd();
00211
00212 SetModulusAndSubgroupGenerator(p, g);
00213 SetSubgroupOrder(q);
00214 }
00215
00216 void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const
00217 {
00218 DERSequenceEncoder parameters(bt);
00219 GetModulus().DEREncode(parameters);
00220 m_q.DEREncode(parameters);
00221 GetSubgroupGenerator().DEREncode(parameters);
00222 parameters.MessageEnd();
00223 }
00224
00225 bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00226 {
00227 return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue)
00228 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus);
00229 }
00230
00231 void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source)
00232 {
00233 AssignFromHelper(this, source)
00234 CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator)
00235 CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
00236 ;
00237 }
00238
00239 OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const
00240 {
00241 return ASN1::id_dsa();
00242 }
00243
00244 void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
00245 {
00246 ModularArithmetic ma(GetModulus());
00247 ma.SimultaneousExponentiate(results, base, exponents, exponentsCount);
00248 }
00249
00250 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const
00251 {
00252 return a_times_b_mod_c(a, b, GetModulus());
00253 }
00254
00255 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
00256 {
00257 ModularArithmetic ma(GetModulus());
00258 return ma.CascadeExponentiate(element1, exponent1, element2, exponent2);
00259 }
00260
00261 Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const
00262 {
00263 return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount())));
00264 }
00265
00266 unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
00267 {
00268 return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize);
00269 }
00270
00271 NAMESPACE_END
00272
00273 #endif