A
download dsa.cpp
Language: C++
LOC: 306
Project Info
NNIM
Server: SourceForge
Type: cvs
...rge\n\nnim\nnim\GNU\crypto\
   3desval.dat
   3way.cpp
   3way.h
   3wayval.dat
   adler32.cpp
   adler32.h
   aes.h
   algebra.cpp
   algebra.h
   arc4.cpp
   arc4.h
   asn.cpp
   asn.h
   base64.cpp
   base64.h
   bench.cpp
   bench.h
   bfinit.cpp
   blowfish.cpp
   blowfish.h
   blum1024.dat
   blum2048.dat
   blum512.dat
   blumgold.cpp
   blumgold.h
   blumshub.cpp
   blumshub.h
   cast.cpp
   cast.h
   cast128v.dat
   cast256v.dat
   casts.cpp
   cbc.cpp
   cbc.h
   cbcmac.h
   channels.cpp
   channels.h
   config.h
   crc.cpp
   crc.h
   cryptest.dsp
   cryptest.dsw
   cryptest.ncb
   cryptlib.cpp
   cryptlib.dsp
   cryptlib.dsw
   cryptlib.h
   cryptlib.sln
   cryptlib.vcproj
   default.cpp
   default.h
   des.cpp
   des.h
   descert.dat
   dessp.cpp
   dh.cpp
   dh.h
   dh1024.dat
   dh2.cpp
   dh2.h
   dh2048.dat
   dh512.dat
   diamond.cpp
   diamond.dat
   diamond.h
   diamondt.cpp
   dmac.h
   dsa.cpp
   dsa.h
   dsa1024.dat
   dsa1024b.dat
   dsa512.dat
   ec2n.cpp
   ec2n.h
   eccrypto.cpp
   eccrypto.h
   ecp.cpp
   ecp.h
   elgamal.cpp
   elgamal.h
   elgc1024.dat
   elgc2048.dat
   elgc512.dat
   eprecomp.cpp
   eprecomp.h
   files.cpp
   files.h
   filters.cpp
   filters.h
   gf2_32.cpp
   gf2_32.h
   gf256.cpp
   gf256.h
   gf2n.cpp
   gf2n.h
   gost.cpp
   gost.h
   gostval.dat
   gzip.cpp
   gzip.h
   haval.cpp
   haval.h
   havalcer.dat
   hex.cpp
   hex.h
   hmac.h
   hrtimer.cpp
   hrtimer.h
   ida.cpp
   ida.h
   idea.cpp
   idea.h
   ideaval.dat
   integer.cpp
   integer.h
   iterhash.cpp
   iterhash.h
   lubyrack.h
   luc.cpp
   luc.h
   luc1024.dat
   luc2048.dat
   luc512.dat
   lucc1024.dat
   lucc512.dat
   lucd1024.dat
   lucd512.dat
   lucs1024.dat
   lucs512.dat
   Makefile.am
   Makefile.in
   mars.cpp
   mars.h
   marss.cpp
   marsval.dat
   md2.cpp
   md2.h
   md4.cpp
   md4.h
   md5.cpp
   md5.h
   md5mac.cpp
   md5mac.h
   mdc.h
   misc.cpp
   misc.h
   modarith.h
   modes.cpp
   modes.h
   modexppc.cpp
   modexppc.h
   mqueue.cpp
   mqueue.h
   mqv.cpp
   mqv.h
   mqv1024.dat
   mqv2048.dat
   mqv512.dat
   nbtheory.cpp
   nbtheory.h
   network.cpp
   network.h
   nr.cpp
   nr.h
   nr1024.dat
   nr2048.dat
   nr512.dat
   oaep.cpp
   oaep.h
   oids.h
   osrng.cpp
   osrng.h
   panama.cpp
   panama.h
   pch.cpp
   pch.h
   pkcspad.cpp
   pkcspad.h
   polynomi.cpp
   polynomi.h
   pssr.h
   pubkey.cpp
   pubkey.h
   queue.cpp
   queue.h
   rabi1024.dat
   rabi2048.dat
   rabi512.dat
   rabin.cpp
   rabin.h
   randpool.cpp
   randpool.h
   rc2.cpp
   rc2.h
   rc2val.dat
   rc5.cpp
   rc5.h
   rc5val.dat
   rc6.cpp
   rc6.h
   rc6val.dat
   rdtables.cpp
   rijndael.cpp
   rijndael.dat
   rijndael.h
   ripemd.cpp
   ripemd.h
   rng.cpp
   rng.h
   rsa.cpp
   rsa.h
   rsa1024.dat
   rsa2048.dat
   rsa400pb.dat
   rsa400pv.dat
   rsa512.dat
   rsa512a.dat
   rw.cpp
   rw.h
   rw1024.dat
   rw2048.dat
   rw512.dat
   safer.cpp
   safer.h
   saferval.dat
   sapphire.cpp
   sapphire.h
   seal.cpp
   seal.h
   secshare.cpp
   secshare.h
   serpent.cpp
   serpent.h
   serpentv.dat
   sha.cpp
   sha.h
   shark.cpp
   shark.h
   sharkbox.cpp
   sharkval.dat
   skipjack.cpp
   skipjack.dat
   skipjack.h
   smartptr.h
   socketft.cpp
   socketft.h
   square.cpp
   square.h
   squaretb.cpp
   squareva.dat
   tea.cpp
   tea.h
   test.cpp
   tftables.cpp
   tiger.cpp
   tiger.h
   tigertab.cpp
   trunhash.h
   twofish.cpp
   twofish.h
   twofishv.dat
   usage.dat
   validat1.cpp
   validat2.cpp
   validat3.cpp
   validate.h
   wake.cpp
   wake.h
   winpipes.cpp
   winpipes.h
   words.h
   xormac.h
   xtr.cpp
   xtr.h
   xtrcrypt.cpp
   xtrcrypt.h
   xtrdh171.dat
   xtrdh342.dat
   zdeflate.cpp
   zdeflate.h
   zinflate.cpp
   zinflate.h
   zlib.cpp
   zlib.h

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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
// dsa.cpp - written and placed in the public domain by Wei Dai

