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 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