diff options
author | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
---|---|---|
committer | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
commit | b21162cf8e06f40baa1f58be6a8c17435cebc34d (patch) | |
tree | 8b045309c238226c32a563b1df6b9c30a2f0e0b3 /dsa.cpp | |
download | cryptopp-b21162cf8e06f40baa1f58be6a8c17435cebc34d.tar.gz |
Initial revision
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'dsa.cpp')
-rw-r--r-- | dsa.cpp | 114 |
1 files changed, 114 insertions, 0 deletions
@@ -0,0 +1,114 @@ +// dsa.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "dsa.h" +#include "nbtheory.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(); +} + +bool DSA::GeneratePrimes(const byte *seedIn, unsigned int g, int &counter, + Integer &p, unsigned int L, Integer &q, bool useInputCounterValue) +{ + assert(g%8 == 0); + + SHA sha; + SecByteBlock seed(seedIn, g/8); + 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; + + int counterEnd = useInputCounterValue ? counter+1 : 4096; + + for (int c = 0; c < counterEnd; c++) + { + for (int k=0; k<=n; k++) + { + for (int i=g/8-1, carry=true; i>=0 && carry; i--) + carry=!++seed[i]; + if (!useInputCounterValue || c == counter) + sha.CalculateDigest(W+(n-k)*SHA::DIGESTSIZE, seed, g/8); + } + if (!useInputCounterValue || c == counter) + { + 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)) + { + counter = c; + return true; + } + } + } + return false; +} + +NAMESPACE_END |