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