summaryrefslogtreecommitdiff
path: root/rw.h
blob: 48aa289152275ad95417dc72d9eb232d40c6ba79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// rw.h - originally written and placed in the public domain by Wei Dai

/// \file rw.h
/// \brief Classes for Rabin-Williams signature scheme
/// \details The implementation provides Rabin-Williams signature schemes as defined in
///   IEEE P1363. It uses Bernstein's tweaked square roots in place of square roots to
///   speedup calculations.
/// \sa <A HREF="http://cr.yp.to/sigs/rwsota-20080131.pdf">RSA signatures and Rabin–Williams
///   signatures: the state of the art (20080131)</A>, Section 6, <em>The tweaks e and f</em>.
/// \since Crypto++ 3.0

#ifndef CRYPTOPP_RW_H
#define CRYPTOPP_RW_H

#include "cryptlib.h"
#include "pubkey.h"
#include "integer.h"

NAMESPACE_BEGIN(CryptoPP)

/// \brief Rabin-Williams trapdoor function using the public key
/// \since Crypto++ 3.0, Tweaked roots using <em>e</em> and <em>f</em> since Crypto++ 5.6.4
class CRYPTOPP_DLL RWFunction : public TrapdoorFunction, public PublicKey
{
	typedef RWFunction ThisClass;

public:

	/// \brief Initialize a Rabin-Williams public key
	/// \param n the modulus
	void Initialize(const Integer &n)
		{m_n = n;}

	void BERDecode(BufferedTransformation &bt);
	void DEREncode(BufferedTransformation &bt) const;

	void Save(BufferedTransformation &bt) const
		{DEREncode(bt);}
	void Load(BufferedTransformation &bt)
		{BERDecode(bt);}

	Integer ApplyFunction(const Integer &x) const;
	Integer PreimageBound() const {return ++(m_n>>1);}
	Integer ImageBound() const {return m_n;}

	bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
	bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
	void AssignFrom(const NameValuePairs &source);

	const Integer& GetModulus() const {return m_n;}
	void SetModulus(const Integer &n) {m_n = n;}

protected:
	Integer m_n;
};

/// \brief Rabin-Williams trapdoor function using the private key
/// \since Crypto++ 3.0, Tweaked roots using <em>e</em> and <em>f</em> since Crypto++ 5.6.4
class CRYPTOPP_DLL InvertibleRWFunction : public RWFunction, public TrapdoorFunctionInverse, public PrivateKey
{
	typedef InvertibleRWFunction ThisClass;

public:
	/// \brief Construct an InvertibleRWFunction
	InvertibleRWFunction() : m_precompute(false) {}

	/// \brief Initialize a Rabin-Williams private key
	/// \param n modulus
	/// \param p first prime factor
	/// \param q second prime factor
	/// \param u q<sup>-1</sup> mod p
	/// \details This Initialize() function overload initializes a private key from existing parameters.
	void Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u);

	/// \brief Create a Rabin-Williams private key
	/// \param rng a RandomNumberGenerator derived class
	/// \param modulusBits the size of the modulus, in bits
	/// \details This function overload of Initialize() creates a new private key because it
	///   takes a RandomNumberGenerator() as a parameter. If you have an existing keypair,
	///   then use one of the other Initialize() overloads.
	void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
		{GenerateRandomWithKeySize(rng, modulusBits);}

	void BERDecode(BufferedTransformation &bt);
	void DEREncode(BufferedTransformation &bt) const;

	void Save(BufferedTransformation &bt) const
		{DEREncode(bt);}
	void Load(BufferedTransformation &bt)
		{BERDecode(bt);}

	Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const;

	// GeneratibleCryptoMaterial
	bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
	bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
	void AssignFrom(const NameValuePairs &source);
	/*! parameters: (ModulusSize) */
	void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);

	const Integer& GetPrime1() const {return m_p;}
	const Integer& GetPrime2() const {return m_q;}
	const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;}

	void SetPrime1(const Integer &p) {m_p = p;}
	void SetPrime2(const Integer &q) {m_q = q;}
	void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;}

	virtual bool SupportsPrecomputation() const {return true;}
	virtual void Precompute(unsigned int unused = 0) {CRYPTOPP_UNUSED(unused); PrecomputeTweakedRoots();}
	virtual void Precompute(unsigned int unused = 0) const {CRYPTOPP_UNUSED(unused); PrecomputeTweakedRoots();}

	virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation);
	virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const;

protected:
	void PrecomputeTweakedRoots() const;

protected:
	Integer m_p, m_q, m_u;

	mutable Integer m_pre_2_9p, m_pre_2_3q, m_pre_q_p;
	mutable bool m_precompute;
};

/// \brief Rabin-Williams keys
/// \since Crypto++ 3.0
struct RW
{
	CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "RW";}
	typedef RWFunction PublicKey;
	typedef InvertibleRWFunction PrivateKey;
};

/// \brief Rabin-Williams signature scheme
/// \tparam STANDARD signature standard
/// \tparam H hash transformation
/// \since Crypto++ 3.0
template <class STANDARD, class H>
struct RWSS : public TF_SS<RW, STANDARD, H>
{
};

NAMESPACE_END

#endif