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