- Main Page
- Namespaces
- Classes
- Files

# dsa.cpp

    00001 // dsa.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004
    00005 #ifndef CRYPTOPP_IMPORTS
    00006
    00007 #include "dsa.h"
    00008 #include "nbtheory.h"
    00009
    00010 NAMESPACE_BEGIN(CryptoPP)
    00011
    00012 size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFormat toFormat, const byte *signature, size_t signatureLen, DSASignatureFormat fromFormat)
    00013 {
    00014         Integer r, s;
    00015         StringStore store(signature, signatureLen);
    00016         ArraySink sink(buffer, bufferSize);
    00017
    00018         switch (fromFormat)
    00019         {
    00020         case DSA_P1363:
    00021                 r.Decode(store, signatureLen/2);
    00022                 s.Decode(store, signatureLen/2);
    00023                 break;
    00024         case DSA_DER:
    00025         {
    00026                 BERSequenceDecoder seq(store);
    00027                 r.BERDecode(seq);
    00028                 s.BERDecode(seq);
    00029                 seq.MessageEnd();
    00030                 break;
    00031         }
    00032         case DSA_OPENPGP:
    00033                 r.OpenPGPDecode(store);
    00034                 s.OpenPGPDecode(store);
    00035                 break;
    00036         }
    00037
    00038         switch (toFormat)
    00039         {
    00040         case DSA_P1363:
    00041                 r.Encode(sink, bufferSize/2);
    00042                 s.Encode(sink, bufferSize/2);
    00043                 break;
    00044         case DSA_DER:
    00045         {
    00046                 DERSequenceEncoder seq(sink);
    00047                 r.DEREncode(seq);
    00048                 s.DEREncode(seq);
    00049                 seq.MessageEnd();
    00050                 break;
    00051         }
    00052         case DSA_OPENPGP:
    00053                 r.OpenPGPEncode(sink);
    00054                 s.OpenPGPEncode(sink);
    00055                 break;
    00056         }
    00057
    00058         return (size_t)sink.TotalPutLength();
    00059 }
    00060
    00061 bool DSA::GeneratePrimes(const byte *seedIn, unsigned int g, int &counter,
    00062                                                   Integer &p, unsigned int L, Integer &q, bool useInputCounterValue)
    00063 {
    00064         assert(g%8 == 0);
    00065
    00066         SHA sha;
    00067         SecByteBlock seed(seedIn, g/8);
    00068         SecByteBlock U(SHA::DIGESTSIZE);
    00069         SecByteBlock temp(SHA::DIGESTSIZE);
    00070         SecByteBlock W(((L-1)/160+1) * SHA::DIGESTSIZE);
    00071         const int n = (L-1) / 160;
    00072         const int b = (L-1) % 160;
    00073         Integer X;
    00074
    00075         sha.CalculateDigest(U, seed, g/8);
    00076
    00077         for (int i=g/8-1, carry=true; i>=0 && carry; i--)
    00078                 carry=!++seed[i];
    00079
    00080         sha.CalculateDigest(temp, seed, g/8);
    00081         xorbuf(U, temp, SHA::DIGESTSIZE);
    00082
    00083         U[0] |= 0x80;
    00084         U[SHA::DIGESTSIZE-1] |= 1;
    00085         q.Decode(U, SHA::DIGESTSIZE);
    00086
    00087         if (!IsPrime(q))
    00088                 return false;
    00089
    00090         int counterEnd = useInputCounterValue ? counter+1 : 4096;
    00091
    00092         for (int c = 0; c < counterEnd; c++)
    00093         {
    00094                 for (int k=0; k<=n; k++)
    00095                 {
    00096                         for (int i=g/8-1, carry=true; i>=0 && carry; i--)
    00097                                 carry=!++seed[i];
    00098                         if (!useInputCounterValue || c == counter)
    00099                                 sha.CalculateDigest(W+(n-k)*SHA::DIGESTSIZE, seed, g/8);
    00100                 }
    00101                 if (!useInputCounterValue || c == counter)
    00102                 {
    00103                         W[SHA::DIGESTSIZE - 1 - b/8] |= 0x80;
    00104                         X.Decode(W + SHA::DIGESTSIZE - 1 - b/8, L/8);
    00105                         p = X-((X % (2*q))-1);
    00106
    00107                         if (p.GetBit(L-1) && IsPrime(p))
    00108                         {
    00109                                 counter = c;
    00110                                 return true;
    00111                         }
    00112                 }
    00113         }
    00114         return false;
    00115 }
    00116
    00117 NAMESPACE_END
    00118
    00119 #endif