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 AlgorithmParameters 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 PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)0);
00105 m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed))));
00106 PutWord(false, 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