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 00005 #ifndef CRYPTOPP_IMPORTS 00006 00007 #include "dsa.h" 00008 #include "nbtheory.h" 00009 00010 NAMESPACE_BEGIN(CryptoPP) 00011 00012 unsigned int DSAConvertSignatureFormat(byte *buffer, unsigned int bufferSize, DSASignatureFormat toFormat, const byte *signature, unsigned int 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 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 Fri Aug 27 21:59:26 2004 for Crypto++ by doxygen 1.3.8