00001
00002
00003
#include "pch.h"
00004
#include "esign.h"
00005
#include "asn.h"
00006
#include "modarith.h"
00007
#include "nbtheory.h"
00008
#include "sha.h"
00009
#include "algparam.h"
00010
00011 NAMESPACE_BEGIN(CryptoPP)
00012
00013 void ESIGN_TestInstantiations()
00014 {
00015
ESIGN<SHA>::Verifier x1(1, 1);
00016
ESIGN<SHA>::Signer x2(NullRNG(), 1);
00017
ESIGN<SHA>::Verifier x3(x2);
00018
ESIGN<SHA>::Verifier x4(x2.GetKey());
00019
ESIGN<SHA>::Verifier x5(x3);
00020
ESIGN<SHA>::Signer x6 = x2;
00021
00022 x6 = x2;
00023 x3 =
ESIGN<SHA>::Verifier(x2);
00024 x4 = x2.GetKey();
00025 }
00026
00027 void ESIGNFunction::BERDecode(
BufferedTransformation &bt)
00028 {
00029
BERSequenceDecoder seq(bt);
00030 m_n.
BERDecode(seq);
00031 m_e.
BERDecode(seq);
00032 seq.
MessageEnd();
00033 }
00034
00035 void ESIGNFunction::DEREncode(
BufferedTransformation &bt)
const
00036
{
00037
DERSequenceEncoder seq(bt);
00038 m_n.
DEREncode(seq);
00039 m_e.
DEREncode(seq);
00040 seq.
MessageEnd();
00041 }
00042
00043
Integer ESIGNFunction::ApplyFunction(
const Integer &x)
const
00044
{
00045 DoQuickSanityCheck();
00046
return STDMIN(a_exp_b_mod_c(x, m_e, m_n) >> (2*GetK()+2), MaxImage());
00047 }
00048
00049 bool ESIGNFunction::Validate(
RandomNumberGenerator &rng,
unsigned int level)
const
00050
{
00051
bool pass =
true;
00052 pass = pass && m_n >
Integer::One() && m_n.
IsOdd();
00053 pass = pass && m_e >= 8 && m_e < m_n;
00054
return pass;
00055 }
00056
00057 bool ESIGNFunction::GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00058
{
00059
return GetValueHelper(
this, name, valueType, pValue).Assignable()
00060 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
00061 CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent)
00062 ;
00063 }
00064
00065 void ESIGNFunction::AssignFrom(
const NameValuePairs &source)
00066 {
00067 AssignFromHelper(
this, source)
00068 CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
00069 CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent)
00070 ;
00071 }
00072
00073
00074
00075 void InvertibleESIGNFunction::GenerateRandom(
RandomNumberGenerator &rng,
const NameValuePairs ¶m)
00076 {
00077
int modulusSize = 1023*2;
00078 param.
GetIntValue(
"ModulusSize", modulusSize) || param.
GetIntValue(
"KeySize", modulusSize);
00079
00080
if (modulusSize < 24)
00081
throw InvalidArgument(
"InvertibleESIGNFunction: specified modulus size is too small");
00082
00083
if (modulusSize % 3 != 0)
00084
throw InvalidArgument(
"InvertibleESIGNFunction: modulus size must be divisible by 3");
00085
00086 m_e = param.
GetValueWithDefault(
"PublicExponent",
Integer(32));
00087
00088
if (m_e < 8)
00089
throw InvalidArgument(
"InvertibleESIGNFunction: public exponents less than 8 may not be secure");
00090
00091
00092
ConstByteArrayParameter seedParam;
00093
SecByteBlock seed;
00094
00095
const Integer minP =
Integer(204) << (modulusSize/3-8);
00096
const Integer maxP = Integer::Power2(modulusSize/3)-1;
00097
const NameValuePairs &primeParam = MakeParameters(
"Min", minP)(
"Max", maxP)(
"RandomNumberType", Integer::PRIME);
00098
00099
if (param.
GetValue(
"Seed", seedParam))
00100 {
00101 seed.
resize(seedParam.
size() + 4);
00102 memcpy(seed + 4, seedParam.
begin(), seedParam.
size());
00103
00104 UnalignedPutWord(BIG_ENDIAN_ORDER, seed, (word32)0);
00105 m_p.
GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters(
"Seed",
ConstByteArrayParameter(seed))));
00106 UnalignedPutWord(BIG_ENDIAN_ORDER, seed, (word32)1);
00107 m_q.
GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters(
"Seed",
ConstByteArrayParameter(seed))));
00108 }
00109
else
00110 {
00111 m_p.
GenerateRandom(rng, primeParam);
00112 m_q.
GenerateRandom(rng, primeParam);
00113 }
00114
00115 m_n = m_p * m_p * m_q;
00116
00117 assert(m_n.
BitCount() == modulusSize);
00118 }
00119
00120 void InvertibleESIGNFunction::BERDecode(
BufferedTransformation &bt)
00121 {
00122
BERSequenceDecoder privateKey(bt);
00123 m_n.
BERDecode(privateKey);
00124 m_e.
BERDecode(privateKey);
00125 m_p.
BERDecode(privateKey);
00126 m_q.
BERDecode(privateKey);
00127 privateKey.
MessageEnd();
00128 }
00129
00130 void InvertibleESIGNFunction::DEREncode(
BufferedTransformation &bt)
const
00131
{
00132
DERSequenceEncoder privateKey(bt);
00133 m_n.
DEREncode(privateKey);
00134 m_e.
DEREncode(privateKey);
00135 m_p.
DEREncode(privateKey);
00136 m_q.
DEREncode(privateKey);
00137 privateKey.
MessageEnd();
00138 }
00139
00140
Integer InvertibleESIGNFunction::CalculateRandomizedInverse(
RandomNumberGenerator &rng,
const Integer &x)
const
00141
{
00142 DoQuickSanityCheck();
00143
00144
Integer pq = m_p * m_q;
00145
Integer p2 = m_p * m_p;
00146
Integer r, z, re, a, w0, w1;
00147
00148
do
00149 {
00150 r.
Randomize(rng, Integer::Zero(), pq);
00151 z = x << (2*GetK()+2);
00152 re = a_exp_b_mod_c(r, m_e, m_n);
00153 a = (z - re) % m_n;
00154 Integer::Divide(w1, w0, a, pq);
00155
if (w1.
NotZero())
00156 {
00157 ++w0;
00158 w1 = pq - w1;
00159 }
00160 }
00161
while ((w1 >> 2*GetK()+1).IsPositive());
00162
00163
ModularArithmetic modp(m_p);
00164
Integer t = modp.
Divide(w0 * r % m_p, m_e * re % m_p);
00165
Integer s = r + t*pq;
00166 assert(s < m_n);
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
return s;
00179 }
00180
00181 bool InvertibleESIGNFunction::Validate(
RandomNumberGenerator &rng,
unsigned int level)
const
00182
{
00183
bool pass = ESIGNFunction::Validate(rng, level);
00184 pass = pass && m_p >
Integer::One() && m_p.
IsOdd() && m_p < m_n;
00185 pass = pass && m_q >
Integer::One() && m_q.
IsOdd() && m_q < m_n;
00186 pass = pass && m_p.BitCount() == m_q.BitCount();
00187
if (level >= 1)
00188 pass = pass && m_p * m_p * m_q == m_n;
00189
if (level >= 2)
00190 pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
00191
return pass;
00192 }
00193
00194 bool InvertibleESIGNFunction::GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
00195
{
00196
return GetValueHelper<ESIGNFunction>(
this, name, valueType, pValue).Assignable()
00197 CRYPTOPP_GET_FUNCTION_ENTRY(Prime1)
00198 CRYPTOPP_GET_FUNCTION_ENTRY(Prime2)
00199 ;
00200 }
00201
00202 void InvertibleESIGNFunction::AssignFrom(
const NameValuePairs &source)
00203 {
00204 AssignFromHelper<ESIGNFunction>(
this, source)
00205 CRYPTOPP_SET_FUNCTION_ENTRY(Prime1)
00206 CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
00207 ;
00208 }
00209
00210 NAMESPACE_END