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