00001
00002
00003
#ifndef CRYPTOPP_PUBKEY_H
00004
#define CRYPTOPP_PUBKEY_H
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
#include "modarith.h"
00036
#include "filters.h"
00037
#include "eprecomp.h"
00038
#include "fips140.h"
00039
#include "argnames.h"
00040
#include <memory>
00041
00042
00043
#undef INTERFACE
00044
00045 NAMESPACE_BEGIN(CryptoPP)
00046
00047
00048 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE
TrapdoorFunctionBounds
00049 {
00050
public:
00051
virtual ~TrapdoorFunctionBounds() {}
00052
00053
virtual Integer PreimageBound()
const =0;
00054
virtual Integer ImageBound()
const =0;
00055
virtual Integer MaxPreimage()
const {
return --PreimageBound();}
00056
virtual Integer MaxImage()
const {
return --ImageBound();}
00057 };
00058
00059
00060 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction :
public TrapdoorFunctionBounds
00061 {
00062
public:
00063
virtual Integer ApplyRandomizedFunction(
RandomNumberGenerator &rng,
const Integer &x)
const =0;
00064
virtual bool IsRandomized()
const {
return true;}
00065 };
00066
00067
00068 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction :
public RandomizedTrapdoorFunction
00069 {
00070
public:
00071
Integer ApplyRandomizedFunction(
RandomNumberGenerator &rng,
const Integer &x)
const
00072
{
return ApplyFunction(x);}
00073
bool IsRandomized()
const {
return false;}
00074
00075
virtual Integer ApplyFunction(
const Integer &x)
const =0;
00076 };
00077
00078
00079 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse
00080 {
00081
public:
00082
virtual ~RandomizedTrapdoorFunctionInverse() {}
00083
00084
virtual Integer CalculateRandomizedInverse(
RandomNumberGenerator &rng,
const Integer &x)
const =0;
00085
virtual bool IsRandomized()
const {
return true;}
00086 };
00087
00088
00089 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse :
public RandomizedTrapdoorFunctionInverse
00090 {
00091
public:
00092
virtual ~TrapdoorFunctionInverse() {}
00093
00094
Integer CalculateRandomizedInverse(
RandomNumberGenerator &rng,
const Integer &x)
const
00095
{
return CalculateInverse(rng, x);}
00096
bool IsRandomized()
const {
return false;}
00097
00098
virtual Integer CalculateInverse(
RandomNumberGenerator &rng,
const Integer &x)
const =0;
00099 };
00100
00101
00102
00103
00104 class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
00105 {
00106
public:
00107
virtual ~PK_EncryptionMessageEncodingMethod() {}
00108
00109
virtual bool ParameterSupported(
const char *name)
const {
return false;}
00110
00111
00112
virtual unsigned int MaxUnpaddedLength(
unsigned int paddedLength)
const =0;
00113
00114
virtual void Pad(
RandomNumberGenerator &rng,
const byte *raw,
unsigned int inputLength, byte *padded,
unsigned int paddedBitLength,
const NameValuePairs ¶meters)
const =0;
00115
00116
virtual DecodingResult Unpad(
const byte *padded,
unsigned int paddedBitLength, byte *raw,
const NameValuePairs ¶meters)
const =0;
00117 };
00118
00119
00120
00121
00122
template <
class TFI,
class MEI>
00123 class CRYPTOPP_NO_VTABLE TF_Base
00124 {
00125
protected:
00126
virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds()
const =0;
00127
00128
typedef TFI TrapdoorFunctionInterface;
00129
virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface()
const =0;
00130
00131
typedef MEI MessageEncodingInterface;
00132
virtual const MessageEncodingInterface & GetMessageEncodingInterface()
const =0;
00133 };
00134
00135
00136
00137
00138
template <
class BASE>
00139 class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl :
public BASE
00140 {
00141
public:
00142
unsigned int MaxPlaintextLength(
unsigned int ciphertextLength)
const
00143
{
return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
00144
unsigned int CiphertextLength(
unsigned int plaintextLength)
const
00145
{
return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
00146
00147
virtual unsigned int FixedMaxPlaintextLength()
const =0;
00148
virtual unsigned int FixedCiphertextLength()
const =0;
00149 };
00150
00151
00152
template <
class INTERFACE,
class BASE>
00153 class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase :
public PK_FixedLengthCryptoSystemImpl<INTERFACE>,
protected BASE
00154 {
00155
public:
00156
bool ParameterSupported(
const char *name)
const {
return this->GetMessageEncodingInterface().ParameterSupported(name);}
00157
unsigned int FixedMaxPlaintextLength()
const {
return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
00158
unsigned int FixedCiphertextLength()
const {
return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
00159
00160
protected:
00161
unsigned int PaddedBlockByteLength()
const {
return BitsToBytes(PaddedBlockBitLength());}
00162
unsigned int PaddedBlockBitLength()
const {
return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
00163 };
00164
00165
00166 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase :
public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
00167 {
00168
public:
00169
DecodingResult Decrypt(
RandomNumberGenerator &rng,
const byte *ciphertext,
unsigned int ciphertextLength, byte *plaintext,
const NameValuePairs ¶meters = g_nullNameValuePairs)
const;
00170 };
00171
00172
00173 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase :
public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
00174 {
00175
public:
00176
void Encrypt(
RandomNumberGenerator &rng,
const byte *plaintext,
unsigned int plaintextLength, byte *ciphertext,
const NameValuePairs ¶meters = g_nullNameValuePairs)
const;
00177 };
00178
00179
00180
00181
typedef std::pair<const byte *, unsigned int> HashIdentifier;
00182
00183
00184 class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod
00185 {
00186
public:
00187
virtual ~PK_SignatureMessageEncodingMethod() {}
00188
00189
virtual unsigned int MaxRecoverableLength(
unsigned int representativeBitLength,
unsigned int hashIdentifierLength,
unsigned int digestLength)
const
00190
{
return 0;}
00191
00192
bool IsProbabilistic()
const
00193
{
return true;}
00194
bool AllowNonrecoverablePart()
const
00195
{
throw NotImplemented(
"PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00196
virtual bool RecoverablePartFirst()
const
00197
{
throw NotImplemented(
"PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00198
00199
00200
virtual void ProcessSemisignature(
HashTransformation &hash,
const byte *semisignature,
unsigned int semisignatureLength)
const {}
00201
00202
00203
virtual void ProcessRecoverableMessage(
HashTransformation &hash,
00204
const byte *recoverableMessage,
unsigned int recoverableMessageLength,
00205
const byte *presignature,
unsigned int presignatureLength,
00206
SecByteBlock &semisignature)
const
00207
{
00208
if (RecoverablePartFirst())
00209 assert(!
"ProcessRecoverableMessage() not implemented");
00210 }
00211
00212
virtual void ComputeMessageRepresentative(
RandomNumberGenerator &rng,
00213
const byte *recoverableMessage,
unsigned int recoverableMessageLength,
00214
HashTransformation &hash, HashIdentifier hashIdentifier,
bool messageEmpty,
00215 byte *representative,
unsigned int representativeBitLength)
const =0;
00216
00217
virtual bool VerifyMessageRepresentative(
00218
HashTransformation &hash, HashIdentifier hashIdentifier,
bool messageEmpty,
00219 byte *representative,
unsigned int representativeBitLength)
const =0;
00220
00221
virtual DecodingResult RecoverMessageFromRepresentative(
00222
HashTransformation &hash, HashIdentifier hashIdentifier,
bool messageEmpty,
00223 byte *representative,
unsigned int representativeBitLength,
00224 byte *recoveredMessage)
const
00225
{
throw NotImplemented(
"PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00226
00227
virtual DecodingResult RecoverMessageFromSemisignature(
00228
HashTransformation &hash, HashIdentifier hashIdentifier,
00229
const byte *presignature,
unsigned int presignatureLength,
00230
const byte *semisignature,
unsigned int semisignatureLength,
00231 byte *recoveredMessage)
const
00232
{
throw NotImplemented(
"PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
00233
00234
00235
struct HashIdentifierLookup
00236 {
00237
template <
class H>
struct HashIdentifierLookup2
00238 {
00239
static HashIdentifier Lookup()
00240 {
00241
return HashIdentifier(NULL, 0);
00242 }
00243 };
00244 };
00245 };
00246
00247
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod :
public PK_SignatureMessageEncodingMethod
00248 {
00249
public:
00250
bool VerifyMessageRepresentative(
00251
HashTransformation &hash, HashIdentifier hashIdentifier,
bool messageEmpty,
00252 byte *representative,
unsigned int representativeBitLength)
const;
00253 };
00254
00255
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod :
public PK_SignatureMessageEncodingMethod
00256 {
00257
public:
00258
bool VerifyMessageRepresentative(
00259
HashTransformation &hash, HashIdentifier hashIdentifier,
bool messageEmpty,
00260 byte *representative,
unsigned int representativeBitLength)
const;
00261 };
00262
00263
class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA :
public PK_DeterministicSignatureMessageEncodingMethod
00264 {
00265
public:
00266
void ComputeMessageRepresentative(
RandomNumberGenerator &rng,
00267
const byte *recoverableMessage,
unsigned int recoverableMessageLength,
00268
HashTransformation &hash, HashIdentifier hashIdentifier,
bool messageEmpty,
00269 byte *representative,
unsigned int representativeBitLength)
const;
00270 };
00271
00272
class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR :
public PK_DeterministicSignatureMessageEncodingMethod
00273 {
00274
public:
00275
void ComputeMessageRepresentative(
RandomNumberGenerator &rng,
00276
const byte *recoverableMessage,
unsigned int recoverableMessageLength,
00277
HashTransformation &hash, HashIdentifier hashIdentifier,
bool messageEmpty,
00278 byte *representative,
unsigned int representativeBitLength)
const;
00279 };
00280
00281
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase :
public PK_MessageAccumulator
00282 {
00283
public:
00284 PK_MessageAccumulatorBase() : m_empty(true) {}
00285
00286
virtual HashTransformation & AccessHash() =0;
00287
00288
void Update(
const byte *input,
unsigned int length)
00289 {
00290 AccessHash().Update(input, length);
00291 m_empty = m_empty && length == 0;
00292 }
00293
00294
SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
00295
Integer m_k, m_s;
00296
bool m_empty;
00297 };
00298
00299
template <
class HASH_ALGORITHM>
00300
class PK_MessageAccumulatorImpl :
public PK_MessageAccumulatorBase,
protected ObjectHolder<HASH_ALGORITHM>
00301 {
00302
public:
00303
HashTransformation & AccessHash() {
return this->m_object;}
00304 };
00305
00306
00307
template <
class INTERFACE,
class BASE>
00308 class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase :
public INTERFACE,
protected BASE
00309 {
00310
public:
00311
unsigned int SignatureLength()
const
00312
{
return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
00313
unsigned int MaxRecoverableLength()
const
00314
{
return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
00315
unsigned int MaxRecoverableLengthFromSignatureLength(
unsigned int signatureLength)
const
00316
{
return this->MaxRecoverableLength();}
00317
00318
bool IsProbabilistic()
const
00319
{
return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();}
00320
bool AllowNonrecoverablePart()
const
00321
{
return this->GetMessageEncodingInterface().AllowNonrecoverablePart();}
00322
bool RecoverablePartFirst()
const
00323
{
return this->GetMessageEncodingInterface().RecoverablePartFirst();}
00324
00325
protected:
00326
unsigned int MessageRepresentativeLength()
const {
return BitsToBytes(MessageRepresentativeBitLength());}
00327
unsigned int MessageRepresentativeBitLength()
const {
return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
00328
virtual HashIdentifier GetHashIdentifier()
const =0;
00329
virtual unsigned int GetDigestSize()
const =0;
00330 };
00331
00332
00333 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase :
public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
00334 {
00335
public:
00336
void InputRecoverableMessage(
PK_MessageAccumulator &messageAccumulator,
const byte *recoverableMessage,
unsigned int recoverableMessageLength)
const;
00337
unsigned int SignAndRestart(
RandomNumberGenerator &rng,
PK_MessageAccumulator &messageAccumulator, byte *signature,
bool restart=
true)
const;
00338 };
00339
00340
00341 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase :
public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
00342 {
00343
public:
00344
void InputSignature(
PK_MessageAccumulator &messageAccumulator,
const byte *signature,
unsigned int signatureLength)
const;
00345
bool VerifyAndRestart(
PK_MessageAccumulator &messageAccumulator)
const;
00346
DecodingResult RecoverAndRestart(byte *recoveredMessage,
PK_MessageAccumulator &recoveryAccumulator)
const;
00347 };
00348
00349
00350
00351
00352
template <
class T1,
class T2,
class T3>
00353 struct TF_CryptoSchemeOptions
00354 {
00355
typedef T1 AlgorithmInfo;
00356
typedef T2 Keys;
00357
typedef typename Keys::PrivateKey PrivateKey;
00358
typedef typename Keys::PublicKey PublicKey;
00359
typedef T3 MessageEncodingMethod;
00360 };
00361
00362
00363
template <
class T1,
class T2,
class T3,
class T4>
00364 struct TF_SignatureSchemeOptions :
public TF_CryptoSchemeOptions<T1, T2, T3>
00365 {
00366
typedef T4 HashFunction;
00367 };
00368
00369
00370
template <
class KEYS>
00371 class CRYPTOPP_NO_VTABLE PublicKeyCopier
00372 {
00373
public:
00374
typedef typename KEYS::PublicKey KeyClass;
00375
virtual void CopyKeyInto(
typename KEYS::PublicKey &key)
const =0;
00376 };
00377
00378
00379
template <
class KEYS>
00380 class CRYPTOPP_NO_VTABLE PrivateKeyCopier
00381 {
00382
public:
00383
typedef typename KEYS::PrivateKey KeyClass;
00384
virtual void CopyKeyInto(
typename KEYS::PublicKey &key)
const =0;
00385
virtual void CopyKeyInto(
typename KEYS::PrivateKey &key)
const =0;
00386 };
00387
00388
00389
template <
class BASE,
class SCHEME_OPTIONS,
class KEY>
00390 class CRYPTOPP_NO_VTABLE TF_ObjectImplBase :
public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
00391 {
00392
public:
00393
typedef SCHEME_OPTIONS SchemeOptions;
00394
typedef KEY KeyClass;
00395
00396
PublicKey & AccessPublicKey() {
return AccessKey();}
00397
const PublicKey & GetPublicKey()
const {
return GetKey();}
00398
00399
PrivateKey & AccessPrivateKey() {
return AccessKey();}
00400
const PrivateKey & GetPrivateKey()
const {
return GetKey();}
00401
00402
virtual const KeyClass & GetKey()
const =0;
00403
virtual KeyClass & AccessKey() =0;
00404
00405
const KeyClass & GetTrapdoorFunction()
const {
return GetKey();}
00406
00407
PK_MessageAccumulator * NewSignatureAccumulator(
RandomNumberGenerator &rng)
const
00408
{
00409
return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
00410 }
00411
PK_MessageAccumulator * NewVerificationAccumulator()
const
00412
{
00413
return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
00414 }
00415
00416
protected:
00417
const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface()
const
00418
{
return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
00419
const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds()
const
00420
{
return GetKey();}
00421
const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface()
const
00422
{
return GetKey();}
00423
00424
00425 HashIdentifier GetHashIdentifier()
const
00426
{
00427
typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
00428
return L::Lookup();
00429 }
00430
unsigned int GetDigestSize()
const
00431
{
00432
typedef CPP_TYPENAME SchemeOptions::HashFunction H;
00433
return H::DIGESTSIZE;
00434 }
00435 };
00436
00437
00438
template <
class BASE,
class SCHEME_OPTIONS,
class KEY>
00439 class TF_ObjectImplExtRef :
public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
00440 {
00441
public:
00442
TF_ObjectImplExtRef(
const KEY *pKey = NULL) : m_pKey(pKey) {}
00443
void SetKeyPtr(
const KEY *pKey) {m_pKey = pKey;}
00444
00445
const KEY & GetKey()
const {
return *m_pKey;}
00446 KEY & AccessKey() {
throw NotImplemented(
"TF_ObjectImplExtRef: cannot modify refererenced key");}
00447
00448
private:
00449
const KEY * m_pKey;
00450 };
00451
00452
00453
template <
class BASE,
class SCHEME_OPTIONS,
class KEY_COPIER>
00454 class CRYPTOPP_NO_VTABLE TF_ObjectImpl :
public TF_ObjectImplBase<TwoBases<BASE, KEY_COPIER>, SCHEME_OPTIONS, typename KEY_COPIER::KeyClass>
00455 {
00456
public:
00457
typedef typename KEY_COPIER::KeyClass KeyClass;
00458
00459
const KeyClass & GetKey()
const {
return m_trapdoorFunction;}
00460 KeyClass & AccessKey() {
return m_trapdoorFunction;}
00461
00462
void CopyKeyInto(
typename SCHEME_OPTIONS::PrivateKey &key)
const {key = GetKey();}
00463
void CopyKeyInto(
typename SCHEME_OPTIONS::PublicKey &key)
const {key = GetKey();}
00464
00465
private:
00466 KeyClass m_trapdoorFunction;
00467 };
00468
00469
00470
template <
class SCHEME_OPTIONS>
00471 class TF_DecryptorImpl :
public TF_ObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS, PrivateKeyCopier<typename SCHEME_OPTIONS::Keys> >
00472 {
00473 };
00474
00475
00476
template <
class SCHEME_OPTIONS>
00477 class TF_EncryptorImpl :
public TF_ObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS, PublicKeyCopier<typename SCHEME_OPTIONS::Keys> >
00478 {
00479 };
00480
00481
00482
template <
class SCHEME_OPTIONS>
00483 class TF_SignerImpl :
public TF_ObjectImpl<TF_SignerBase, SCHEME_OPTIONS, PrivateKeyCopier<typename SCHEME_OPTIONS::Keys> >
00484 {
00485 };
00486
00487
00488
template <
class SCHEME_OPTIONS>
00489 class TF_VerifierImpl :
public TF_ObjectImpl<TF_VerifierBase, SCHEME_OPTIONS, PublicKeyCopier<typename SCHEME_OPTIONS::Keys> >
00490 {
00491 };
00492
00493
00494
00495
00496 class CRYPTOPP_NO_VTABLE MaskGeneratingFunction
00497 {
00498
public:
00499
virtual ~MaskGeneratingFunction() {}
00500
virtual void GenerateAndMask(
HashTransformation &hash, byte *output,
unsigned int outputLength,
const byte *input,
unsigned int inputLength,
bool mask =
true)
const =0;
00501 };
00502
00503 CRYPTOPP_DLL
void P1363_MGF1KDF2_Common(
HashTransformation &hash, byte *output,
unsigned int outputLength,
const byte *input,
unsigned int inputLength,
const byte *derivationParams,
unsigned int derivationParamsLength,
bool mask,
unsigned int counterStart);
00504
00505
00506 class P1363_MGF1 :
public MaskGeneratingFunction
00507 {
00508
public:
00509
static const char * StaticAlgorithmName() {
return "MGF1";}
00510
void GenerateAndMask(
HashTransformation &hash, byte *output,
unsigned int outputLength,
const byte *input,
unsigned int inputLength,
bool mask =
true)
const
00511
{
00512 P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
00513 }
00514 };
00515
00516
00517
00518
00519
template <
class H>
00520 class P1363_KDF2
00521 {
00522
public:
00523
static void DeriveKey(byte *output,
unsigned int outputLength,
const byte *input,
unsigned int inputLength,
const byte *derivationParams,
unsigned int derivationParamsLength)
00524 {
00525 H h;
00526 P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength,
false, 1);
00527 }
00528 };
00529
00530
00531
00532
00533 class DL_BadElement :
public InvalidDataFormat
00534 {
00535
public:
00536
DL_BadElement() :
InvalidDataFormat(
"CryptoPP: invalid group element") {}
00537 };
00538
00539
00540
template <
class T>
00541 class CRYPTOPP_NO_VTABLE DL_GroupParameters :
public CryptoParameters
00542 {
00543
typedef DL_GroupParameters<T> ThisClass;
00544
00545
public:
00546
typedef T Element;
00547
00548 DL_GroupParameters() : m_validationLevel(0) {}
00549
00550
00551 bool Validate(
RandomNumberGenerator &rng,
unsigned int level)
const
00552
{
00553
if (!GetBasePrecomputation().IsInitialized())
00554
return false;
00555
00556
if (m_validationLevel > level)
00557
return true;
00558
00559
bool pass = ValidateGroup(rng, level);
00560 pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
00561
00562 m_validationLevel = pass ? level+1 : 0;
00563
00564
return pass;
00565 }
00566
00567 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00568
{
00569
return GetValueHelper(
this, name, valueType, pValue)
00570 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
00571 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
00572 ;
00573 }
00574
00575 bool SupportsPrecomputation()
const {
return true;}
00576
00577 void Precompute(
unsigned int precomputationStorage=16)
00578 {
00579 AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
00580 }
00581
00582 void LoadPrecomputation(
BufferedTransformation &storedPrecomputation)
00583 {
00584 AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
00585 m_validationLevel = 0;
00586 }
00587
00588 void SavePrecomputation(
BufferedTransformation &storedPrecomputation)
const
00589
{
00590 GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
00591 }
00592
00593
00594
virtual const Element & GetSubgroupGenerator()
const {
return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
00595
virtual void SetSubgroupGenerator(
const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
00596
virtual Element ExponentiateBase(
const Integer &exponent)
const
00597
{
00598
return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
00599 }
00600
virtual Element ExponentiateElement(
const Element &base,
const Integer &exponent)
const
00601
{
00602 Element result;
00603 SimultaneousExponentiate(&result, base, &exponent, 1);
00604
return result;
00605 }
00606
00607
virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
00608 virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
00609 virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
00610 virtual const
Integer & GetSubgroupOrder() const =0;
00611 virtual
Integer GetMaxExponent() const =0;
00612 virtual
Integer GetGroupOrder()
const {
return GetSubgroupOrder()*GetCofactor();}
00613
virtual Integer GetCofactor()
const {
return GetGroupOrder()/GetSubgroupOrder();}
00614
virtual unsigned int GetEncodedElementSize(
bool reversible)
const =0;
00615
virtual void EncodeElement(
bool reversible,
const Element &element, byte *encoded)
const =0;
00616
virtual Element DecodeElement(
const byte *encoded,
bool checkForGroupMembership)
const =0;
00617
virtual Integer ConvertElementToInteger(
const Element &element)
const =0;
00618
virtual bool ValidateGroup(
RandomNumberGenerator &rng,
unsigned int level)
const =0;
00619
virtual bool ValidateElement(
unsigned int level,
const Element &element,
const DL_FixedBasePrecomputation<Element> *precomp)
const =0;
00620
virtual bool FastSubgroupCheckAvailable() const =0;
00621 virtual
bool IsIdentity(const Element &element) const =0;
00622 virtual
void SimultaneousExponentiate(Element *results, const Element &base, const
Integer *exponents,
unsigned int exponentsCount) const =0;
00623
00624 protected:
00625
void ParametersChanged() {m_validationLevel = 0;}
00626
00627
private:
00628
mutable unsigned int m_validationLevel;
00629 };
00630
00631
00632
template <
class GROUP_PRECOMP,
class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element>,
class BASE = DL_GroupParameters<CPP_TYPENAME GROUP_PRECOMP::Element> >
00633 class DL_GroupParametersImpl :
public BASE
00634 {
00635
public:
00636
typedef GROUP_PRECOMP GroupPrecomputation;
00637
typedef typename GROUP_PRECOMP::Element Element;
00638
typedef BASE_PRECOMP BasePrecomputation;
00639
00640
const DL_GroupPrecomputation<Element> & GetGroupPrecomputation()
const {
return m_groupPrecomputation;}
00641
const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation()
const {
return m_gpc;}
00642 DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {
return m_gpc;}
00643
00644
protected:
00645 GROUP_PRECOMP m_groupPrecomputation;
00646 BASE_PRECOMP m_gpc;
00647 };
00648
00649
00650
template <
class T>
00651 class CRYPTOPP_NO_VTABLE DL_Key
00652 {
00653
public:
00654
virtual const DL_GroupParameters<T> & GetAbstractGroupParameters()
const =0;
00655
virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
00656 };
00657
00658
00659
template <
class T>
00660 class CRYPTOPP_NO_VTABLE DL_PublicKey :
public DL_Key<T>
00661 {
00662
typedef DL_PublicKey<T> ThisClass;
00663
00664
public:
00665
typedef T Element;
00666
00667
bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00668
{
00669
return GetValueHelper(
this, name, valueType, pValue, &this->GetAbstractGroupParameters())
00670 CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
00671 }
00672
00673
void AssignFrom(
const NameValuePairs &source);
00674
00675
00676
virtual const Element & GetPublicElement()
const {
return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());}
00677
virtual void SetPublicElement(
const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
00678
virtual Element ExponentiatePublicElement(
const Integer &exponent)
const
00679
{
00680
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
00681
return GetPublicPrecomputation().Exponentiate(params.
GetGroupPrecomputation(), exponent);
00682 }
00683
virtual Element CascadeExponentiateBaseAndPublicElement(
const Integer &baseExp,
const Integer &publicExp)
const
00684
{
00685
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
00686
return params.
GetBasePrecomputation().CascadeExponentiate(params.
GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
00687 }
00688
00689
virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation()
const =0;
00690
virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
00691 };
00692
00693
00694
template <
class T>
00695 class CRYPTOPP_NO_VTABLE DL_PrivateKey :
public DL_Key<T>
00696 {
00697
typedef DL_PrivateKey<T> ThisClass;
00698
00699
public:
00700
typedef T Element;
00701
00702
void MakePublicKey(
DL_PublicKey<T> &pub)
const
00703
{
00704 pub.
AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters());
00705 pub.
SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
00706 }
00707
00708
bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00709
{
00710
return GetValueHelper(
this, name, valueType, pValue, &this->GetAbstractGroupParameters())
00711 CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
00712 }
00713
00714
void AssignFrom(
const NameValuePairs &source)
00715 {
00716 this->AccessAbstractGroupParameters().AssignFrom(source);
00717 AssignFromHelper(
this, source)
00718 CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
00719 }
00720
00721
virtual const Integer & GetPrivateExponent()
const =0;
00722
virtual void SetPrivateExponent(
const Integer &x) =0;
00723 };
00724
00725
template <
class T>
00726
void DL_PublicKey<T>::AssignFrom(
const NameValuePairs &source)
00727 {
00728
DL_PrivateKey<T> *pPrivateKey = NULL;
00729
if (source.
GetThisPointer(pPrivateKey))
00730 pPrivateKey->
MakePublicKey(*
this);
00731
else
00732 {
00733 this->AccessAbstractGroupParameters().AssignFrom(source);
00734 AssignFromHelper(
this, source)
00735 CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
00736 }
00737 }
00738
00739 class
OID;
00740
00741
00742 template <class PK, class GP, class O = OID>
00743 class
DL_KeyImpl : public PK
00744 {
00745
public:
00746
typedef GP GroupParameters;
00747
00748 O GetAlgorithmID()
const {
return GetGroupParameters().GetAlgorithmID();}
00749
00750
00751
00752
00753
bool BERDecodeAlgorithmParameters(
BufferedTransformation &bt)
00754 {AccessGroupParameters().BERDecode(bt);
return true;}
00755
bool DEREncodeAlgorithmParameters(
BufferedTransformation &bt)
const
00756
{GetGroupParameters().DEREncode(bt);
return true;}
00757
00758
const GP & GetGroupParameters()
const {
return m_groupParameters;}
00759 GP & AccessGroupParameters() {
return m_groupParameters;}
00760
00761
private:
00762 GP m_groupParameters;
00763 };
00764
00765
class X509PublicKey;
00766
class PKCS8PrivateKey;
00767
00768
00769
template <
class GP>
00770 class DL_PrivateKeyImpl :
public DL_PrivateKey<CPP_TYPENAME GP::Element>,
public DL_KeyImpl<PKCS8PrivateKey, GP>
00771 {
00772
public:
00773
typedef typename GP::Element Element;
00774
00775
00776 bool Validate(
RandomNumberGenerator &rng,
unsigned int level)
const
00777
{
00778
bool pass = GetAbstractGroupParameters().Validate(rng, level);
00779
00780
const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
00781
const Integer &x = GetPrivateExponent();
00782
00783 pass = pass && x.IsPositive() && x < q;
00784
if (level >= 1)
00785 pass = pass &&
Integer::Gcd(x, q) ==
Integer::One();
00786
return pass;
00787 }
00788
00789 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00790
{
00791
return GetValueHelper<DL_PrivateKey<Element> >(
this, name, valueType, pValue).Assignable();
00792 }
00793
00794 void AssignFrom(
const NameValuePairs &source)
00795 {
00796 AssignFromHelper<DL_PrivateKey<Element> >(
this, source);
00797 }
00798
00799 void GenerateRandom(
RandomNumberGenerator &rng,
const NameValuePairs ¶ms)
00800 {
00801
if (!params.
GetThisObject(this->AccessGroupParameters()))
00802 this->AccessGroupParameters().GenerateRandom(rng, params);
00803
00804
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
00805
00806
00807 SetPrivateExponent(x);
00808 }
00809
00810 bool SupportsPrecomputation()
const {
return true;}
00811
00812 void Precompute(
unsigned int precomputationStorage=16)
00813 {AccessAbstractGroupParameters().Precompute(precomputationStorage);}
00814
00815 void LoadPrecomputation(
BufferedTransformation &storedPrecomputation)
00816 {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
00817
00818 void SavePrecomputation(
BufferedTransformation &storedPrecomputation)
const
00819
{GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
00820
00821
00822
const DL_GroupParameters<Element> & GetAbstractGroupParameters()
const {
return this->GetGroupParameters();}
00823
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {
return this->AccessGroupParameters();}
00824
00825
00826
const Integer & GetPrivateExponent()
const {
return m_x;}
00827
void SetPrivateExponent(
const Integer &x) {m_x = x;}
00828
00829
00830 void BERDecodeKey(
BufferedTransformation &bt)
00831 {m_x.BERDecode(bt);}
00832 void DEREncodeKey(
BufferedTransformation &bt)
const
00833
{m_x.DEREncode(bt);}
00834
00835
private:
00836
Integer m_x;
00837 };
00838
00839
00840
template <
class BASE,
class SIGNATURE_SCHEME>
00841 class DL_PrivateKey_WithSignaturePairwiseConsistencyTest :
public BASE
00842 {
00843
public:
00844
void GenerateRandom(
RandomNumberGenerator &rng,
const NameValuePairs ¶ms)
00845 {
00846 BASE::GenerateRandom(rng, params);
00847
00848
if (FIPS_140_2_ComplianceEnabled())
00849 {
00850
typename SIGNATURE_SCHEME::Signer signer(*
this);
00851
typename SIGNATURE_SCHEME::Verifier verifier(signer);
00852 SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
00853 }
00854 }
00855 };
00856
00857
00858
template <
class GP>
00859 class DL_PublicKeyImpl :
public DL_PublicKey<typename GP::Element>,
public DL_KeyImpl<X509PublicKey, GP>
00860 {
00861
public:
00862
typedef typename GP::Element Element;
00863
00864
00865 bool Validate(
RandomNumberGenerator &rng,
unsigned int level)
const
00866
{
00867
bool pass = GetAbstractGroupParameters().Validate(rng, level);
00868 pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation());
00869
return pass;
00870 }
00871
00872 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00873
{
00874
return GetValueHelper<DL_PublicKey<Element> >(
this, name, valueType, pValue).Assignable();
00875 }
00876
00877 void AssignFrom(
const NameValuePairs &source)
00878 {
00879 AssignFromHelper<DL_PublicKey<Element> >(
this, source);
00880 }
00881
00882 bool SupportsPrecomputation()
const {
return true;}
00883
00884 void Precompute(
unsigned int precomputationStorage=16)
00885 {
00886 AccessAbstractGroupParameters().Precompute(precomputationStorage);
00887 AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
00888 }
00889
00890 void LoadPrecomputation(
BufferedTransformation &storedPrecomputation)
00891 {
00892 AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
00893 AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
00894 }
00895
00896 void SavePrecomputation(
BufferedTransformation &storedPrecomputation)
const
00897
{
00898 GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
00899 GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
00900 }
00901
00902
00903
const DL_GroupParameters<Element> & GetAbstractGroupParameters()
const {
return this->GetGroupParameters();}
00904
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {
return this->AccessGroupParameters();}
00905
00906
00907
const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation()
const {
return m_ypc;}
00908 DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {
return m_ypc;}
00909
00910
00911
bool operator==(
const DL_PublicKeyImpl<GP> &rhs)
const
00912
{
return this->GetGroupParameters() == rhs.
GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();}
00913
00914
private:
00915
typename GP::BasePrecomputation m_ypc;
00916 };
00917
00918
00919
template <
class T>
00920 class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm
00921 {
00922
public:
00923
virtual void Sign(
const DL_GroupParameters<T> ¶ms,
const Integer &privateKey,
const Integer &k,
const Integer &e,
Integer &r,
Integer &s)
const =0;
00924
virtual bool Verify(
const DL_GroupParameters<T> ¶ms,
const DL_PublicKey<T> &publicKey,
const Integer &e,
const Integer &r,
const Integer &s)
const =0;
00925
virtual Integer RecoverPresignature(
const DL_GroupParameters<T> ¶ms,
const DL_PublicKey<T> &publicKey,
const Integer &r,
const Integer &s)
const
00926
{
throw NotImplemented(
"DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");}
00927
virtual unsigned int RLen(
const DL_GroupParameters<T> ¶ms)
const
00928
{
return params.
GetSubgroupOrder().
ByteCount();}
00929
virtual unsigned int SLen(
const DL_GroupParameters<T> ¶ms)
const
00930
{
return params.
GetSubgroupOrder().
ByteCount();}
00931 };
00932
00933
00934
template <
class T>
00935 class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm
00936 {
00937
public:
00938
typedef T Element;
00939
00940
virtual Element AgreeWithEphemeralPrivateKey(
const DL_GroupParameters<Element> ¶ms,
const DL_FixedBasePrecomputation<Element> &publicPrecomputation,
const Integer &privateExponent)
const =0;
00941
virtual Element AgreeWithStaticPrivateKey(
const DL_GroupParameters<Element> ¶ms,
const Element &publicElement,
bool validateOtherPublicKey,
const Integer &privateExponent)
const =0;
00942 };
00943
00944
00945
template <
class T>
00946 class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
00947 {
00948
public:
00949
virtual bool ParameterSupported(
const char *name)
const {
return false;}
00950
virtual void Derive(
const DL_GroupParameters<T> &groupParams, byte *derivedKey,
unsigned int derivedLength,
const T &agreedElement,
const T &ephemeralPublicKey,
const NameValuePairs &derivationParams)
const =0;
00951 };
00952
00953
00954 class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
00955 {
00956
public:
00957
virtual bool ParameterSupported(
const char *name)
const {
return false;}
00958
virtual unsigned int GetSymmetricKeyLength(
unsigned int plaintextLength)
const =0;
00959
virtual unsigned int GetSymmetricCiphertextLength(
unsigned int plaintextLength)
const =0;
00960
virtual unsigned int GetMaxSymmetricPlaintextLength(
unsigned int ciphertextLength)
const =0;
00961
virtual void SymmetricEncrypt(
RandomNumberGenerator &rng,
const byte *key,
const byte *plaintext,
unsigned int plaintextLength, byte *ciphertext,
const NameValuePairs ¶meters)
const =0;
00962
virtual DecodingResult SymmetricDecrypt(
const byte *key,
const byte *ciphertext,
unsigned int ciphertextLength, byte *plaintext,
const NameValuePairs ¶meters)
const =0;
00963 };
00964
00965
00966
template <
class KI>
00967 class CRYPTOPP_NO_VTABLE DL_Base
00968 {
00969
protected:
00970
typedef KI KeyInterface;
00971
typedef typename KI::Element Element;
00972
00973
const DL_GroupParameters<Element> & GetAbstractGroupParameters()
const {
return GetKeyInterface().GetAbstractGroupParameters();}
00974
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {
return AccessKeyInterface().AccessAbstractGroupParameters();}
00975
00976
virtual KeyInterface & AccessKeyInterface() =0;
00977
virtual const KeyInterface & GetKeyInterface()
const =0;
00978 };
00979
00980
00981
template <
class INTERFACE,
class KEY_INTERFACE>
00982 class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase :
public INTERFACE,
public DL_Base<KEY_INTERFACE>
00983 {
00984
public:
00985
unsigned int SignatureLength()
const
00986
{
00987
return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters())
00988 + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters());
00989 }
00990
unsigned int MaxRecoverableLength()
const
00991
{
return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
00992
unsigned int MaxRecoverableLengthFromSignatureLength(
unsigned int signatureLength)
const
00993
{assert(
false);
return 0;}
00994
00995
bool IsProbabilistic()
const
00996
{
return true;}
00997
bool AllowNonrecoverablePart()
const
00998
{
return GetMessageEncodingInterface().AllowNonrecoverablePart();}
00999
bool RecoverablePartFirst()
const
01000
{
return GetMessageEncodingInterface().RecoverablePartFirst();}
01001
01002
protected:
01003
unsigned int MessageRepresentativeLength()
const {
return BitsToBytes(MessageRepresentativeBitLength());}
01004
unsigned int MessageRepresentativeBitLength()
const {
return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
01005
01006
virtual const DL_ElgamalLikeSignatureAlgorithm<CPP_TYPENAME KEY_INTERFACE::Element> & GetSignatureAlgorithm()
const =0;
01007
virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface()
const =0;
01008
virtual HashIdentifier GetHashIdentifier()
const =0;
01009
virtual unsigned int GetDigestSize()
const =0;
01010 };
01011
01012
01013
template <
class T>
01014 class CRYPTOPP_NO_VTABLE DL_SignerBase :
public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
01015 {
01016
public:
01017
01018
void RawSign(
const Integer &k,
const Integer &e,
Integer &r,
Integer &s)
const
01019
{
01020
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01021
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01022
const DL_PrivateKey<T> &key = this->GetKeyInterface();
01023
01024 r = params.
ConvertElementToInteger(params.
ExponentiateBase(k));
01025 alg.
Sign(params, key.
GetPrivateExponent(), k, e, r, s);
01026 }
01027
01028
void InputRecoverableMessage(
PK_MessageAccumulator &messageAccumulator,
const byte *recoverableMessage,
unsigned int recoverableMessageLength)
const
01029
{
01030 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01031 ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
01032 this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
01033 recoverableMessage, recoverableMessageLength,
01034 ma.m_presignature, ma.m_presignature.size(),
01035 ma.m_semisignature);
01036 }
01037
01038 unsigned int SignAndRestart(
RandomNumberGenerator &rng,
PK_MessageAccumulator &messageAccumulator, byte *signature,
bool restart)
const
01039
{
01040 this->GetMaterial().DoQuickSanityCheck();
01041
01042 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01043
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01044
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01045
const DL_PrivateKey<T> &key = this->GetKeyInterface();
01046
01047
SecByteBlock representative(this->MessageRepresentativeLength());
01048 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
01049 rng,
01050 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
01051 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01052 representative, this->MessageRepresentativeBitLength());
01053 ma.m_empty =
true;
01054
Integer e(representative, representative.size());
01055
01056
Integer r;
01057
if (this->MaxRecoverableLength() > 0)
01058 r.
Decode(ma.m_semisignature, ma.m_semisignature.size());
01059
else
01060 r.
Decode(ma.m_presignature, ma.m_presignature.size());
01061
Integer s;
01062 alg.
Sign(params, key.
GetPrivateExponent(), ma.m_k, e, r, s);
01063
01064
unsigned int rLen = alg.
RLen(params);
01065 r.Encode(signature, rLen);
01066 s.
Encode(signature+rLen, alg.
SLen(params));
01067
01068
if (restart)
01069 RestartMessageAccumulator(rng, ma);
01070
01071
return this->SignatureLength();
01072 }
01073
01074
protected:
01075
void RestartMessageAccumulator(
RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma)
const
01076
{
01077
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01078
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01079 ma.m_k.Randomize(rng, 1, params.
GetSubgroupOrder()-1);
01080 ma.m_presignature.New(params.
GetEncodedElementSize(
false));
01081 params.
ConvertElementToInteger(params.
ExponentiateBase(ma.m_k)).
Encode(ma.m_presignature, ma.m_presignature.size());
01082 }
01083 };
01084
01085
01086
template <
class T>
01087 class CRYPTOPP_NO_VTABLE DL_VerifierBase :
public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
01088 {
01089
public:
01090 void InputSignature(
PK_MessageAccumulator &messageAccumulator,
const byte *signature,
unsigned int signatureLength)
const
01091
{
01092 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01093
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01094
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01095
01096
unsigned int rLen = alg.
RLen(params);
01097 ma.m_semisignature.Assign(signature, rLen);
01098 ma.m_s.Decode(signature+rLen, alg.
SLen(params));
01099
01100 this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
01101 }
01102
01103 bool VerifyAndRestart(
PK_MessageAccumulator &messageAccumulator)
const
01104
{
01105 this->GetMaterial().DoQuickSanityCheck();
01106
01107 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01108
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01109
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01110
const DL_PublicKey<T> &key = this->GetKeyInterface();
01111
01112
SecByteBlock representative(this->MessageRepresentativeLength());
01113 this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
01114 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01115 representative, this->MessageRepresentativeBitLength());
01116 ma.m_empty =
true;
01117
Integer e(representative, representative.size());
01118
01119
Integer r(ma.m_semisignature, ma.m_semisignature.size());
01120
return alg.
Verify(params, key, e, r, ma.m_s);
01121 }
01122
01123 DecodingResult RecoverAndRestart(byte *recoveredMessage,
PK_MessageAccumulator &messageAccumulator)
const
01124
{
01125 this->GetMaterial().DoQuickSanityCheck();
01126
01127 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
01128
const DL_ElgamalLikeSignatureAlgorithm<T> &alg = this->GetSignatureAlgorithm();
01129
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01130
const DL_PublicKey<T> &key = this->GetKeyInterface();
01131
01132
SecByteBlock representative(this->MessageRepresentativeLength());
01133 this->GetMessageEncodingInterface().ComputeMessageRepresentative(
01134 NullRNG(),
01135 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
01136 ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty,
01137 representative, this->MessageRepresentativeBitLength());
01138 ma.m_empty =
true;
01139
Integer e(representative, representative.size());
01140
01141 ma.m_presignature.New(params.
GetEncodedElementSize(
false));
01142
Integer r(ma.m_semisignature, ma.m_semisignature.size());
01143 alg.
RecoverPresignature(params, key, r, ma.m_s).
Encode(ma.m_presignature, ma.m_presignature.size());
01144
01145
return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature(
01146 ma.AccessHash(), this->GetHashIdentifier(),
01147 ma.m_presignature, ma.m_presignature.size(),
01148 ma.m_semisignature, ma.m_semisignature.size(),
01149 recoveredMessage);
01150 }
01151 };
01152
01153
01154
template <
class PK,
class KI>
01155 class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase :
public PK,
public DL_Base<KI>
01156 {
01157
public:
01158
typedef typename DL_Base<KI>::Element Element;
01159
01160
unsigned int MaxPlaintextLength(
unsigned int ciphertextLength)
const
01161
{
01162
unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(
true);
01163
return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
01164 }
01165
01166
unsigned int CiphertextLength(
unsigned int plaintextLength)
const
01167
{
01168
unsigned int len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
01169
return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(
true) + len;
01170 }
01171
01172
bool ParameterSupported(
const char *name)
const
01173
{
return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
01174
01175
protected:
01176
virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm()
const =0;
01177
virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm()
const =0;
01178
virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm()
const =0;
01179 };
01180
01181
01182
template <
class T>
01183 class CRYPTOPP_NO_VTABLE DL_DecryptorBase :
public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
01184 {
01185
public:
01186
typedef T Element;
01187
01188 DecodingResult Decrypt(
RandomNumberGenerator &rng,
const byte *ciphertext,
unsigned int ciphertextLength, byte *plaintext,
const NameValuePairs ¶meters = g_nullNameValuePairs)
const
01189
{
01190
try
01191 {
01192
const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01193
const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01194
const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01195
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01196
const DL_PrivateKey<T> &key = this->GetKeyInterface();
01197
01198 Element q = params.
DecodeElement(ciphertext,
true);
01199
unsigned int elementSize = params.
GetEncodedElementSize(
true);
01200 ciphertext += elementSize;
01201 ciphertextLength -= elementSize;
01202
01203 Element z = agreeAlg.
AgreeWithStaticPrivateKey(params, q,
true, key.
GetPrivateExponent());
01204
01205
SecByteBlock derivedKey(encAlg.
GetSymmetricKeyLength(encAlg.
GetMaxSymmetricPlaintextLength(ciphertextLength)));
01206 derivAlg.
Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01207
01208
return encAlg.
SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
01209 }
01210
catch (
DL_BadElement &)
01211 {
01212
return DecodingResult();
01213 }
01214 }
01215 };
01216
01217
01218
template <
class T>
01219 class CRYPTOPP_NO_VTABLE DL_EncryptorBase :
public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
01220 {
01221
public:
01222
typedef T Element;
01223
01224 void Encrypt(
RandomNumberGenerator &rng,
const byte *plaintext,
unsigned int plaintextLength, byte *ciphertext,
const NameValuePairs ¶meters = g_nullNameValuePairs)
const
01225
{
01226
const DL_KeyAgreementAlgorithm<T> &agreeAlg = this->GetKeyAgreementAlgorithm();
01227
const DL_KeyDerivationAlgorithm<T> &derivAlg = this->GetKeyDerivationAlgorithm();
01228
const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm();
01229
const DL_GroupParameters<T> ¶ms = this->GetAbstractGroupParameters();
01230
const DL_PublicKey<T> &key = this->GetKeyInterface();
01231
01232
Integer x(rng, Integer::One(), params.
GetMaxExponent());
01233 Element q = params.
ExponentiateBase(x);
01234 params.
EncodeElement(
true, q, ciphertext);
01235
unsigned int elementSize = params.
GetEncodedElementSize(
true);
01236 ciphertext += elementSize;
01237
01238 Element z = agreeAlg.
AgreeWithEphemeralPrivateKey(params, key.
GetPublicPrecomputation(), x);
01239
01240
SecByteBlock derivedKey(encAlg.
GetSymmetricKeyLength(plaintextLength));
01241 derivAlg.
Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
01242
01243 encAlg.
SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
01244 }
01245 };
01246
01247
01248
template <
class T1,
class T2>
01249 struct DL_SchemeOptionsBase
01250 {
01251
typedef T1 AlgorithmInfo;
01252
typedef T2 GroupParameters;
01253
typedef typename GroupParameters::Element Element;
01254 };
01255
01256
01257
template <
class T1,
class T2>
01258 struct DL_KeyedSchemeOptions :
public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
01259 {
01260
typedef T2 Keys;
01261
typedef typename Keys::PrivateKey PrivateKey;
01262
typedef typename Keys::PublicKey PublicKey;
01263 };
01264
01265
01266
template <
class T1,
class T2,
class T3,
class T4,
class T5>
01267 struct DL_SignatureSchemeOptions :
public DL_KeyedSchemeOptions<T1, T2>
01268 {
01269
typedef T3 SignatureAlgorithm;
01270
typedef T4 MessageEncodingMethod;
01271
typedef T5 HashFunction;
01272 };
01273
01274
01275
template <
class T1,
class T2,
class T3,
class T4,
class T5>
01276 struct DL_CryptoSchemeOptions :
public DL_KeyedSchemeOptions<T1, T2>
01277 {
01278
typedef T3 KeyAgreementAlgorithm;
01279
typedef T4 KeyDerivationAlgorithm;
01280
typedef T5 SymmetricEncryptionAlgorithm;
01281 };
01282
01283
01284
template <
class BASE,
class SCHEME_OPTIONS,
class KEY>
01285 class CRYPTOPP_NO_VTABLE DL_ObjectImplBase :
public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
01286 {
01287
public:
01288
typedef SCHEME_OPTIONS SchemeOptions;
01289
typedef typename KEY::Element Element;
01290
01291
PrivateKey & AccessPrivateKey() {
return m_key;}
01292
PublicKey & AccessPublicKey() {
return m_key;}
01293
01294
01295
const KEY & GetKey()
const {
return m_key;}
01296 KEY & AccessKey() {
return m_key;}
01297
01298
protected:
01299
typename BASE::KeyInterface & AccessKeyInterface() {
return m_key;}
01300
const typename BASE::KeyInterface & GetKeyInterface()
const {
return m_key;}
01301
01302
01303 HashIdentifier GetHashIdentifier()
const
01304
{
01305
typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup;
01306
return HashLookup::template HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction>::Lookup();
01307 }
01308
unsigned int GetDigestSize()
const
01309
{
01310
typedef CPP_TYPENAME SchemeOptions::HashFunction H;
01311
return H::DIGESTSIZE;
01312 }
01313
01314
private:
01315 KEY m_key;
01316 };
01317
01318
01319
template <
class BASE,
class SCHEME_OPTIONS,
class KEY>
01320 class CRYPTOPP_NO_VTABLE DL_ObjectImpl :
public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
01321 {
01322
public:
01323
typedef typename KEY::Element Element;
01324
01325
protected:
01326
const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm()
const
01327
{
return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SignatureAlgorithm>().Ref();}
01328
const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm()
const
01329
{
return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyAgreementAlgorithm>().Ref();}
01330
const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm()
const
01331
{
return Singleton<CPP_TYPENAME SCHEME_OPTIONS::KeyDerivationAlgorithm>().Ref();}
01332
const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm()
const
01333
{
return Singleton<CPP_TYPENAME SCHEME_OPTIONS::SymmetricEncryptionAlgorithm>().Ref();}
01334 HashIdentifier GetHashIdentifier()
const
01335
{
return HashIdentifier();}
01336
const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface()
const
01337
{
return Singleton<CPP_TYPENAME SCHEME_OPTIONS::MessageEncodingMethod>().Ref();}
01338 };
01339
01340
01341
template <
class BASE,
class SCHEME_OPTIONS>
01342 class CRYPTOPP_NO_VTABLE DL_PublicObjectImpl :
public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>,
public PublicKeyCopier<SCHEME_OPTIONS>
01343 {
01344
public:
01345
void CopyKeyInto(
typename SCHEME_OPTIONS::PublicKey &key)
const
01346
{key = this->GetKey();}
01347 };
01348
01349
01350
template <
class BASE,
class SCHEME_OPTIONS>
01351 class CRYPTOPP_NO_VTABLE DL_PrivateObjectImpl :
public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>,
public PrivateKeyCopier<SCHEME_OPTIONS>
01352 {
01353
public:
01354
void CopyKeyInto(
typename SCHEME_OPTIONS::PublicKey &key)
const
01355
{this->GetKey().MakePublicKey(key);}
01356
void CopyKeyInto(
typename SCHEME_OPTIONS::PrivateKey &key)
const
01357
{key = this->GetKey();}
01358 };
01359
01360
01361
template <
class SCHEME_OPTIONS>
01362 class DL_SignerImpl :
public DL_PrivateObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS>
01363 {
01364
public:
01365
PK_MessageAccumulator * NewSignatureAccumulator(
RandomNumberGenerator &rng)
const
01366
{
01367 std::auto_ptr<PK_MessageAccumulatorBase> p(
new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
01368 this->RestartMessageAccumulator(rng, *p);
01369
return p.release();
01370 }
01371 };
01372
01373
01374
template <
class SCHEME_OPTIONS>
01375 class DL_VerifierImpl :
public DL_PublicObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS>
01376 {
01377
public:
01378
PK_MessageAccumulator * NewVerificationAccumulator()
const
01379
{
01380
return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
01381 }
01382 };
01383
01384
01385
template <
class SCHEME_OPTIONS>
01386 class DL_EncryptorImpl :
public DL_PublicObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS>
01387 {
01388 };
01389
01390
01391
template <
class SCHEME_OPTIONS>
01392 class DL_DecryptorImpl :
public DL_PrivateObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS>
01393 {
01394 };
01395
01396
01397
01398
01399
template <
class T>
01400 class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase :
public SimpleKeyAgreementDomain
01401 {
01402
public:
01403
typedef T Element;
01404
01405
CryptoParameters & AccessCryptoParameters() {
return AccessAbstractGroupParameters();}
01406 unsigned int AgreedValueLength()
const {
return GetAbstractGroupParameters().GetEncodedElementSize(
false);}
01407 unsigned int PrivateKeyLength()
const {
return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
01408 unsigned int PublicKeyLength()
const {
return GetAbstractGroupParameters().GetEncodedElementSize(
true);}
01409
01410 void GeneratePrivateKey(
RandomNumberGenerator &rng, byte *privateKey)
const
01411
{
01412
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
01413 x.Encode(privateKey, PrivateKeyLength());
01414 }
01415
01416 void GeneratePublicKey(
RandomNumberGenerator &rng,
const byte *privateKey, byte *publicKey)
const
01417
{
01418
const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
01419
Integer x(privateKey, PrivateKeyLength());
01420 Element y = params.
ExponentiateBase(x);
01421 params.
EncodeElement(
true, y, publicKey);
01422 }
01423
01424 bool Agree(byte *agreedValue,
const byte *privateKey,
const byte *otherPublicKey,
bool validateOtherPublicKey=
true)
const
01425
{
01426
try
01427 {
01428
const DL_GroupParameters<T> ¶ms = GetAbstractGroupParameters();
01429
Integer x(privateKey, PrivateKeyLength());
01430 Element w = params.
DecodeElement(otherPublicKey, validateOtherPublicKey);
01431
01432 Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
01433 GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
01434 params.
EncodeElement(
false, z, agreedValue);
01435 }
01436
catch (
DL_BadElement &)
01437 {
01438
return false;
01439 }
01440
return true;
01441 }
01442
01443
const Element &GetGenerator()
const {
return GetAbstractGroupParameters().GetSubgroupGenerator();}
01444
01445
protected:
01446
virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
01447 virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
01448 const DL_GroupParameters<Element> & GetAbstractGroupParameters()
const {
return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(
this)->AccessAbstractGroupParameters();}
01449 };
01450
01451
enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
01452
typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
01453
typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
01454
typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
01455
01456
01457
template <
class ELEMENT,
class COFACTOR_OPTION>
01458 class DL_KeyAgreementAlgorithm_DH :
public DL_KeyAgreementAlgorithm<ELEMENT>
01459 {
01460
public:
01461
typedef ELEMENT Element;
01462
01463
static const char *StaticAlgorithmName()
01464 {
return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ?
"DHC" :
"DH";}
01465
01466 Element AgreeWithEphemeralPrivateKey(
const DL_GroupParameters<Element> ¶ms,
const DL_FixedBasePrecomputation<Element> &publicPrecomputation,
const Integer &privateExponent)
const
01467
{
01468
return publicPrecomputation.Exponentiate(params.
GetGroupPrecomputation(),
01469 COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.
GetCofactor() : privateExponent);
01470 }
01471
01472 Element AgreeWithStaticPrivateKey(
const DL_GroupParameters<Element> ¶ms,
const Element &publicElement,
bool validateOtherPublicKey,
const Integer &privateExponent)
const
01473
{
01474
if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
01475 {
01476
const Integer &k = params.
GetCofactor();
01477
return params.
ExponentiateElement(publicElement,
01478
ModularArithmetic(params.
GetSubgroupOrder()).Divide(privateExponent, k)*k);
01479 }
01480
else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
01481
return params.
ExponentiateElement(publicElement, privateExponent*params.
GetCofactor());
01482
else
01483 {
01484 assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
01485
01486
if (!validateOtherPublicKey)
01487
return params.
ExponentiateElement(publicElement, privateExponent);
01488
01489
if (params.
FastSubgroupCheckAvailable())
01490 {
01491
if (!params.
ValidateElement(2, publicElement, NULL))
01492
throw DL_BadElement();
01493
return params.
ExponentiateElement(publicElement, privateExponent);
01494 }
01495
else
01496 {
01497
const Integer e[2] = {params.
GetSubgroupOrder(), privateExponent};
01498 Element r[2];
01499 params.
SimultaneousExponentiate(r, publicElement, e, 2);
01500
if (!params.
IsIdentity(r[0]))
01501
throw DL_BadElement();
01502
return r[1];
01503 }
01504 }
01505 }
01506 };
01507
01508
01509
01510
01511
template <
class BASE>
01512 class CRYPTOPP_NO_VTABLE PK_FinalTemplate :
public BASE
01513 {
01514
public:
01515 PK_FinalTemplate() {}
01516
01517 PK_FinalTemplate(
const Integer &v1)
01518 {this->AccessKey().Initialize(v1);}
01519
01520 PK_FinalTemplate(
const typename BASE::KeyClass &key) {this->AccessKey().operator=(key);}
01521
01522
template <
class T>
01523 PK_FinalTemplate(
const PublicKeyCopier<T> &key)
01524 {key.
CopyKeyInto(this->AccessKey());}
01525
01526
template <
class T>
01527 PK_FinalTemplate(
const PrivateKeyCopier<T> &key)
01528 {key.
CopyKeyInto(this->AccessKey());}
01529
01530 PK_FinalTemplate(
BufferedTransformation &bt) {this->AccessKey().BERDecode(bt);}
01531
01532
#if (defined(_MSC_VER) && _MSC_VER < 1300)
01533
01534
template <
class T1,
class T2>
01535 PK_FinalTemplate(T1 &v1, T2 &v2)
01536 {this->AccessKey().Initialize(v1, v2);}
01537
01538
template <
class T1,
class T2,
class T3>
01539 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
01540 {this->AccessKey().Initialize(v1, v2, v3);}
01541
01542
template <
class T1,
class T2,
class T3,
class T4>
01543 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
01544 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01545
01546
template <
class T1,
class T2,
class T3,
class T4,
class T5>
01547 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
01548 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01549
01550
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
01551 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
01552 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01553
01554
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
01555 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
01556 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01557
01558
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8>
01559 PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
01560 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01561
01562
#else
01563
01564
template <
class T1,
class T2>
01565 PK_FinalTemplate(
const T1 &v1,
const T2 &v2)
01566 {this->AccessKey().Initialize(v1, v2);}
01567
01568
template <
class T1,
class T2,
class T3>
01569 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3)
01570 {this->AccessKey().Initialize(v1, v2, v3);}
01571
01572
template <
class T1,
class T2,
class T3,
class T4>
01573 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4)
01574 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01575
01576
template <
class T1,
class T2,
class T3,
class T4,
class T5>
01577 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5)
01578 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01579
01580
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
01581 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6)
01582 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01583
01584
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
01585 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6,
const T7 &v7)
01586 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01587
01588
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8>
01589 PK_FinalTemplate(
const T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6,
const T7 &v7,
const T8 &v8)
01590 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01591
01592
template <
class T1,
class T2>
01593 PK_FinalTemplate(T1 &v1,
const T2 &v2)
01594 {this->AccessKey().Initialize(v1, v2);}
01595
01596
template <
class T1,
class T2,
class T3>
01597 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3)
01598 {this->AccessKey().Initialize(v1, v2, v3);}
01599
01600
template <
class T1,
class T2,
class T3,
class T4>
01601 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4)
01602 {this->AccessKey().Initialize(v1, v2, v3, v4);}
01603
01604
template <
class T1,
class T2,
class T3,
class T4,
class T5>
01605 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5)
01606 {this->AccessKey().Initialize(v1, v2, v3, v4, v5);}
01607
01608
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6>
01609 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6)
01610 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
01611
01612
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7>
01613 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6,
const T7 &v7)
01614 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
01615
01616
template <
class T1,
class T2,
class T3,
class T4,
class T5,
class T6,
class T7,
class T8>
01617 PK_FinalTemplate(T1 &v1,
const T2 &v2,
const T3 &v3,
const T4 &v4,
const T5 &v5,
const T6 &v6,
const T7 &v7,
const T8 &v8)
01618 {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
01619
01620
#endif
01621
};
01622
01623
01624 struct EncryptionStandard {};
01625
01626
01627 struct SignatureStandard {};
01628
01629
template <
class STANDARD,
class KEYS,
class ALG_INFO>
01630
class TF_ES;
01631
01632
01633
template <
class STANDARD,
class KEYS,
class ALG_INFO = TF_ES<STANDARD, KEYS,
int> >
01634 class TF_ES :
public KEYS
01635 {
01636
typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
01637
01638
public:
01639
01640 typedef STANDARD
Standard;
01641
typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
01642
01643
static std::string StaticAlgorithmName() {
return KEYS::StaticAlgorithmName() +
"/" + MessageEncodingMethod::StaticAlgorithmName();}
01644
01645
01646 typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> >
Decryptor;
01647
01648 typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> >
Encryptor;
01649 };
01650
01651
template <
class STANDARD,
class H,
class KEYS,
class ALG_INFO>
01652
class TF_SS;
01653
01654
01655
template <
class STANDARD,
class H,
class KEYS,
class ALG_INFO = TF_SS<STANDARD, H, KEYS,
int> >
01656 class TF_SS :
public KEYS
01657 {
01658
public:
01659
01660 typedef STANDARD
Standard;
01661
typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
01662
typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
01663
01664
static std::string StaticAlgorithmName() {
return KEYS::StaticAlgorithmName() +
"/" + MessageEncodingMethod::StaticAlgorithmName() +
"(" + H::StaticAlgorithmName() +
")";}
01665
01666
01667 typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> >
Signer;
01668
01669 typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> >
Verifier;
01670 };
01671
01672
template <
class KEYS,
class SA,
class MEM,
class H,
class ALG_INFO>
01673
class DL_SS;
01674
01675
01676
template <
class KEYS,
class SA,
class MEM,
class H,
class ALG_INFO = DL_SS<KEYS, SA, MEM, H,
int> >
01677 class DL_SS :
public KEYS
01678 {
01679
typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
01680
01681
public:
01682
static std::string StaticAlgorithmName() {
return SA::StaticAlgorithmName() + std::string(
"/EMSA1(") + H::StaticAlgorithmName() +
")";}
01683
01684
01685 typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> >
Signer;
01686
01687 typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> >
Verifier;
01688 };
01689
01690
01691
template <
class KEYS,
class AA,
class DA,
class EA,
class ALG_INFO>
01692 class DL_ES :
public KEYS
01693 {
01694
typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
01695
01696
public:
01697
01698 typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> >
Decryptor;
01699
01700 typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> >
Encryptor;
01701 };
01702
01703 NAMESPACE_END
01704
01705
#endif