1 // esign.h - written and placed in the public domain by Wei Dai
2 
3 //! \file esign.h
4 //! \brief Classes providing ESIGN signature schemes as defined in IEEE P1363a
5 //! \since Crypto++ 5.0
6 
7 #ifndef CRYPTOPP_ESIGN_H
8 #define CRYPTOPP_ESIGN_H
9 
10 #include "cryptlib.h"
11 #include "pubkey.h"
12 #include "integer.h"
13 #include "asn.h"
14 #include "misc.h"
15 
NAMESPACE_BEGIN(CryptoPP)16 NAMESPACE_BEGIN(CryptoPP)
17 
18 //! \class ESIGNFunction
19 //! \brief ESIGN trapdoor function using the public key
20 //! \since Crypto++ 5.0
21 class ESIGNFunction : public TrapdoorFunction, public ASN1CryptoMaterial<PublicKey>
22 {
23 	typedef ESIGNFunction ThisClass;
24 
25 public:
26 
27 	//! \brief Initialize a ESIGN public key with {n,e}
28 	//! \param n the modulus
29 	//! \param e the public exponent
30 	void Initialize(const Integer &n, const Integer &e)
31 		{m_n = n; m_e = e;}
32 
33 	// PublicKey
34 	void BERDecode(BufferedTransformation &bt);
35 	void DEREncode(BufferedTransformation &bt) const;
36 
37 	// CryptoMaterial
38 	bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
39 	bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
40 	void AssignFrom(const NameValuePairs &source);
41 
42 	// TrapdoorFunction
43 	Integer ApplyFunction(const Integer &x) const;
44 	Integer PreimageBound() const {return m_n;}
45 	Integer ImageBound() const {return Integer::Power2(GetK());}
46 
47 	// non-derived
48 	const Integer & GetModulus() const {return m_n;}
49 	const Integer & GetPublicExponent() const {return m_e;}
50 
51 	void SetModulus(const Integer &n) {m_n = n;}
52 	void SetPublicExponent(const Integer &e) {m_e = e;}
53 
54 protected:
55 	// Covertiy finding on overflow. The library allows small values for research purposes.
56 	unsigned int GetK() const {return SaturatingSubtract(m_n.BitCount()/3, 1U);}
57 
58 	Integer m_n, m_e;
59 };
60 
61 //! \class InvertibleESIGNFunction
62 //! \brief ESIGN trapdoor function using the private key
63 //! \since Crypto++ 5.0
64 class InvertibleESIGNFunction : public ESIGNFunction, public RandomizedTrapdoorFunctionInverse, public PrivateKey
65 {
66 	typedef InvertibleESIGNFunction ThisClass;
67 
68 public:
69 
70 	//! \brief Initialize a ESIGN private key with {n,e,p,q}
71 	//! \param n modulus
72 	//! \param e public exponent
73 	//! \param p first prime factor
74 	//! \param q second prime factor
75 	//! \details This Initialize() function overload initializes a private key from existing parameters.
Initialize(const Integer & n,const Integer & e,const Integer & p,const Integer & q)76 	void Initialize(const Integer &n, const Integer &e, const Integer &p, const Integer &q)
77 		{m_n = n; m_e = e; m_p = p; m_q = q;}
78 
79 	//! \brief Create a ESIGN private key
80 	//! \param rng a RandomNumberGenerator derived class
81 	//! \param modulusBits the size of the modulud, in bits
82 	//! \details This function overload of Initialize() creates a new private key because it
83 	//!   takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
84 	//!   then use one of the other Initialize() overloads.
Initialize(RandomNumberGenerator & rng,unsigned int modulusBits)85 	void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
86 		{GenerateRandomWithKeySize(rng, modulusBits);}
87 
88 	void BERDecode(BufferedTransformation &bt);
89 	void DEREncode(BufferedTransformation &bt) const;
90 
91 	Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const;
92 
93 	// GeneratibleCryptoMaterial
94 	bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
95 	bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
96 	void AssignFrom(const NameValuePairs &source);
97 	/*! parameters: (ModulusSize) */
98 	void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
99 
GetPrime1()100 	const Integer& GetPrime1() const {return m_p;}
GetPrime2()101 	const Integer& GetPrime2() const {return m_q;}
102 
SetPrime1(const Integer & p)103 	void SetPrime1(const Integer &p) {m_p = p;}
SetPrime2(const Integer & q)104 	void SetPrime2(const Integer &q) {m_q = q;}
105 
106 protected:
107 	Integer m_p, m_q;
108 };
109 
110 //! \class EMSA5Pad
111 //! \brief EMSA5 padding method
112 //! \tparam T Mask Generation Function
113 //! \since Crypto++ 5.0
114 template <class T>
115 class EMSA5Pad : public PK_DeterministicSignatureMessageEncodingMethod
116 {
117 public:
StaticAlgorithmName()118 	CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "EMSA5";}
119 
ComputeMessageRepresentative(RandomNumberGenerator & rng,const byte * recoverableMessage,size_t recoverableMessageLength,HashTransformation & hash,HashIdentifier hashIdentifier,bool messageEmpty,byte * representative,size_t representativeBitLength)120 	void ComputeMessageRepresentative(RandomNumberGenerator &rng,
121 		const byte *recoverableMessage, size_t recoverableMessageLength,
122 		HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
123 		byte *representative, size_t representativeBitLength) const
124 	{
125 		CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
126 		CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
127 		SecByteBlock digest(hash.DigestSize());
128 		hash.Final(digest);
129 		size_t representativeByteLength = BitsToBytes(representativeBitLength);
130 		T mgf;
131 		mgf.GenerateAndMask(hash, representative, representativeByteLength, digest, digest.size(), false);
132 		if (representativeBitLength % 8 != 0)
133 			representative[0] = (byte)Crop(representative[0], representativeBitLength % 8);
134 	}
135 };
136 
137 //! \class P1363_EMSA5
138 //! \brief EMSA5 padding method, for use with ESIGN
139 //! \since Crypto++ 5.0
140 struct P1363_EMSA5 : public SignatureStandard
141 {
142 	typedef EMSA5Pad<P1363_MGF1> SignatureMessageEncodingMethod;
143 };
144 
145 struct ESIGN_Keys
146 {
StaticAlgorithmNameESIGN_Keys147 	CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ESIGN";}
148 	typedef ESIGNFunction PublicKey;
149 	typedef InvertibleESIGNFunction PrivateKey;
150 };
151 
152 //! \class ESIGN
153 //! \brief ESIGN signature scheme, IEEE P1363a
154 //! \tparam H HashTransformation derived class
155 //! \tparam STANDARD Signature encoding method
156 //! \since Crypto++ 5.0
157 template <class H, class STANDARD = P1363_EMSA5>
158 struct ESIGN : public TF_SS<ESIGN_Keys, STANDARD, H>
159 {
160 };
161 
162 NAMESPACE_END
163 
164 #endif
165