1#ifndef CRYPTOPP_LUC_H
2#define CRYPTOPP_LUC_H
3
4/** \file
5*/
6
7#include "pkcspad.h"
8#include "oaep.h"
9#include "integer.h"
10#include "dh.h"
11
12#include <limits.h>
13
14NAMESPACE_BEGIN(CryptoPP)
15
16//! The LUC function.
17/*! This class is here for historical and pedagogical interest. It has no
18	practical advantages over other trapdoor functions and probably shouldn't
19	be used in production software. The discrete log based LUC schemes
20	defined later in this .h file may be of more practical interest.
21*/
22class LUCFunction : public TrapdoorFunction, public PublicKey
23{
24	typedef LUCFunction ThisClass;
25
26public:
27	void Initialize(const Integer &n, const Integer &e)
28		{m_n = n; m_e = e;}
29
30	void BERDecode(BufferedTransformation &bt);
31	void DEREncode(BufferedTransformation &bt) const;
32
33	Integer ApplyFunction(const Integer &x) const;
34	Integer PreimageBound() const {return m_n;}
35	Integer ImageBound() const {return m_n;}
36
37	bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
38	bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
39	void AssignFrom(const NameValuePairs &source);
40
41	// non-derived interface
42	const Integer & GetModulus() const {return m_n;}
43	const Integer & GetPublicExponent() const {return m_e;}
44
45	void SetModulus(const Integer &n) {m_n = n;}
46	void SetPublicExponent(const Integer &e) {m_e = e;}
47
48protected:
49	Integer m_n, m_e;
50};
51
52//! _
53class InvertibleLUCFunction : public LUCFunction, public TrapdoorFunctionInverse, public PrivateKey
54{
55	typedef InvertibleLUCFunction ThisClass;
56
57public:
58	void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &eStart=17);
59	void Initialize(const Integer &n, const Integer &e, const Integer &p, const Integer &q, const Integer &u)
60		{m_n = n; m_e = e; m_p = p; m_q = q; m_u = u;}
61
62	void BERDecode(BufferedTransformation &bt);
63	void DEREncode(BufferedTransformation &bt) const;
64
65	Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const;
66
67	bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
68	bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
69	void AssignFrom(const NameValuePairs &source);
70	/*! parameters: (ModulusSize, PublicExponent (default 17)) */
71	void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
72
73	// non-derived interface
74	const Integer& GetPrime1() const {return m_p;}
75	const Integer& GetPrime2() const {return m_q;}
76	const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;}
77
78	void SetPrime1(const Integer &p) {m_p = p;}
79	void SetPrime2(const Integer &q) {m_q = q;}
80	void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;}
81
82protected:
83	Integer m_p, m_q, m_u;
84};
85
86struct LUC
87{
88	static std::string StaticAlgorithmName() {return "LUC";}
89	typedef LUCFunction PublicKey;
90	typedef InvertibleLUCFunction PrivateKey;
91};
92
93//! LUC cryptosystem
94template <class STANDARD>
95struct LUCES : public TF_ES<STANDARD, LUC>
96{
97};
98
99//! LUC signature scheme with appendix
100template <class STANDARD, class H>
101struct LUCSS : public TF_SS<STANDARD, H, LUC>
102{
103};
104
105// analagous to the RSA schemes defined in PKCS #1 v2.0
106typedef LUCES<OAEP<SHA> >::Decryptor LUCES_OAEP_SHA_Decryptor;
107typedef LUCES<OAEP<SHA> >::Encryptor LUCES_OAEP_SHA_Encryptor;
108
109typedef LUCSS<PKCS1v15, SHA>::Signer LUCSSA_PKCS1v15_SHA_Signer;
110typedef LUCSS<PKCS1v15, SHA>::Verifier LUCSSA_PKCS1v15_SHA_Verifier;
111
112// ********************************************************
113
114// no actual precomputation
115class DL_GroupPrecomputation_LUC : public DL_GroupPrecomputation<Integer>
116{
117public:
118	const AbstractGroup<Element> & GetGroup() const {assert(false); throw 0;}
119	Element BERDecodeElement(BufferedTransformation &bt) const {return Integer(bt);}
120	void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {v.DEREncode(bt);}
121
122	// non-inherited
123	void SetModulus(const Integer &v) {m_p = v;}
124	const Integer & GetModulus() const {return m_p;}
125
126private:
127	Integer m_p;
128};
129
130//! _
131class DL_BasePrecomputation_LUC : public DL_FixedBasePrecomputation<Integer>
132{
133public:
134	// DL_FixedBasePrecomputation
135	bool IsInitialized() const {return m_g.NotZero();}
136	void SetBase(const DL_GroupPrecomputation<Element> &group, const Integer &base) {m_g = base;}
137	const Integer & GetBase(const DL_GroupPrecomputation<Element> &group) const {return m_g;}
138	void Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage) {}
139	void Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) {}
140	void Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &storedPrecomputation) const {}
141	Integer Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const;
142	Integer CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent, const DL_FixedBasePrecomputation<Integer> &pc2, const Integer &exponent2) const
143		{throw NotImplemented("DL_BasePrecomputation_LUC: CascadeExponentiate not implemented");}	// shouldn't be called
144
145private:
146	Integer m_g;
147};
148
149//! _
150class DL_GroupParameters_LUC : public DL_GroupParameters_IntegerBasedImpl<DL_GroupPrecomputation_LUC, DL_BasePrecomputation_LUC>
151{
152public:
153	// DL_GroupParameters
154	bool IsIdentity(const Integer &element) const {return element == Integer::Two();}
155	void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
156	Element MultiplyElements(const Element &a, const Element &b) const
157		{throw NotImplemented("LUC_GroupParameters: MultiplyElements can not be implemented");}
158	Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
159		{throw NotImplemented("LUC_GroupParameters: MultiplyElements can not be implemented");}
160
161	// NameValuePairs interface
162	bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
163	{
164		return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();
165	}
166
167private:
168	int GetFieldType() const {return 2;}
169};
170
171//! _
172class DL_GroupParameters_LUC_DefaultSafePrime : public DL_GroupParameters_LUC
173{
174public:
175	typedef NoCofactorMultiplication DefaultCofactorOption;
176
177protected:
178	unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
179};
180
181//! _
182class DL_Algorithm_LUC_HMP : public DL_ElgamalLikeSignatureAlgorithm<Integer>
183{
184public:
185	static const char * StaticAlgorithmName() {return "LUC-HMP";}
186
187	void Sign(const DL_GroupParameters<Integer> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const;
188	bool Verify(const DL_GroupParameters<Integer> &params, const DL_PublicKey<Integer> &publicKey, const Integer &e, const Integer &r, const Integer &s) const;
189
190	size_t RLen(const DL_GroupParameters<Integer> &params) const
191		{return params.GetGroupOrder().ByteCount();}
192};
193
194//! _
195struct DL_SignatureKeys_LUC
196{
197	typedef DL_GroupParameters_LUC GroupParameters;
198	typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
199	typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
200};
201
202//! LUC-HMP, based on "Digital signature schemes based on Lucas functions" by Patrick Horster, Markus Michels, Holger Petersen
203template <class H>
204struct LUC_HMP : public DL_SS<DL_SignatureKeys_LUC, DL_Algorithm_LUC_HMP, DL_SignatureMessageEncodingMethod_DSA, H>
205{
206};
207
208//! _
209struct DL_CryptoKeys_LUC
210{
211	typedef DL_GroupParameters_LUC_DefaultSafePrime GroupParameters;
212	typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
213	typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
214};
215
216//! LUC-IES
217template <class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true>
218struct LUC_IES
219	: public DL_ES<
220		DL_CryptoKeys_LUC,
221		DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
222		DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >,
223		DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
224		LUC_IES<> >
225{
226	static std::string StaticAlgorithmName() {return "LUC-IES";}	// non-standard name
227};
228
229// ********************************************************
230
231//! LUC-DH
232typedef DH_Domain<DL_GroupParameters_LUC_DefaultSafePrime> LUC_DH;
233
234NAMESPACE_END
235
236#endif
237