summaryrefslogtreecommitdiff
path: root/rw.h
blob: 2dbfce589a37bd3885979d080e195c82ea4ea878 (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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#ifndef CRYPTOPP_RW_H
#define CRYPTOPP_RW_H

/** \file
	This file contains classes that implement the
	Rabin-Williams signature schemes as defined in IEEE P1363.
*/

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

NAMESPACE_BEGIN(CryptoPP)

const word IFSSR_R = 6;
const word IFSSA_R = 12;

//! .
template <word r>
class RWFunction : virtual public TrapdoorFunction, public PublicKey
{
	typedef RWFunction ThisClass;

public:
	void Initialize(const Integer &n)
		{m_n = n;}

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

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

	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;
};

//! .
template <word r>
class InvertibleRWFunction : public RWFunction<r>, public TrapdoorFunctionInverse, public PrivateKey
{
	typedef InvertibleRWFunction ThisClass;

public:
	void Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u)
		{m_n = n; m_p = p; m_q = q; m_u = u;}
	// generate a random private key
	void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
		{GenerateRandomWithKeySize(rng, modulusBits);}

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

	Integer CalculateInverse(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;}

protected:
	Integer m_p, m_q, m_u;
};

//! .
class EMSA2Pad : public PK_PaddingAlgorithm
{
public:
	static const char *StaticAlgorithmName() {return "EMSA2";}
	
	unsigned int MaxUnpaddedLength(unsigned int paddedLength) const {return (paddedLength+1)/8-2;}

	void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength) const;
	DecodingResult Unpad(const byte *padded, unsigned int paddedLength, byte *raw) const;
};

//! .
template <class H>
class EMSA2DecoratedHashModule : public HashTransformationWithDefaultTruncation
{
public:
	EMSA2DecoratedHashModule() : empty(true) {}
	void Update(const byte *input, unsigned int length)
		{h.Update(input, length); empty = empty && length==0;}
	unsigned int DigestSize() const;
	void Final(byte *digest);
	void Restart() {h.Restart(); empty=true;}

private:
	H h;
	bool empty;
};

template <class H> struct EMSA2DigestDecoration
{
	static const byte decoration;
};

//! EMSA2, for use with RW
/*! The following hash functions are supported: SHA, RIPEMD160. */
struct P1363_EMSA2 : public SignatureStandard
{
	template <class H> struct SignaturePaddingAlgorithm {typedef EMSA2Pad type;};
	template <class H> struct DecoratedHashingAlgorithm {typedef EMSA2DecoratedHashModule<H> type;};
};

template<> struct CryptoStandardTraits<P1363_EMSA2> : public P1363_EMSA2 {};

// EMSA2DecoratedHashModule can be instantiated with the following two classes.
class SHA;
class RIPEMD160;

template <class H>
void EMSA2DecoratedHashModule<H>::Final(byte *digest)
{
	digest[0] = empty ? 0x4b : 0x6b;
	h.Final(digest+1);
	digest[DigestSize()-1] = EMSA2DigestDecoration<H>::decoration;
	empty=true;
}

template <class H>
unsigned int EMSA2DecoratedHashModule<H>::DigestSize() const
{
	return h.DigestSize() + 2;
}

//! .
template <word r>
struct RW
{
	static std::string StaticAlgorithmName() {return "RW";}
	typedef RWFunction<r> PublicKey;
	typedef InvertibleRWFunction<r> PrivateKey;
};

//! RW
template <class H, class STANDARD = P1363_EMSA2>
struct RWSSA : public TF_SSA<STANDARD, H, RW<IFSSA_R> >
{
};

NAMESPACE_END

#endif