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

Generated on Sat Dec 23 02:07:06 2006 for Crypto++ by  doxygen 1.5.1-p1