#include "pch.h"
#include "dsa.h"
#include "asn.h"
#include "oids.h"
#include "nbtheory.h"
#include "sha.h"

NAMESPACE_BEGIN(CryptoPP)

unsigned int DSAConvertSignatureFormat(byte *buffer, unsigned int bufferSize, DSASignatureFormat toFormat, const byte *signature, unsigned int signatureLen, DSASignatureFormat fromFormat)
{
	Integer r, s;
	StringStore store(signature, signatureLen);
	ArraySink sink(buffer, bufferSize);

	switch (fromFormat)
	{
	case DSA_P1363:
		r.Decode(store, signatureLen/2);
		s.Decode(store, signatureLen/2);
		break;
	case DSA_DER:
	{
		BERSequenceDecoder seq(store);
		r.BERDecode(seq);
		s.BERDecode(seq);
		seq.MessageEnd();
		break;
	}
	case DSA_OPENPGP:
		r.OpenPGPDecode(store);
		s.OpenPGPDecode(store);
		break;
	}

	switch (toFormat)
	{
	case DSA_P1363:
		r.Encode(sink, bufferSize/2);
		s.Encode(sink, bufferSize/2);
		break;
	case DSA_DER:
	{
		DERSequenceEncoder seq(sink);
		r.DEREncode(seq);
		s.DEREncode(seq);
		seq.MessageEnd();
		break;
	}
	case DSA_OPENPGP:
		r.OpenPGPEncode(sink);
		s.OpenPGPEncode(sink);
		break;
	}

	return sink.TotalPutLength();
}

Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen)
{
	Integer h;
	if (digestLen*8 <= modulusBits)
		h.Decode(digest, digestLen);
	else
	{
		h.Decode(digest, bitsToBytes(modulusBits));
		h >>= bitsToBytes(modulusBits)*8 - modulusBits;
	}
	return h;
}

GDSADigestVerifier::GDSADigestVerifier(const Integer &p, const Integer &q,
			   const Integer &g, const Integer &y)
	: m_p(p), m_q(q), m_g(g), m_y(y),
	  m_gpc(p, g), m_ypc(p, y)
{
}

void GDSADigestVerifier::Precompute(unsigned int precomputationStorage)
{
	m_gpc.Precompute(ExponentBitLength(), precomputationStorage);
	m_ypc.Precompute(ExponentBitLength(), precomputationStorage);
}

void GDSADigestVerifier::LoadPrecomputation(BufferedTransformation &bt)
{
	m_gpc.Load(bt);
	m_ypc.Load(bt);
}

void GDSADigestVerifier::SavePrecomputation(BufferedTransformation &bt) const
{
	m_gpc.Save(bt);
	m_ypc.Save(bt);
}

Integer GDSADigestVerifier::EncodeDigest(const byte *digest, unsigned int digestLen) const
{
	return DSA_EncodeDigest(m_q.BitCount(), digest, digestLen);
}

unsigned int GDSADigestVerifier::ExponentBitLength() const
{
	return m_q.BitCount();
}

