00001
00002
00003 #include "pch.h"
00004 #include "luc.h"
00005 #include "asn.h"
00006 #include "nbtheory.h"
00007 #include "sha.h"
00008 #include "algparam.h"
00009
00010 #include "oaep.cpp"
00011
00012 NAMESPACE_BEGIN(CryptoPP)
00013
00014 void LUC_TestInstantiations()
00015 {
00016 LUC_HMP<SHA>::Signer t1;
00017 LUCFunction t2;
00018 InvertibleLUCFunction t3;
00019 }
00020
00021 void DL_Algorithm_LUC_HMP::Sign(const DL_GroupParameters<Integer> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
00022 {
00023 const Integer &q = params.GetSubgroupOrder();
00024 r = params.ExponentiateBase(k);
00025 s = (k + x*(r+e)) % q;
00026 }
00027
00028 bool DL_Algorithm_LUC_HMP::Verify(const DL_GroupParameters<Integer> ¶ms, const DL_PublicKey<Integer> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
00029 {
00030 Integer p = params.GetGroupOrder()-1;
00031 const Integer &q = params.GetSubgroupOrder();
00032
00033 Integer Vsg = params.ExponentiateBase(s);
00034 Integer Vry = publicKey.ExponentiatePublicElement((r+e)%q);
00035 return (Vsg*Vsg + Vry*Vry + r*r) % p == (Vsg * Vry * r + 4) % p;
00036 }
00037
00038 Integer DL_BasePrecomputation_LUC::Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const
00039 {
00040 return Lucas(exponent, m_g, static_cast<const DL_GroupPrecomputation_LUC &>(group).GetModulus());
00041 }
00042
00043 void DL_GroupParameters_LUC::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
00044 {
00045 for (unsigned int i=0; i<exponentsCount; i++)
00046 results[i] = Lucas(exponents[i], base, GetModulus());
00047 }
00048
00049 void LUCFunction::BERDecode(BufferedTransformation &bt)
00050 {
00051 BERSequenceDecoder seq(bt);
00052 m_n.BERDecode(seq);
00053 m_e.BERDecode(seq);
00054 seq.MessageEnd();
00055 }
00056
00057 void LUCFunction::DEREncode(BufferedTransformation &bt) const
00058 {
00059 DERSequenceEncoder seq(bt);
00060 m_n.DEREncode(seq);
00061 m_e.DEREncode(seq);
00062 seq.MessageEnd();
00063 }
00064
00065 Integer LUCFunction::ApplyFunction(const Integer &x) const
00066 {
00067 DoQuickSanityCheck();
00068 return Lucas(m_e, x, m_n);
00069 }
00070
00071 bool LUCFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
00072 {
00073 bool pass = true;
00074 pass = pass && m_n > Integer::One() && m_n.IsOdd();
00075 pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n;
00076 return pass;
00077 }
00078
00079 bool LUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00080 {
00081 return GetValueHelper(this, name, valueType, pValue).Assignable()
00082 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
00083 CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent)
00084 ;
00085 }
00086
00087 void LUCFunction::AssignFrom(const NameValuePairs &source)
00088 {
00089 AssignFromHelper(this, source)
00090 CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
00091 CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent)
00092 ;
00093 }
00094
00095
00096
00097
00098 class LUCPrimeSelector : public PrimeSelector
00099 {
00100 public:
00101 LUCPrimeSelector(const Integer &e) : m_e(e) {}
00102 bool IsAcceptable(const Integer &candidate) const
00103 {
00104 return RelativelyPrime(m_e, candidate+1) && RelativelyPrime(m_e, candidate-1);
00105 }
00106 Integer m_e;
00107 };
00108
00109 void InvertibleLUCFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
00110 {
00111 int modulusSize = 2048;
00112 alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
00113
00114 if (modulusSize < 16)
00115 throw InvalidArgument("InvertibleLUCFunction: specified modulus size is too small");
00116
00117 m_e = alg.GetValueWithDefault("PublicExponent", Integer(17));
00118
00119 if (m_e < 5 || m_e.IsEven())
00120 throw InvalidArgument("InvertibleLUCFunction: invalid public exponent");
00121
00122 LUCPrimeSelector selector(m_e);
00123 const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize)
00124 ("PointerToPrimeSelector", selector.GetSelectorPointer());
00125 m_p.GenerateRandom(rng, primeParam);
00126 m_q.GenerateRandom(rng, primeParam);
00127
00128 m_n = m_p * m_q;
00129 m_u = m_q.InverseMod(m_p);
00130 }
00131
00132 void InvertibleLUCFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e)
00133 {
00134 GenerateRandom(rng, MakeParameters("ModulusSize", (int)keybits)("PublicExponent", e));
00135 }
00136
00137 void InvertibleLUCFunction::BERDecode(BufferedTransformation &bt)
00138 {
00139 BERSequenceDecoder seq(bt);
00140
00141 Integer version(seq);
00142 if (!!version)
00143 BERDecodeError();
00144
00145 m_n.BERDecode(seq);
00146 m_e.BERDecode(seq);
00147 m_p.BERDecode(seq);
00148 m_q.BERDecode(seq);
00149 m_u.BERDecode(seq);
00150 seq.MessageEnd();
00151 }
00152
00153 void InvertibleLUCFunction::DEREncode(BufferedTransformation &bt) const
00154 {
00155 DERSequenceEncoder seq(bt);
00156
00157 const byte version[] = {INTEGER, 1, 0};
00158 seq.Put(version, sizeof(version));
00159 m_n.DEREncode(seq);
00160 m_e.DEREncode(seq);
00161 m_p.DEREncode(seq);
00162 m_q.DEREncode(seq);
00163 m_u.DEREncode(seq);
00164 seq.MessageEnd();
00165 }
00166
00167 Integer InvertibleLUCFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const
00168 {
00169
00170 DoQuickSanityCheck();
00171 return InverseLucas(m_e, x, m_q, m_p, m_u);
00172 }
00173
00174 bool InvertibleLUCFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
00175 {
00176 bool pass = LUCFunction::Validate(rng, level);
00177 pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n;
00178 pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n;
00179 pass = pass && m_u.IsPositive() && m_u < m_p;
00180 if (level >= 1)
00181 {
00182 pass = pass && m_p * m_q == m_n;
00183 pass = pass && RelativelyPrime(m_e, m_p+1);
00184 pass = pass && RelativelyPrime(m_e, m_p-1);
00185 pass = pass && RelativelyPrime(m_e, m_q+1);
00186 pass = pass && RelativelyPrime(m_e, m_q-1);
00187 pass = pass && m_u * m_q % m_p == 1;
00188 }
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 InvertibleLUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00195 {
00196 return GetValueHelper<LUCFunction>(this, name, valueType, pValue).Assignable()
00197 CRYPTOPP_GET_FUNCTION_ENTRY(Prime1)
00198 CRYPTOPP_GET_FUNCTION_ENTRY(Prime2)
00199 CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
00200 ;
00201 }
00202
00203 void InvertibleLUCFunction::AssignFrom(const NameValuePairs &source)
00204 {
00205 AssignFromHelper<LUCFunction>(this, source)
00206 CRYPTOPP_SET_FUNCTION_ENTRY(Prime1)
00207 CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
00208 CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
00209 ;
00210 }
00211
00212 NAMESPACE_END