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