GDSADigestVerifier::GDSADigestVerifier(BufferedTransformation &bt)
{
	BERSequenceDecoder subjectPublicKeyInfo(bt);
	if (subjectPublicKeyInfo.PeekByte() == INTEGER)
	{
		// for backwards compatibility
		m_p.BERDecode(subjectPublicKeyInfo);
		m_q.BERDecode(subjectPublicKeyInfo);
		m_g.BERDecode(subjectPublicKeyInfo);
		m_y.BERDecode(subjectPublicKeyInfo);
	}
	else
	{
		BERSequenceDecoder algorithm(subjectPublicKeyInfo);
			ASN1::id_dsa().BERDecodeAndCheck(algorithm);
			BERSequenceDecoder parameters(algorithm);
				m_p.BERDecode(parameters);
				m_q.BERDecode(parameters);
				m_g.BERDecode(parameters);
			parameters.MessageEnd();
		algorithm.MessageEnd();

		BERSequenceDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
			subjectPublicKey.CheckByte(0);	// unused bits
			m_y.BERDecode(subjectPublicKey);
		subjectPublicKey.MessageEnd();
	}
	subjectPublicKeyInfo.MessageEnd();

	m_gpc.SetModulusAndBase(m_p, m_g);
	m_ypc.SetModulusAndBase(m_p, m_y);
}

void GDSADigestVerifier::DEREncode(BufferedTransformation &bt) const
{
	DERSequenceEncoder subjectPublicKeyInfo(bt);

		DERSequenceEncoder algorithm(subjectPublicKeyInfo);
			ASN1::id_dsa().DEREncode(algorithm);
			DERSequenceEncoder parameters(algorithm);
				m_p.DEREncode(parameters);
				m_q.DEREncode(parameters);
				m_g.DEREncode(parameters);
			parameters.MessageEnd();
		algorithm.MessageEnd();

		DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
			subjectPublicKey.Put(0);	// unused bits
			m_y.DEREncode(subjectPublicKey);
		subjectPublicKey.MessageEnd();

	subjectPublicKeyInfo.MessageEnd();
}

bool GDSADigestVerifier::VerifyDigest(const byte *digest, unsigned int digestLen, const byte *signature) const
{
	assert(digestLen <= MaxDigestLength());

	Integer h = EncodeDigest(digest, digestLen);
	unsigned int qLen = m_q.ByteCount();
	Integer r(signature, qLen);
	Integer s(signature+qLen, qLen);
	return RawVerify(h, r, s);
}

bool GDSADigestVerifier::RawVerify(const Integer &h, const Integer &r, const Integer &s) const
{
	if (r>=m_q || r<1 || s>=m_q || s<1)
		return false;

	Integer w = EuclideanMultiplicativeInverse(s, m_q);
	Integer u1 = (h * w) % m_q;
	Integer u2 = (r * w) % m_q;
	// verify r == (g^u1 * y^u2 mod p) mod q
	return r == m_gpc.CascadeExponentiate(u1, m_ypc, u2) % m_q;
}

// ******************************************************************

GDSADigestSigner::GDSADigestSigner(const Integer &p, const Integer &q, const Integer &g, const Integer &y, const Integer &x)
	: GDSADigestVerifier(p, q, g, y), m_x(x)
{
}

GDSADigestSigner::GDSADigestSigner(RandomNumberGenerator &rng, unsigned int pbits)
{
	PrimeAndGenerator pg(1, rng, pbits, 2*DiscreteLogWorkFactor(pbits));
	m_p = pg.Prime();
	m_q = pg.SubPrime();
	m_g = pg.Generator();
	m_x.Randomize(rng, 1, m_q-1, Integer::ANY);
	m_gpc.SetModulusAndBase(m_p, m_g);
	m_y = m_gpc.Exponentiate(m_x);
	m_ypc.SetModulusAndBase(m_p, m_y);
}

GDSADigestSigner::GDSADigestSigner(RandomNumberGenerator &rng, const Integer &pIn, const Integer &qIn, const Integer &gIn)
{
	m_p = pIn;
	m_q = qIn;
	m_g = gIn;
	m_x.Randomize(rng, 1, m_q-1, Integer::ANY);
	m_gpc.SetModulusAndBase(m_p, m_g);
	m_y = m_gpc.Exponentiate(m_x);
	m_ypc.SetModulusAndBase(m_p, m_y);
}

GDSADigestSigner::GDSADigestSigner(BufferedTransformation &bt)
{
	BERSequenceDecoder privateKeyInfo(bt);
		m_p.BERDecode(privateKeyInfo);
		if (m_p != Integer::Zero())
		{
			// for backwards compatibility
			m_q.BERDecode(privateKeyInfo);
			m_g.BERDecode(privateKeyInfo);
			m_y.BERDecode(privateKeyInfo);
			m_x.BERDecode(privateKeyInfo);
		}
		else
		{
			BERSequenceDecoder algorithm(privateKeyInfo);
				ASN1::id_dsa().BERDecodeAndCheck(algorithm);
				BERSequenceDecoder parameters(algorithm);
					m_p.BERDecode(parameters);
					m_q.BERDecode(parameters);
					m_g.BERDecode(parameters);
				parameters.MessageEnd();
			algorithm.MessageEnd();

			BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
				m_x.BERDecode(octetString);
			octetString.MessageEnd();
		}
	privateKeyInfo.MessageEnd();

	m_gpc.SetModulusAndBase(m_p, m_g);
	m_y = m_gpc.Exponentiate(m_x);
	m_ypc.SetModulusAndBase(m_p, m_y);
}

