Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

dsa.cpp

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

Generated on Mon Apr 19 18:12:29 2004 for Crypto++ by doxygen 1.3.6-20040222