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