// dsa.cpp - written and placed in the public domain by Wei Dai #include "pch.h" #ifndef CRYPTOPP_IMPORTS #include "dsa.h" #include "nbtheory.h" NAMESPACE_BEGIN(CryptoPP) size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFormat toFormat, const byte *signature, size_t 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 (size_t)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 #endif