monotone

monotone Mtn Source Tree

Root/cryptopp/pubkey.h

1// pubkey.h - written and placed in the public domain by Wei Dai
2
3#ifndef CRYPTOPP_PUBKEY_H
4#define CRYPTOPP_PUBKEY_H
5
6/** \file
7
8This file contains helper classes/functions for implementing public key algorithms.
9
10The class hierachies in this .h file tend to look like this:
11<pre>
12 x1
13 / \
14 y1 z1
15 | |
16 x2<y1> x2<z1>
17 | |
18 y2 z2
19 | |
20 x3<y2> x3<z2>
21 | |
22 y3 z3
23</pre>
24- x1, y1, z1 are abstract interface classes defined in cryptlib.h
25- x2, y2, z2 are implementations of the interfaces using "abstract policies", which
26 are pure virtual functions that should return interfaces to interchangeable algorithms.
27 These classes have "Base" suffixes.
28- x3, y3, z3 hold actual algorithms and implement those virtual functions.
29 These classes have "Impl" suffixes.
30
31The "TF_" prefix means an implementation using trapdoor functions on integers.
32The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard).
33*/
34
35#include "integer.h"
36#include "filters.h"
37#include "eprecomp.h"
38#include "fips140.h"
39#include "argnames.h"
40#include <memory>
41
42// VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file
43#undef INTERFACE
44
45NAMESPACE_BEGIN(CryptoPP)
46
47Integer NR_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen);
48Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen);
49
50// ********************************************************
51
52//! .
53class TrapdoorFunctionBounds
54{
55public:
56virtual ~TrapdoorFunctionBounds() {}
57
58virtual Integer PreimageBound() const =0;
59virtual Integer ImageBound() const =0;
60virtual Integer MaxPreimage() const {return --PreimageBound();}
61virtual Integer MaxImage() const {return --ImageBound();}
62};
63
64//! .
65class RandomizedTrapdoorFunction : public TrapdoorFunctionBounds
66{
67public:
68virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0;
69virtual bool IsRandomized() const {return true;}
70};
71
72//! .
73class TrapdoorFunction : public RandomizedTrapdoorFunction
74{
75public:
76Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const
77{return ApplyFunction(x);}
78bool IsRandomized() const {return false;}
79
80virtual Integer ApplyFunction(const Integer &x) const =0;
81};
82
83//! .
84class RandomizedTrapdoorFunctionInverse
85{
86public:
87virtual ~RandomizedTrapdoorFunctionInverse() {}
88
89virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
90virtual bool IsRandomized() const {return true;}
91};
92
93//! .
94class TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse
95{
96public:
97virtual ~TrapdoorFunctionInverse() {}
98
99Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
100{return CalculateInverse(rng, x);}
101bool IsRandomized() const {return false;}
102
103virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0;
104};
105
106// ********************************************************
107
108//! .
109class PK_EncryptionMessageEncodingMethod
110{
111public:
112virtual ~PK_EncryptionMessageEncodingMethod() {}
113
114//! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
115virtual unsigned int MaxUnpaddedLength(unsigned int paddedLength) const =0;
116
117virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedBitLength) const =0;
118
119virtual DecodingResult Unpad(const byte *padded, unsigned int paddedBitLength, byte *raw) const =0;
120};
121
122// ********************************************************
123
124//! .
125template <class TFI, class MEI>
126class TF_Base
127{
128protected:
129virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0;
130
131typedef TFI TrapdoorFunctionInterface;
132virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0;
133
134typedef MEI MessageEncodingInterface;
135virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0;
136};
137
138// ********************************************************
139
140//! .
141template <class INTERFACE, class BASE>
142class TF_CryptoSystemBase : public INTERFACE, protected BASE
143{
144public:
145unsigned int FixedMaxPlaintextLength() const {return GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
146unsigned int FixedCiphertextLength() const {return GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
147
148protected:
149unsigned int PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());}
150unsigned int PaddedBlockBitLength() const {return GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;}
151};
152
153//! .
154class TF_DecryptorBase : public TF_CryptoSystemBase<PK_FixedLengthDecryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
155{
156public:
157DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const;
158};
159
160//! .
161class TF_EncryptorBase : public TF_CryptoSystemBase<PK_FixedLengthEncryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
162{
163public:
164void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const;
165};
166
167// ********************************************************
168
169typedef std::pair<const byte *, unsigned int> HashIdentifier;
170
171//! .
172class PK_SignatureMessageEncodingMethod
173{
174public:
175virtual ~PK_SignatureMessageEncodingMethod() {}
176
177virtual unsigned int MaxRecoverableLength(unsigned int representativeBitLength, unsigned int hashIdentifierLength, unsigned int digestLength) const
178{return 0;}
179
180bool IsProbabilistic() const
181{return true;}
182bool AllowNonrecoverablePart() const
183{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
184virtual bool RecoverablePartFirst() const
185{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
186
187// for verification, DL
188virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, unsigned int semisignatureLength) const {}
189
190// for signature
191virtual void ProcessRecoverableMessage(HashTransformation &hash,
192const byte *recoverableMessage, unsigned int recoverableMessageLength,
193const byte *presignature, unsigned int presignatureLength,
194SecByteBlock &semisignature) const
195{
196if (RecoverablePartFirst())
197assert(!"ProcessRecoverableMessage() not implemented");
198}
199
200virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng,
201const byte *recoverableMessage, unsigned int recoverableMessageLength,
202HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
203byte *representative, unsigned int representativeBitLength) const =0;
204
205virtual bool VerifyMessageRepresentative(
206HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
207byte *representative, unsigned int representativeBitLength) const =0;
208
209virtual DecodingResult RecoverMessageFromRepresentative(// for TF
210HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
211byte *representative, unsigned int representativeBitLength,
212byte *recoveredMessage) const
213{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
214
215virtual DecodingResult RecoverMessageFromSemisignature(// for DL
216HashTransformation &hash, HashIdentifier hashIdentifier,
217const byte *presignature, unsigned int presignatureLength,
218const byte *semisignature, unsigned int semisignatureLength,
219byte *recoveredMessage) const
220{throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");}
221
222// VC60 workaround
223struct HashIdentifierLookup
224{
225template <class H> struct HashIdentifierLookup2
226{
227static HashIdentifier Lookup()
228{
229return HashIdentifier(NULL, 0);
230}
231};
232};
233};
234
235class PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
236{
237public:
238bool VerifyMessageRepresentative(
239HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
240byte *representative, unsigned int representativeBitLength) const;
241};
242
243class PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod
244{
245public:
246bool VerifyMessageRepresentative(
247HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
248byte *representative, unsigned int representativeBitLength) const;
249};
250
251class DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod
252{
253public:
254void ComputeMessageRepresentative(RandomNumberGenerator &rng,
255const byte *recoverableMessage, unsigned int recoverableMessageLength,
256HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
257byte *representative, unsigned int representativeBitLength) const;
258};
259
260class DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod
261{
262public:
263void ComputeMessageRepresentative(RandomNumberGenerator &rng,
264const byte *recoverableMessage, unsigned int recoverableMessageLength,
265HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
266byte *representative, unsigned int representativeBitLength) const;
267};
268
269class PK_MessageAccumulatorBase : public PK_MessageAccumulator
270{
271public:
272PK_MessageAccumulatorBase() : m_empty(true) {}
273
274virtual HashTransformation & AccessHash() =0;
275
276void Update(const byte *input, unsigned int length)
277{
278AccessHash().Update(input, length);
279m_empty = m_empty && length == 0;
280}
281
282SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature;
283Integer m_k, m_s;
284bool m_empty;
285};
286
287template <class HASH_ALGORITHM>
288class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder<HASH_ALGORITHM>
289{
290public:
291HashTransformation & AccessHash() {return m_object;}
292};
293
294//! .
295template <class INTERFACE, class BASE>
296class TF_SignatureSchemeBase : public INTERFACE, protected BASE
297{
298public:
299unsigned int SignatureLength() const
300{return GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();}
301unsigned int MaxRecoverableLength() const
302{return GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());}
303unsigned int MaxRecoverableLengthFromSignatureLength(unsigned int signatureLength) const
304{return MaxRecoverableLength();}
305
306bool IsProbabilistic() const
307{return GetTrapdoorFunctionInterface().IsRandomized() || GetMessageEncodingInterface().IsProbabilistic();}
308bool AllowNonrecoverablePart() const
309{return GetMessageEncodingInterface().AllowNonrecoverablePart();}
310bool RecoverablePartFirst() const
311{return GetMessageEncodingInterface().RecoverablePartFirst();}
312
313protected:
314unsigned int MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
315unsigned int MessageRepresentativeBitLength() const {return GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;}
316virtual HashIdentifier GetHashIdentifier() const =0;
317virtual unsigned int GetDigestSize() const =0;
318};
319
320//! .
321class TF_SignerBase : public TF_SignatureSchemeBase<PK_Signer, TF_Base<RandomizedTrapdoorFunctionInverse, PK_SignatureMessageEncodingMethod> >
322{
323public:
324void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const;
325unsigned int SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const;
326};
327
328//! .
329class TF_VerifierBase : public TF_SignatureSchemeBase<PK_Verifier, TF_Base<TrapdoorFunction, PK_SignatureMessageEncodingMethod> >
330{
331public:
332void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const;
333bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
334DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const;
335};
336
337// ********************************************************
338
339//! .
340template <class T1, class T2, class T3>
341struct TF_CryptoSchemeOptions
342{
343typedef T1 AlgorithmInfo;
344typedef T2 Keys;
345typedef typename Keys::PrivateKey PrivateKey;
346typedef typename Keys::PublicKey PublicKey;
347typedef T3 MessageEncodingMethod;
348};
349
350//! .
351template <class T1, class T2, class T3, class T4>
352struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions<T1, T2, T3>
353{
354typedef T4 HashFunction;
355};
356
357//! .
358template <class KEYS>
359class PublicKeyCopier
360{
361public:
362virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0;
363};
364
365//! .
366template <class KEYS>
367class PrivateKeyCopier
368{
369public:
370virtual void CopyKeyInto(typename KEYS::PublicKey &key) const =0;
371virtual void CopyKeyInto(typename KEYS::PrivateKey &key) const =0;
372};
373
374//! .
375template <class BASE, class SCHEME_OPTIONS, class KEY>
376class TF_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
377{
378public:
379typedef SCHEME_OPTIONS SchemeOptions;
380typedef KEY KeyClass;
381
382PublicKey & AccessPublicKey() {return AccessKey();}
383const PublicKey & GetPublicKey() const {return GetKey();}
384
385PrivateKey & AccessPrivateKey() {return AccessKey();}
386const PrivateKey & GetPrivateKey() const {return GetKey();}
387
388virtual const KeyClass & GetKey() const =0;
389virtual KeyClass & AccessKey() =0;
390
391const KeyClass & GetTrapdoorFunction() const {return GetKey();}
392
393protected:
394const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const
395{static typename SCHEME_OPTIONS::MessageEncodingMethod messageEncodingMethod; return messageEncodingMethod;}
396const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const
397{return GetKey();}
398const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const
399{return GetKey();}
400
401// for signature scheme
402HashIdentifier GetHashIdentifier() const
403{
404typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
405return L::Lookup();
406}
407unsigned int GetDigestSize() const
408{
409typedef CPP_TYPENAME SchemeOptions::HashFunction H;
410return H::DIGESTSIZE;
411}
412};
413
414//! .
415template <class BASE, class SCHEME_OPTIONS, class KEY>
416class TF_ObjectImplExtRef : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
417{
418public:
419TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {}
420void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;}
421
422const KEY & GetKey() const {return *m_pKey;}
423KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");}
424
425void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {assert(false);}
426void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {assert(false);}
427
428private:
429const KEY * m_pKey;
430};
431
432//! .
433template <class BASE, class SCHEME_OPTIONS, class KEY>
434class TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
435{
436public:
437const KEY & GetKey() const {return m_trapdoorFunction;}
438KEY & AccessKey() {return m_trapdoorFunction;}
439
440private:
441KEY m_trapdoorFunction;
442};
443
444//! .
445template <class BASE, class SCHEME_OPTIONS>
446class TF_PublicObjectImpl : public TF_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>, public PublicKeyCopier<SCHEME_OPTIONS>
447{
448public:
449void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();}
450};
451
452//! .
453template <class BASE, class SCHEME_OPTIONS>
454class TF_PrivateObjectImpl : public TF_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>, public PrivateKeyCopier<SCHEME_OPTIONS>
455{
456public:
457void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const {key = GetKey();}
458void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const {key = GetKey();}
459};
460
461//! .
462template <class SCHEME_OPTIONS>
463class TF_DecryptorImpl : public TF_PrivateObjectImpl<TF_DecryptorBase, SCHEME_OPTIONS>
464{
465};
466
467//! .
468template <class SCHEME_OPTIONS>
469class TF_EncryptorImpl : public TF_PublicObjectImpl<TF_EncryptorBase, SCHEME_OPTIONS>
470{
471};
472
473//! .
474template <class SCHEME_OPTIONS>
475class TF_SignerImpl : public TF_PrivateObjectImpl<TF_SignerBase, SCHEME_OPTIONS>
476{
477PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng = NullRNG()) const
478{
479return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
480}
481};
482
483//! .
484template <class SCHEME_OPTIONS>
485class TF_VerifierImpl : public TF_PublicObjectImpl<TF_VerifierBase, SCHEME_OPTIONS>
486{
487PK_MessageAccumulator * NewVerificationAccumulator() const
488{
489return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
490}
491};
492
493// ********************************************************
494
495class MaskGeneratingFunction
496{
497public:
498virtual ~MaskGeneratingFunction() {}
499virtual void GenerateAndMask(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask = true) const =0;
500};
501
502void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask, unsigned int counterStart);
503
504//! .
505class P1363_MGF1 : public MaskGeneratingFunction
506{
507public:
508static const char * StaticAlgorithmName() {return "MGF1";}
509#if 0
510// VC60 workaround: this function causes internal compiler error
511template <class H>
512static void GenerateAndMaskTemplate(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, H* dummy=NULL)
513{
514H h;
515P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, mask, 0);
516}
517#endif
518void GenerateAndMask(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask = true) const
519{
520P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, mask, 0);
521}
522};
523
524// ********************************************************
525
526//! .
527template <class H>
528class P1363_KDF2
529{
530public:
531static void DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength)
532{
533H h;
534P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, false, 1);
535}
536};
537
538// ********************************************************
539
540// to be thrown by DecodeElement and AgreeWithStaticPrivateKey
541class DL_BadElement : public InvalidDataFormat
542{
543public:
544DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {}
545};
546
547//! .
548template <class T>
549class DL_GroupParameters : public CryptoParameters
550{
551typedef DL_GroupParameters<T> ThisClass;
552
553public:
554typedef T Element;
555
556DL_GroupParameters() : m_validationLevel(0) {}
557
558// CryptoMaterial
559bool Validate(RandomNumberGenerator &rng, unsigned int level) const
560{
561if (!GetBasePrecomputation().IsInitialized())
562return false;
563
564if (m_validationLevel > level)
565return true;
566
567bool pass = ValidateGroup(rng, level);
568pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation());
569
570m_validationLevel = pass ? level+1 : 0;
571
572return pass;
573}
574
575bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
576{
577return GetValueHelper(this, name, valueType, pValue)
578CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
579CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
580;
581}
582
583bool SupportsPrecomputation() const {return true;}
584
585void Precompute(unsigned int precomputationStorage=16)
586{
587AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage);
588}
589
590void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
591{
592AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation);
593m_validationLevel = 0;
594}
595
596void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
597{
598GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation);
599}
600
601// non-inherited
602virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());}
603virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);}
604virtual Element ExponentiateBase(const Integer &exponent) const
605{
606return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent);
607}
608virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const
609{
610Element result;
611SimultaneousExponentiate(&result, base, &exponent, 1);
612return result;
613}
614
615virtual const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const =0;
616virtual const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const =0;
617virtual DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() =0;
618virtual const Integer & GetSubgroupOrder() const =0;// order of subgroup generated by base element
619virtual Integer GetMaxExponent() const =0;
620virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();}// one of these two needs to be overriden
621virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();}
622virtual unsigned int GetEncodedElementSize(bool reversible) const =0;
623virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0;
624virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0;
625virtual Integer ConvertElementToInteger(const Element &element) const =0;
626virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0;
627virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const =0;
628virtual bool FastSubgroupCheckAvailable() const =0;
629virtual bool IsIdentity(const Element &element) const =0;
630virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0;
631
632protected:
633void ParametersChanged() {m_validationLevel = 0;}
634
635private:
636mutable unsigned int m_validationLevel;
637};
638
639//! .
640template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element>, class BASE = DL_GroupParameters<typename GROUP_PRECOMP::Element> >
641class DL_GroupParametersImpl : public BASE
642{
643public:
644typedef GROUP_PRECOMP GroupPrecomputation;
645typedef typename GROUP_PRECOMP::Element Element;
646typedef BASE_PRECOMP BasePrecomputation;
647
648const DL_GroupPrecomputation<Element> & GetGroupPrecomputation() const {return m_groupPrecomputation;}
649const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return m_gpc;}
650DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return m_gpc;}
651
652protected:
653GROUP_PRECOMP m_groupPrecomputation;
654BASE_PRECOMP m_gpc;
655};
656
657//! .
658template <class T>
659class DL_Key
660{
661public:
662virtual const DL_GroupParameters<T> & GetAbstractGroupParameters() const =0;
663virtual DL_GroupParameters<T> & AccessAbstractGroupParameters() =0;
664};
665
666//! .
667template <class T>
668class DL_PublicKey : public DL_Key<T>
669{
670typedef DL_PublicKey<T> ThisClass;
671
672public:
673typedef T Element;
674
675bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
676{
677return GetValueHelper(this, name, valueType, pValue, &GetAbstractGroupParameters())
678CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement);
679}
680
681void AssignFrom(const NameValuePairs &source);
682
683// non-inherited
684virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(GetAbstractGroupParameters().GetGroupPrecomputation());}
685virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(GetAbstractGroupParameters().GetGroupPrecomputation(), y);}
686virtual Element ExponentiatePublicElement(const Integer &exponent) const
687{
688const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
689return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent);
690}
691virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
692{
693const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
694return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp);
695}
696
697virtual const DL_FixedBasePrecomputation<T> & GetPublicPrecomputation() const =0;
698virtual DL_FixedBasePrecomputation<T> & AccessPublicPrecomputation() =0;
699};
700
701//! .
702template <class T>
703class DL_PrivateKey : public DL_Key<T>
704{
705typedef DL_PrivateKey<T> ThisClass;
706
707public:
708typedef T Element;
709
710void MakePublicKey(DL_PublicKey<T> &pub) const
711{
712pub.AccessAbstractGroupParameters().AssignFrom(GetAbstractGroupParameters());
713pub.SetPublicElement(GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent()));
714}
715
716bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
717{
718return GetValueHelper(this, name, valueType, pValue, &GetAbstractGroupParameters())
719CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent);
720}
721
722void AssignFrom(const NameValuePairs &source)
723{
724AccessAbstractGroupParameters().AssignFrom(source);
725AssignFromHelper(this, source)
726CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent);
727}
728
729virtual const Integer & GetPrivateExponent() const =0;
730virtual void SetPrivateExponent(const Integer &x) =0;
731};
732
733template <class T>
734void DL_PublicKey<T>::AssignFrom(const NameValuePairs &source)
735{
736DL_PrivateKey<T> *pPrivateKey = NULL;
737if (source.GetThisPointer(pPrivateKey))
738pPrivateKey->MakePublicKey(*this);
739else
740{
741AccessAbstractGroupParameters().AssignFrom(source);
742AssignFromHelper(this, source)
743CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement);
744}
745}
746
747class OID;
748
749//! .
750template <class PK, class GP>
751class DL_KeyImpl : public PK
752{
753public:
754typedef GP GroupParameters;
755
756OID GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();}
757//void BERDecode(BufferedTransformation &bt)
758//{PK::BERDecode(bt);}
759//void DEREncode(BufferedTransformation &bt) const
760//{PK::DEREncode(bt);}
761bool BERDecodeAlgorithmParameters(BufferedTransformation &bt)
762{AccessGroupParameters().BERDecode(bt); return true;}
763bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const
764{GetGroupParameters().DEREncode(bt); return true;}
765
766const GP & GetGroupParameters() const {return m_groupParameters;}
767GP & AccessGroupParameters() {return m_groupParameters;}
768
769private:
770GP m_groupParameters;
771};
772
773class X509PublicKey;
774class PKCS8PrivateKey;
775
776//! .
777template <class GP>
778class DL_PrivateKeyImpl : public DL_PrivateKey<CPP_TYPENAME GP::Element>, public DL_KeyImpl<PKCS8PrivateKey, GP>
779{
780public:
781typedef typename GP::Element Element;
782
783// GeneratableCryptoMaterial
784bool Validate(RandomNumberGenerator &rng, unsigned int level) const
785{
786bool pass = GetAbstractGroupParameters().Validate(rng, level);
787
788const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder();
789const Integer &x = GetPrivateExponent();
790
791pass = pass && x.IsPositive() && x < q;
792if (level >= 1)
793pass = pass && Integer::Gcd(x, q) == Integer::One();
794return pass;
795}
796
797bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
798{
799return GetValueHelper<DL_PrivateKey<Element> >(this, name, valueType, pValue).Assignable();
800}
801
802void AssignFrom(const NameValuePairs &source)
803{
804AssignFromHelper<DL_PrivateKey<Element> >(this, source);
805}
806
807void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
808{
809if (!params.GetThisObject(AccessGroupParameters()))
810AccessGroupParameters().GenerateRandom(rng, params);
811//std::pair<const byte *, int> seed;
812Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
813//Integer::ANY, Integer::Zero(), Integer::One(),
814//params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL);
815SetPrivateExponent(x);
816}
817
818bool SupportsPrecomputation() const {return true;}
819
820void Precompute(unsigned int precomputationStorage=16)
821{AccessAbstractGroupParameters().Precompute(precomputationStorage);}
822
823void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
824{AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);}
825
826void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
827{GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);}
828
829// DL_Key
830const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetGroupParameters();}
831DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessGroupParameters();}
832
833// DL_PrivateKey
834const Integer & GetPrivateExponent() const {return m_x;}
835void SetPrivateExponent(const Integer &x) {m_x = x;}
836
837// PKCS8PrivateKey
838void BERDecodeKey(BufferedTransformation &bt)
839{m_x.BERDecode(bt);}
840void DEREncodeKey(BufferedTransformation &bt) const
841{m_x.DEREncode(bt);}
842
843private:
844Integer m_x;
845};
846
847//! .
848template <class BASE, class SIGNATURE_SCHEME>
849class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE
850{
851public:
852void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
853{
854BASE::GenerateRandom(rng, params);
855
856if (FIPS_140_2_ComplianceEnabled())
857{
858typename SIGNATURE_SCHEME::Signer signer(*this);
859typename SIGNATURE_SCHEME::Verifier verifier(signer);
860SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier);
861}
862}
863};
864
865//! .
866template <class GP>
867class DL_PublicKeyImpl : public DL_PublicKey<typename GP::Element>, public DL_KeyImpl<X509PublicKey, GP>
868{
869public:
870typedef typename GP::Element Element;
871
872// CryptoMaterial
873bool Validate(RandomNumberGenerator &rng, unsigned int level) const
874{
875bool pass = GetAbstractGroupParameters().Validate(rng, level);
876pass = pass && GetAbstractGroupParameters().ValidateElement(level, GetPublicElement(), &GetPublicPrecomputation());
877return pass;
878}
879
880bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
881{
882return GetValueHelper<DL_PublicKey<Element> >(this, name, valueType, pValue).Assignable();
883}
884
885void AssignFrom(const NameValuePairs &source)
886{
887AssignFromHelper<DL_PublicKey<Element> >(this, source);
888}
889
890bool SupportsPrecomputation() const {return true;}
891
892void Precompute(unsigned int precomputationStorage=16)
893{
894AccessAbstractGroupParameters().Precompute(precomputationStorage);
895AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage);
896}
897
898void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
899{
900AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);
901AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
902}
903
904void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
905{
906GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);
907GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation);
908}
909
910// DL_Key
911const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetGroupParameters();}
912DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessGroupParameters();}
913
914// DL_PublicKey
915const DL_FixedBasePrecomputation<Element> & GetPublicPrecomputation() const {return m_ypc;}
916DL_FixedBasePrecomputation<Element> & AccessPublicPrecomputation() {return m_ypc;}
917
918// non-inherited
919bool operator==(const DL_PublicKeyImpl<GP> &rhs) const
920{return GetGroupParameters() == rhs.GetGroupParameters() && GetPublicElement() == rhs.GetPublicElement();}
921
922private:
923typename GP::BasePrecomputation m_ypc;
924};
925
926//! .
927template <class T>
928class DL_ElgamalLikeSignatureAlgorithm
929{
930public:
931//virtual Integer EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLength) const =0;
932virtual void Sign(const DL_GroupParameters<T> &params, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
933virtual bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
934virtual Integer RecoverPresignature(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
935{throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");}
936virtual unsigned int RLen(const DL_GroupParameters<T> &params) const
937{return params.GetSubgroupOrder().ByteCount();}
938virtual unsigned int SLen(const DL_GroupParameters<T> &params) const
939{return params.GetSubgroupOrder().ByteCount();}
940};
941
942//! .
943template <class T>
944class DL_KeyAgreementAlgorithm
945{
946public:
947typedef T Element;
948
949virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const =0;
950virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0;
951};
952
953//! .
954template <class T>
955class DL_KeyDerivationAlgorithm
956{
957public:
958virtual void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey) const =0;
959};
960
961//! .
962class DL_SymmetricEncryptionAlgorithm
963{
964public:
965virtual unsigned int GetSymmetricKeyLength(unsigned int plainTextLength) const =0;
966virtual unsigned int GetSymmetricCiphertextLength(unsigned int plainTextLength) const =0;
967virtual unsigned int GetMaxSymmetricPlaintextLength(unsigned int cipherTextLength) const =0;
968virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const =0;
969virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const =0;
970};
971
972//! .
973template <class KI>
974class DL_Base
975{
976protected:
977typedef KI KeyInterface;
978typedef typename KI::Element Element;
979
980const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();}
981DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();}
982
983virtual KeyInterface & AccessKeyInterface() =0;
984virtual const KeyInterface & GetKeyInterface() const =0;
985};
986
987//! .
988template <class INTERFACE, class KEY_INTERFACE>
989class DL_SignatureSchemeBase : public INTERFACE, public DL_Base<KEY_INTERFACE>
990{
991public:
992unsigned int SignatureLength() const
993{
994return GetSignatureAlgorithm().RLen(GetAbstractGroupParameters())
995+ GetSignatureAlgorithm().SLen(GetAbstractGroupParameters());
996}
997unsigned int MaxRecoverableLength() const
998{return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());}
999unsigned int MaxRecoverableLengthFromSignatureLength(unsigned int signatureLength) const
1000{assert(false); return 0;}// TODO
1001
1002bool IsProbabilistic() const
1003{return true;}
1004bool AllowNonrecoverablePart() const
1005{return GetMessageEncodingInterface().AllowNonrecoverablePart();}
1006bool RecoverablePartFirst() const
1007{return GetMessageEncodingInterface().RecoverablePartFirst();}
1008
1009protected:
1010unsigned int MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
1011unsigned int MessageRepresentativeBitLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
1012
1013virtual const DL_ElgamalLikeSignatureAlgorithm<CPP_TYPENAME KEY_INTERFACE::Element> & GetSignatureAlgorithm() const =0;
1014virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
1015virtual HashIdentifier GetHashIdentifier() const =0;
1016virtual unsigned int GetDigestSize() const =0;
1017};
1018
1019//! .
1020template <class T>
1021class DL_SignerBase : public DL_SignatureSchemeBase<PK_Signer, DL_PrivateKey<T> >
1022{
1023public:
1024// for validation testing
1025void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const
1026{
1027const DL_ElgamalLikeSignatureAlgorithm<T> &alg = GetSignatureAlgorithm();
1028const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1029const DL_PrivateKey<T> &key = GetKeyInterface();
1030
1031r = params.ConvertElementToInteger(params.ExponentiateBase(k));
1032alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
1033}
1034
1035void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const
1036{
1037PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1038ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
1039GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(),
1040recoverableMessage, recoverableMessageLength,
1041ma.m_presignature, ma.m_presignature.size(),
1042ma.m_semisignature);
1043}
1044
1045unsigned int SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
1046{
1047GetMaterial().DoQuickSanityCheck();
1048
1049PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1050const DL_ElgamalLikeSignatureAlgorithm<T> &alg = GetSignatureAlgorithm();
1051const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1052const DL_PrivateKey<T> &key = GetKeyInterface();
1053
1054SecByteBlock representative(MessageRepresentativeLength());
1055GetMessageEncodingInterface().ComputeMessageRepresentative(
1056rng,
1057ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1058ma.AccessHash(), GetHashIdentifier(), ma.m_empty,
1059representative, MessageRepresentativeBitLength());
1060ma.m_empty = true;
1061Integer e(representative, representative.size());
1062
1063Integer r;
1064if (MaxRecoverableLength() > 0)
1065r.Decode(ma.m_semisignature, ma.m_semisignature.size());
1066else
1067r.Decode(ma.m_presignature, ma.m_presignature.size());
1068Integer s;
1069alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s);
1070
1071unsigned int rLen = alg.RLen(params);
1072r.Encode(signature, rLen);
1073s.Encode(signature+rLen, alg.SLen(params));
1074
1075if (restart)
1076RestartMessageAccumulator(rng, ma);
1077
1078return SignatureLength();
1079}
1080
1081protected:
1082void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const
1083{
1084const DL_ElgamalLikeSignatureAlgorithm<T> &alg = GetSignatureAlgorithm();
1085const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1086ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
1087ma.m_presignature.New(params.GetEncodedElementSize(false));
1088params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size());
1089}
1090};
1091
1092//! .
1093template <class T>
1094class DL_VerifierBase : public DL_SignatureSchemeBase<PK_Verifier, DL_PublicKey<T> >
1095{
1096public:
1097void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const
1098{
1099PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1100const DL_ElgamalLikeSignatureAlgorithm<T> &alg = GetSignatureAlgorithm();
1101const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1102
1103unsigned int rLen = alg.RLen(params);
1104ma.m_semisignature.Assign(signature, rLen);
1105ma.m_s.Decode(signature+rLen, alg.SLen(params));
1106
1107GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size());
1108}
1109
1110bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
1111{
1112GetMaterial().DoQuickSanityCheck();
1113
1114PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1115const DL_ElgamalLikeSignatureAlgorithm<T> &alg = GetSignatureAlgorithm();
1116const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1117const DL_PublicKey<T> &key = GetKeyInterface();
1118
1119SecByteBlock representative(MessageRepresentativeLength());
1120GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1121ma.AccessHash(), GetHashIdentifier(), ma.m_empty,
1122representative, MessageRepresentativeBitLength());
1123ma.m_empty = true;
1124Integer e(representative, representative.size());
1125
1126Integer r(ma.m_semisignature, ma.m_semisignature.size());
1127return alg.Verify(params, key, e, r, ma.m_s);
1128}
1129
1130DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
1131{
1132GetMaterial().DoQuickSanityCheck();
1133
1134PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
1135const DL_ElgamalLikeSignatureAlgorithm<T> &alg = GetSignatureAlgorithm();
1136const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1137const DL_PublicKey<T> &key = GetKeyInterface();
1138
1139SecByteBlock representative(MessageRepresentativeLength());
1140GetMessageEncodingInterface().ComputeMessageRepresentative(
1141NullRNG(),
1142ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
1143ma.AccessHash(), GetHashIdentifier(), ma.m_empty,
1144representative, MessageRepresentativeBitLength());
1145ma.m_empty = true;
1146Integer e(representative, representative.size());
1147
1148ma.m_presignature.New(params.GetEncodedElementSize(false));
1149Integer r(ma.m_semisignature, ma.m_semisignature.size());
1150alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size());
1151
1152return GetMessageEncodingInterface().RecoverMessageFromSemisignature(
1153ma.AccessHash(), GetHashIdentifier(),
1154ma.m_presignature, ma.m_presignature.size(),
1155ma.m_semisignature, ma.m_semisignature.size(),
1156recoveredMessage);
1157}
1158};
1159
1160//! .
1161template <class PK, class KI>
1162class DL_CryptoSystemBase : public PK, public DL_Base<KI>
1163{
1164public:
1165typedef typename DL_Base<KI>::Element Element;
1166
1167unsigned int MaxPlaintextLength(unsigned int cipherTextLength) const
1168{
1169unsigned int minLen = GetAbstractGroupParameters().GetEncodedElementSize(true);
1170return cipherTextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(cipherTextLength - minLen);
1171}
1172
1173unsigned int CiphertextLength(unsigned int plainTextLength) const
1174{
1175unsigned int len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plainTextLength);
1176return len == 0 ? 0 : GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
1177}
1178
1179protected:
1180virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1181virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
1182virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0;
1183};
1184
1185//! .
1186template <class T, class PK = PK_Decryptor>
1187class DL_DecryptorBase : public DL_CryptoSystemBase<PK, DL_PrivateKey<T> >
1188{
1189public:
1190typedef T Element;
1191
1192DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
1193{
1194try
1195{
1196const DL_KeyAgreementAlgorithm<T> &agreeAlg = GetKeyAgreementAlgorithm();
1197const DL_KeyDerivationAlgorithm<T> &derivAlg = GetKeyDerivationAlgorithm();
1198const DL_SymmetricEncryptionAlgorithm &encAlg = GetSymmetricEncryptionAlgorithm();
1199const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1200const DL_PrivateKey<T> &key = GetKeyInterface();
1201
1202Element q = params.DecodeElement(cipherText, true);
1203unsigned int elementSize = params.GetEncodedElementSize(true);
1204cipherText += elementSize;
1205cipherTextLength -= elementSize;
1206
1207Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
1208
1209SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(cipherTextLength)));
1210derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q);
1211
1212return encAlg.SymmetricDecrypt(derivedKey, cipherText, cipherTextLength, plainText);
1213}
1214catch (DL_BadElement &)
1215{
1216return DecodingResult();
1217}
1218}
1219};
1220
1221//! .
1222template <class T, class PK = PK_Encryptor>
1223class DL_EncryptorBase : public DL_CryptoSystemBase<PK, DL_PublicKey<T> >
1224{
1225public:
1226typedef T Element;
1227
1228void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const
1229{
1230const DL_KeyAgreementAlgorithm<T> &agreeAlg = GetKeyAgreementAlgorithm();
1231const DL_KeyDerivationAlgorithm<T> &derivAlg = GetKeyDerivationAlgorithm();
1232const DL_SymmetricEncryptionAlgorithm &encAlg = GetSymmetricEncryptionAlgorithm();
1233const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1234const DL_PublicKey<T> &key = GetKeyInterface();
1235
1236Integer x(rng, Integer::One(), params.GetMaxExponent());
1237Element q = params.ExponentiateBase(x);
1238params.EncodeElement(true, q, cipherText);
1239unsigned int elementSize = params.GetEncodedElementSize(true);
1240cipherText += elementSize;
1241
1242Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
1243
1244SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plainTextLength));
1245derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q);
1246
1247encAlg.SymmetricEncrypt(rng, derivedKey, plainText, plainTextLength, cipherText);
1248}
1249};
1250
1251//! .
1252template <class T1, class T2>
1253struct DL_SchemeOptionsBase
1254{
1255typedef T1 AlgorithmInfo;
1256typedef T2 GroupParameters;
1257typedef typename GroupParameters::Element Element;
1258};
1259
1260//! .
1261template <class T1, class T2>
1262struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase<T1, typename T2::PublicKey::GroupParameters>
1263{
1264typedef T2 Keys;
1265typedef typename Keys::PrivateKey PrivateKey;
1266typedef typename Keys::PublicKey PublicKey;
1267};
1268
1269//! .
1270template <class T1, class T2, class T3, class T4, class T5>
1271struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
1272{
1273typedef T3 SignatureAlgorithm;
1274typedef T4 MessageEncodingMethod;
1275typedef T5 HashFunction;
1276};
1277
1278//! .
1279template <class T1, class T2, class T3, class T4, class T5>
1280struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions<T1, T2>
1281{
1282typedef T3 KeyAgreementAlgorithm;
1283typedef T4 KeyDerivationAlgorithm;
1284typedef T5 SymmetricEncryptionAlgorithm;
1285};
1286
1287//! .
1288template <class BASE, class SCHEME_OPTIONS, class KEY>
1289class DL_ObjectImplBase : public AlgorithmImpl<BASE, typename SCHEME_OPTIONS::AlgorithmInfo>
1290{
1291public:
1292typedef SCHEME_OPTIONS SchemeOptions;
1293typedef KEY KeyClass;
1294typedef typename KeyClass::Element Element;
1295
1296PrivateKey & AccessPrivateKey() {return m_key;}
1297PublicKey & AccessPublicKey() {return m_key;}
1298
1299// KeyAccessor
1300const KeyClass & GetKey() const {return m_key;}
1301KeyClass & AccessKey() {return m_key;}
1302
1303protected:
1304typename BASE::KeyInterface & AccessKeyInterface() {return m_key;}
1305const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;}
1306
1307// for signature scheme
1308HashIdentifier GetHashIdentifier() const
1309{
1310typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::HashIdentifierLookup2<CPP_TYPENAME SchemeOptions::HashFunction> L;
1311return L::Lookup();
1312}
1313unsigned int GetDigestSize() const
1314{
1315typedef CPP_TYPENAME SchemeOptions::HashFunction H;
1316return H::DIGESTSIZE;
1317}
1318
1319private:
1320KeyClass m_key;
1321};
1322
1323//! .
1324template <class BASE, class SCHEME_OPTIONS, class KEY>
1325class DL_ObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>
1326{
1327public:
1328typedef typename KEY::Element Element;
1329
1330protected:
1331const DL_ElgamalLikeSignatureAlgorithm<Element> & GetSignatureAlgorithm() const
1332{static typename SCHEME_OPTIONS::SignatureAlgorithm a; return a;}
1333const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const
1334{static typename SCHEME_OPTIONS::KeyAgreementAlgorithm a; return a;}
1335const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const
1336{static typename SCHEME_OPTIONS::KeyDerivationAlgorithm a; return a;}
1337const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const
1338{static typename SCHEME_OPTIONS::SymmetricEncryptionAlgorithm a; return a;}
1339HashIdentifier GetHashIdentifier() const
1340{return HashIdentifier();}
1341const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const
1342{static typename SCHEME_OPTIONS::MessageEncodingMethod a; return a;}
1343};
1344
1345//! .
1346template <class BASE, class SCHEME_OPTIONS>
1347class DL_PublicObjectImpl : public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey>, public PublicKeyCopier<SCHEME_OPTIONS>
1348{
1349public:
1350void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const
1351{key = GetKey();}
1352};
1353
1354//! .
1355template <class BASE, class SCHEME_OPTIONS>
1356class DL_PrivateObjectImpl : public DL_ObjectImpl<BASE, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey>, public PrivateKeyCopier<SCHEME_OPTIONS>
1357{
1358public:
1359void CopyKeyInto(typename SCHEME_OPTIONS::PublicKey &key) const
1360{GetKey().MakePublicKey(key);}
1361void CopyKeyInto(typename SCHEME_OPTIONS::PrivateKey &key) const
1362{key = GetKey();}
1363};
1364
1365//! .
1366template <class SCHEME_OPTIONS>
1367class DL_SignerImpl : public DL_PrivateObjectImpl<DL_SignerBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS>
1368{
1369PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng = NullRNG()) const
1370{
1371std::auto_ptr<PK_MessageAccumulatorBase> p(new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>);
1372RestartMessageAccumulator(rng, *p);
1373return p.release();
1374}
1375};
1376
1377//! .
1378template <class SCHEME_OPTIONS>
1379class DL_VerifierImpl : public DL_PublicObjectImpl<DL_VerifierBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS>
1380{
1381PK_MessageAccumulator * NewVerificationAccumulator() const
1382{
1383return new PK_MessageAccumulatorImpl<CPP_TYPENAME SCHEME_OPTIONS::HashFunction>;
1384}
1385};
1386
1387//! .
1388template <class SCHEME_OPTIONS>
1389class DL_EncryptorImpl : public DL_PublicObjectImpl<DL_EncryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS>
1390{
1391};
1392
1393//! .
1394template <class SCHEME_OPTIONS>
1395class DL_DecryptorImpl : public DL_PrivateObjectImpl<DL_DecryptorBase<typename SCHEME_OPTIONS::Element>, SCHEME_OPTIONS>
1396{
1397};
1398
1399// ********************************************************
1400
1401//! .
1402template <class T>
1403class DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain
1404{
1405public:
1406typedef T Element;
1407
1408CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
1409unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
1410unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
1411unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
1412
1413void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
1414{
1415Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
1416x.Encode(privateKey, PrivateKeyLength());
1417}
1418
1419void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
1420{
1421const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1422Integer x(privateKey, PrivateKeyLength());
1423Element y = params.ExponentiateBase(x);
1424params.EncodeElement(true, y, publicKey);
1425}
1426
1427bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
1428{
1429try
1430{
1431const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
1432Integer x(privateKey, PrivateKeyLength());
1433Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey);
1434
1435Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey(
1436GetAbstractGroupParameters(), w, validateOtherPublicKey, x);
1437params.EncodeElement(false, z, agreedValue);
1438}
1439catch (DL_BadElement &)
1440{
1441return false;
1442}
1443return true;
1444}
1445
1446const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();}
1447
1448protected:
1449virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
1450virtual DL_GroupParameters<Element> & AccessAbstractGroupParameters() =0;
1451const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase<Element> *>(this)->AccessAbstractGroupParameters();}
1452};
1453
1454enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION};
1455typedef EnumToType<CofactorMultiplicationOption, NO_COFACTOR_MULTIPLICTION> NoCofactorMultiplication;
1456typedef EnumToType<CofactorMultiplicationOption, COMPATIBLE_COFACTOR_MULTIPLICTION> CompatibleCofactorMultiplication;
1457typedef EnumToType<CofactorMultiplicationOption, INCOMPATIBLE_COFACTOR_MULTIPLICTION> IncompatibleCofactorMultiplication;
1458
1459//! DH key agreement algorithm
1460template <class ELEMENT, class COFACTOR_OPTION>
1461class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm<ELEMENT>
1462{
1463public:
1464typedef ELEMENT Element;
1465
1466static const char *StaticAlgorithmName()
1467{return COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION ? "DH" : "DHC";}
1468
1469Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters<Element> &params, const DL_FixedBasePrecomputation<Element> &publicPrecomputation, const Integer &privateExponent) const
1470{
1471return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(),
1472COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent);
1473}
1474
1475Element AgreeWithStaticPrivateKey(const DL_GroupParameters<Element> &params, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const
1476{
1477if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
1478{
1479const Integer &k = params.GetCofactor();
1480return params.ExponentiateElement(publicElement,
1481ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k);
1482}
1483else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION)
1484return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor());
1485else
1486{
1487assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION);
1488
1489if (!validateOtherPublicKey)
1490return params.ExponentiateElement(publicElement, privateExponent);
1491
1492if (params.FastSubgroupCheckAvailable())
1493{
1494if (!params.ValidateElement(2, publicElement, NULL))
1495throw DL_BadElement();
1496return params.ExponentiateElement(publicElement, privateExponent);
1497}
1498else
1499{
1500const Integer e[2] = {params.GetSubgroupOrder(), privateExponent};
1501Element r[2];
1502params.SimultaneousExponentiate(r, publicElement, e, 2);
1503if (!params.IsIdentity(r[0]))
1504throw DL_BadElement();
1505return r[1];
1506}
1507}
1508}
1509};
1510
1511// ********************************************************
1512
1513//! A template implementing constructors for public key algorithm classes
1514template <class BASE>
1515class PK_FinalTemplate : public BASE
1516{
1517public:
1518PK_FinalTemplate() {}
1519
1520PK_FinalTemplate(const Integer &v1)
1521{AccessKey().Initialize(v1);}
1522
1523PK_FinalTemplate(const typename BASE::KeyClass &key) {AccessKey().operator=(key);}
1524
1525template <class T>
1526PK_FinalTemplate(const PublicKeyCopier<T> &key)
1527{key.CopyKeyInto(AccessKey());}
1528
1529template <class T>
1530PK_FinalTemplate(const PrivateKeyCopier<T> &key)
1531{key.CopyKeyInto(AccessKey());}
1532
1533PK_FinalTemplate(BufferedTransformation &bt) {AccessKey().BERDecode(bt);}
1534
1535#if (defined(_MSC_VER) && _MSC_VER < 1300)
1536
1537template <class T1, class T2>
1538PK_FinalTemplate(T1 &v1, T2 &v2)
1539{AccessKey().Initialize(v1, v2);}
1540
1541template <class T1, class T2, class T3>
1542PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3)
1543{AccessKey().Initialize(v1, v2, v3);}
1544
1545template <class T1, class T2, class T3, class T4>
1546PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4)
1547{AccessKey().Initialize(v1, v2, v3, v4);}
1548
1549template <class T1, class T2, class T3, class T4, class T5>
1550PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5)
1551{AccessKey().Initialize(v1, v2, v3, v4, v5);}
1552
1553template <class T1, class T2, class T3, class T4, class T5, class T6>
1554PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6)
1555{AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1556
1557template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1558PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7)
1559{AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1560
1561template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1562PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8)
1563{AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1564
1565#else
1566
1567template <class T1, class T2>
1568PK_FinalTemplate(const T1 &v1, const T2 &v2)
1569{AccessKey().Initialize(v1, v2);}
1570
1571template <class T1, class T2, class T3>
1572PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3)
1573{AccessKey().Initialize(v1, v2, v3);}
1574
1575template <class T1, class T2, class T3, class T4>
1576PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
1577{AccessKey().Initialize(v1, v2, v3, v4);}
1578
1579template <class T1, class T2, class T3, class T4, class T5>
1580PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
1581{AccessKey().Initialize(v1, v2, v3, v4, v5);}
1582
1583template <class T1, class T2, class T3, class T4, class T5, class T6>
1584PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
1585{AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1586
1587template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1588PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
1589{AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1590
1591template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1592PK_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)
1593{AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1594
1595template <class T1, class T2>
1596PK_FinalTemplate(T1 &v1, const T2 &v2)
1597{AccessKey().Initialize(v1, v2);}
1598
1599template <class T1, class T2, class T3>
1600PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3)
1601{AccessKey().Initialize(v1, v2, v3);}
1602
1603template <class T1, class T2, class T3, class T4>
1604PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4)
1605{AccessKey().Initialize(v1, v2, v3, v4);}
1606
1607template <class T1, class T2, class T3, class T4, class T5>
1608PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5)
1609{AccessKey().Initialize(v1, v2, v3, v4, v5);}
1610
1611template <class T1, class T2, class T3, class T4, class T5, class T6>
1612PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6)
1613{AccessKey().Initialize(v1, v2, v3, v4, v5, v6);}
1614
1615template <class T1, class T2, class T3, class T4, class T5, class T6, class T7>
1616PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7)
1617{AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);}
1618
1619template <class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
1620PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8)
1621{AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);}
1622
1623#endif
1624};
1625
1626//! Base class for public key encryption standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
1627struct EncryptionStandard {};
1628
1629//! Base class for public key signature standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms.
1630struct SignatureStandard {};
1631
1632template <class STANDARD, class KEYS, class ALG_INFO>
1633class TF_ES;
1634
1635//! Trapdoor Function Based Encryption Scheme
1636template <class STANDARD, class KEYS, class ALG_INFO = TF_ES<STANDARD, KEYS, int> >
1637class TF_ES : public KEYS
1638{
1639typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod;
1640
1641public:
1642//! see EncryptionStandard for a list of standards
1643typedef STANDARD Standard;
1644typedef TF_CryptoSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod> SchemeOptions;
1645
1646static std::string StaticAlgorithmName() {return KEYS::StaticAlgorithmName() + "/" + MessageEncodingMethod::StaticAlgorithmName();}
1647
1648//! implements PK_Decryptor interface
1649typedef PK_FinalTemplate<TF_DecryptorImpl<SchemeOptions> > Decryptor;
1650//! implements PK_Encryptor interface
1651typedef PK_FinalTemplate<TF_EncryptorImpl<SchemeOptions> > Encryptor;
1652};
1653
1654template <class STANDARD, class H, class KEYS, class ALG_INFO>// VC60 workaround: doesn't work if KEYS is first parameter
1655class TF_SS;
1656
1657//! Trapdoor Function Based Signature Scheme
1658template <class STANDARD, class H, class KEYS, class ALG_INFO = TF_SS<STANDARD, H, KEYS, int> >// VC60 workaround: doesn't work if KEYS is first parameter
1659class TF_SS : public KEYS
1660{
1661public:
1662//! see SignatureStandard for a list of standards
1663typedef STANDARD Standard;
1664typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod;
1665typedef TF_SignatureSchemeOptions<ALG_INFO, KEYS, MessageEncodingMethod, H> SchemeOptions;
1666
1667static std::string StaticAlgorithmName() {return KEYS::StaticAlgorithmName() + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
1668
1669//! implements PK_Signer interface
1670typedef PK_FinalTemplate<TF_SignerImpl<SchemeOptions> > Signer;
1671//! implements PK_Verifier interface
1672typedef PK_FinalTemplate<TF_VerifierImpl<SchemeOptions> > Verifier;
1673};
1674
1675template <class KEYS, class SA, class MEM, class H, class ALG_INFO>
1676class DL_SS;
1677
1678//! Discrete Log Based Signature Scheme
1679template <class KEYS, class SA, class MEM, class H, class ALG_INFO = DL_SS<KEYS, SA, MEM, H, int> >
1680class DL_SS : public KEYS
1681{
1682typedef DL_SignatureSchemeOptions<ALG_INFO, KEYS, SA, MEM, H> SchemeOptions;
1683
1684public:
1685static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";}
1686
1687//! implements PK_Signer interface
1688typedef PK_FinalTemplate<DL_SignerImpl<SchemeOptions> > Signer;
1689//! implements PK_Verifier interface
1690typedef PK_FinalTemplate<DL_VerifierImpl<SchemeOptions> > Verifier;
1691};
1692
1693//! Discrete Log Based Encryption Scheme
1694template <class KEYS, class AA, class DA, class EA, class ALG_INFO>
1695class DL_ES : public KEYS
1696{
1697typedef DL_CryptoSchemeOptions<ALG_INFO, KEYS, AA, DA, EA> SchemeOptions;
1698
1699public:
1700//! implements PK_Decryptor interface
1701typedef PK_FinalTemplate<DL_DecryptorImpl<SchemeOptions> > Decryptor;
1702//! implements PK_Encryptor interface
1703typedef PK_FinalTemplate<DL_EncryptorImpl<SchemeOptions> > Encryptor;
1704};
1705
1706NAMESPACE_END
1707
1708#endif

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status