00001
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