void GDSADigestSigner::DEREncode(BufferedTransformation &bt) const
{
	DERSequenceEncoder privateKeyInfo(bt);

		DEREncodeUnsigned<word32>(privateKeyInfo, 0);	// version

		DERSequenceEncoder algorithm(privateKeyInfo);
			ASN1::id_dsa().DEREncode(algorithm);
			DERSequenceEncoder parameters(algorithm);
				m_p.DEREncode(parameters);
				m_q.DEREncode(parameters);
				m_g.DEREncode(parameters);
			parameters.MessageEnd();
		algorithm.MessageEnd();

		DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
			m_x.DEREncode(octetString);
		octetString.MessageEnd();

	privateKeyInfo.MessageEnd();
}

void GDSADigestSigner::SignDigest(RandomNumberGenerator &rng, const byte *digest, unsigned int digestLen, byte *signature) const
{
	assert(digestLen <= MaxDigestLength());

	Integer h = EncodeDigest(digest, digestLen);
	Integer k(rng, 1, m_q-1);
	Integer r, s;

	RawSign(k, h, r, s);
	r.Encode(signature, m_q.ByteCount());
	s.Encode(signature+m_q.ByteCount(), m_q.ByteCount());
}

void GDSADigestSigner::RawSign(const Integer &k, const Integer &h, Integer &r, Integer &s) const
{
	do
	{
		r = m_gpc.Exponentiate(k) % m_q;
		Integer kInv = EuclideanMultiplicativeInverse(k, m_q);
		s = (kInv * (m_x*r + h)) % m_q;
	} while (!r || !s);
}

bool GenerateDSAPrimes(byte *seed, unsigned int g, int &counter,
						  Integer &p, unsigned int L, Integer &q)
{
	assert(L >= MIN_DSA_PRIME_LENGTH && L <= MAX_DSA_PRIME_LENGTH);
	assert(L % 64 == 0);

	SHA sha;
	SecByteBlock U(SHA::DIGESTSIZE);
	SecByteBlock temp(SHA::DIGESTSIZE);
	SecByteBlock W(((L-1)/160+1) * SHA::DIGESTSIZE);
	const int n = (L-1) / 160;
	const int b = (L-1) % 160;
	Integer X;

	sha.CalculateDigest(U, seed, g/8);

	for (int i=g/8-1, carry=true; i>=0 && carry; i--)
		carry=!++seed[i];

	sha.CalculateDigest(temp, seed, g/8);
	xorbuf(U, temp, SHA::DIGESTSIZE);

	U[0] |= 0x80;
	U[SHA::DIGESTSIZE-1] |= 1;
	q.Decode(U, SHA::DIGESTSIZE);

	if (!IsPrime(q))
		return false;

	for (counter = 0; counter < 4096; counter++)
	{
		for (int k=0; k<=n; k++)
		{
			for (int i=g/8-1, carry=true; i>=0 && carry; i--)
				carry=!++seed[i];
			sha.CalculateDigest(W+(n-k)*SHA::DIGESTSIZE, seed, g/8);
		}
		W[SHA::DIGESTSIZE - 1 - b/8] |= 0x80;
		X.Decode(W + SHA::DIGESTSIZE - 1 - b/8, L/8);
		p = X-((X % (2*q))-1);

		if (p.GetBit(L-1) && IsPrime(p))
			return true;
	}
	return false;
}

DSAPrivateKey::DSAPrivateKey(RandomNumberGenerator &rng, unsigned int keybits)
{
	SecByteBlock seed(SHA::DIGESTSIZE);
	Integer h;
	int c;

	do
	{
		rng.GetBlock(seed, SHA::DIGESTSIZE);
	} while (!GenerateDSAPrimes(seed, SHA::DIGESTSIZE*8, c, m_p, keybits, m_q));

	do
	{
		h.Randomize(rng, 2, m_p-2);
		m_g = a_exp_b_mod_c(h, (m_p-1)/m_q, m_p);
	} while (m_g <= 1);

	m_x.Randomize(rng, 1, m_q-1);
	m_gpc.SetModulusAndBase(m_p, m_g);
	m_y = m_gpc.Exponentiate(m_x);
	m_ypc.SetModulusAndBase(m_p, m_y);
}

NAMESPACE_END

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us