00001
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