Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

luc.cpp

00001 // luc.cpp - written and placed in the public domain by Wei Dai 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> &params, 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> &params, 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 // private key operations: 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) // make sure version is 0 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 // not clear how to do blinding with LUC 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

Generated on Wed Jul 28 08:07:08 2004 for Crypto++ by doxygen 1.3.7