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 Integer NR_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen)
00070 {
00071 Integer h;
00072 if (digestLen*8 < modulusBits)
00073 h.Decode(digest, digestLen);
00074 else
00075 {
00076 h.Decode(digest, BitsToBytes(modulusBits));
00077 h >>= BitsToBytes(modulusBits)*8 - modulusBits + 1;
00078 }
00079 return h;
00080 }
00081
00082 Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen)
00083 {
00084 Integer h;
00085 if (digestLen*8 <= modulusBits)
00086 h.Decode(digest, digestLen);
00087 else
00088 {
00089 h.Decode(digest, BitsToBytes(modulusBits));
00090 h >>= BitsToBytes(modulusBits)*8 - modulusBits;
00091 }
00092 return h;
00093 }
00094
00095 bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
00096 {
00097 const Integer &p = GetModulus(), &q = GetSubgroupOrder();
00098
00099 bool pass = true;
00100 pass = pass && p > Integer::One() && p.IsOdd();
00101 pass = pass && q > Integer::One() && q.IsOdd();
00102
00103 if (level >= 1)
00104 pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
00105 if (level >= 2)
00106 pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
00107
00108 return pass;
00109 }
00110
00111 bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
00112 {
00113 const Integer &p = GetModulus(), &q = GetSubgroupOrder();
00114
00115 bool pass = true;
00116 pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
00117 pass = pass && g < p && !IsIdentity(g);
00118
00119 if (level >= 1)
00120 {
00121 if (gpc)
00122 pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
00123 }
00124 if (level >= 2)
00125 {
00126 if (GetFieldType() == 2)
00127 pass = pass && Jacobi(g*g-4, p)==-1;
00128
00129
00130
00131 bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable();
00132
00133 if (fullValidate)
00134 pass = pass && IsIdentity(gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q));
00135 else if (GetFieldType() == 1)
00136 pass = pass && Jacobi(g, p) == 1;
00137 }
00138
00139 return pass;
00140 }
00141
00142 void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
00143 {
00144 Integer p, q, g;
00145
00146 if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
00147 {
00148 q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
00149 }
00150 else
00151 {
00152 int modulusSize, subgroupOrderSize;
00153
00154 if (!alg.GetIntValue("ModulusSize", modulusSize))
00155 modulusSize = alg.GetIntValueWithDefault("KeySize", 2048);
00156
00157 if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize))
00158 subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize);
00159
00160 PrimeAndGenerator pg;
00161 pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize);
00162 p = pg.Prime();
00163 q = pg.SubPrime();
00164 g = pg.Generator();
00165 }
00166
00167 Initialize(p, q, g);
00168 }
00169
00170 Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const
00171 {
00172 Integer g(encoded, GetModulus().ByteCount());
00173 if (!ValidateElement(1, g, NULL))
00174 throw DL_BadElement();
00175 return g;
00176 }
00177
00178 void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt)
00179 {
00180 BERSequenceDecoder parameters(bt);
00181 Integer p(parameters);
00182 Integer q(parameters);
00183 Integer g;
00184 if (parameters.EndReached())
00185 {
00186 g = q;
00187 q = ComputeGroupOrder(p) / 2;
00188 }
00189 else
00190 g.BERDecode(parameters);
00191 parameters.MessageEnd();
00192
00193 SetModulusAndSubgroupGenerator(p, g);
00194 SetSubgroupOrder(q);
00195 }
00196
00197 void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const
00198 {
00199 DERSequenceEncoder parameters(bt);
00200 GetModulus().DEREncode(parameters);
00201 m_q.DEREncode(parameters);
00202 GetSubgroupGenerator().DEREncode(parameters);
00203 parameters.MessageEnd();
00204 }
00205
00206 bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00207 {
00208 return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue)
00209 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus);
00210 }
00211
00212 void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source)
00213 {
00214 AssignFromHelper(this, source)
00215 CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator)
00216 CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
00217 ;
00218 }
00219
00220 OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const
00221 {
00222 return ASN1::id_dsa();
00223 }
00224
00225 void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
00226 {
00227 ModularArithmetic ma(GetModulus());
00228 ma.SimultaneousExponentiate(results, base, exponents, exponentsCount);
00229 }
00230
00231 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const
00232 {
00233 return a_times_b_mod_c(a, b, GetModulus());
00234 }
00235
00236 DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
00237 {
00238 ModularArithmetic ma(GetModulus());
00239 return ma.CascadeExponentiate(element1, exponent1, element2, exponent2);
00240 }
00241
00242 Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const
00243 {
00244 return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount())));
00245 }
00246
00247 unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
00248 {
00249 return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize);
00250 }
00251
00252 NAMESPACE_END
00253
00254 #endif