<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>Crypto++: luc.cpp Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.3.7 --> <div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Class Members</a> | <a class="qindex" href="globals.html">File Members</a></div> <h1>luc.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// luc.cpp - written and placed in the public domain by Wei Dai</span> 00002 00003 <span class="preprocessor">#include "pch.h"</span> 00004 <span class="preprocessor">#include "<a class="code" href="luc_8h.html">luc.h</a>"</span> 00005 <span class="preprocessor">#include "asn.h"</span> 00006 <span class="preprocessor">#include "nbtheory.h"</span> 00007 <span class="preprocessor">#include "sha.h"</span> 00008 <span class="preprocessor">#include "algparam.h"</span> 00009 00010 NAMESPACE_BEGIN(CryptoPP) 00011 00012 void LUC_TestInstantiations() 00013 { 00014 <a class="code" href="struct_l_u_c___h_m_p.html">LUC_HMP<SHA></a>::Signer t1; 00015 <a class="code" href="class_l_u_c_function.html">LUCFunction</a> t2; 00016 <a class="code" href="class_invertible_l_u_c_function.html">InvertibleLUCFunction</a> t3; 00017 } 00018 00019 <span class="keywordtype">void</span> DL_Algorithm_LUC_HMP::Sign(<span class="keyword">const</span> <a class="code" href="class_d_l___group_parameters.html">DL_GroupParameters<Integer></a> &params, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &x, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &k, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &e, <a class="code" href="class_integer.html">Integer</a> &r, <a class="code" href="class_integer.html">Integer</a> &s)<span class="keyword"> const</span> 00020 <span class="keyword"></span>{ 00021 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &q = params.<a class="code" href="class_d_l___group_parameters.html#_d_l___group_parametersa14">GetSubgroupOrder</a>(); 00022 r = params.<a class="code" href="class_d_l___group_parameters.html#_d_l___group_parametersa9">ExponentiateBase</a>(k); 00023 s = (k + x*(r+e)) % q; 00024 } 00025 00026 <span class="keywordtype">bool</span> DL_Algorithm_LUC_HMP::Verify(<span class="keyword">const</span> <a class="code" href="class_d_l___group_parameters.html">DL_GroupParameters<Integer></a> &params, <span class="keyword">const</span> <a class="code" href="class_d_l___public_key.html">DL_PublicKey<Integer></a> &publicKey, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &e, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &r, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &s)<span class="keyword"> const</span> 00027 <span class="keyword"></span>{ 00028 <a class="code" href="class_integer.html">Integer</a> p = params.<a class="code" href="class_d_l___group_parameters.html#_d_l___group_parametersa16">GetGroupOrder</a>()-1; 00029 <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &q = params.<a class="code" href="class_d_l___group_parameters.html#_d_l___group_parametersa14">GetSubgroupOrder</a>(); 00030 00031 <a class="code" href="class_integer.html">Integer</a> Vsg = params.<a class="code" href="class_d_l___group_parameters.html#_d_l___group_parametersa9">ExponentiateBase</a>(s); 00032 <a class="code" href="class_integer.html">Integer</a> Vry = publicKey.<a class="code" href="class_d_l___public_key.html#_d_l___public_keya4">ExponentiatePublicElement</a>((r+e)%q); 00033 <span class="keywordflow">return</span> (Vsg*Vsg + Vry*Vry + r*r) % p == (Vsg * Vry * r + 4) % p; 00034 } 00035 00036 <a class="code" href="class_integer.html">Integer</a> DL_BasePrecomputation_LUC::Exponentiate(<span class="keyword">const</span> DL_GroupPrecomputation<Element> &group, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &exponent)<span class="keyword"> const</span> 00037 <span class="keyword"></span>{ 00038 <span class="keywordflow">return</span> Lucas(exponent, m_g, static_cast<const DL_GroupPrecomputation_LUC &>(group).GetModulus()); 00039 } 00040 00041 <span class="keywordtype">void</span> DL_GroupParameters_LUC::SimultaneousExponentiate(Element *results, <span class="keyword">const</span> Element &base, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> *exponents, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> exponentsCount)<span class="keyword"> const</span> 00042 <span class="keyword"></span>{ 00043 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i<exponentsCount; i++) 00044 results[i] = Lucas(exponents[i], base, GetModulus()); 00045 } 00046 00047 <span class="keywordtype">void</span> LUCFunction::BERDecode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt) 00048 { 00049 <a class="code" href="class_b_e_r_sequence_decoder.html">BERSequenceDecoder</a> seq(bt); 00050 m_n.<a class="code" href="class_integer.html#_integerz39_9">BERDecode</a>(seq); 00051 m_e.<a class="code" href="class_integer.html#_integerz39_9">BERDecode</a>(seq); 00052 seq.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00053 } 00054 00055 <span class="keywordtype">void</span> LUCFunction::DEREncode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00056 <span class="keyword"></span>{ 00057 <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> seq(bt); 00058 m_n.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq); 00059 m_e.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq); 00060 seq.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00061 } 00062 00063 <a class="code" href="class_integer.html">Integer</a> LUCFunction::ApplyFunction(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &x)<span class="keyword"> const</span> 00064 <span class="keyword"></span>{ 00065 DoQuickSanityCheck(); 00066 <span class="keywordflow">return</span> Lucas(m_e, x, m_n); 00067 } 00068 <a name="l00069"></a><a class="code" href="class_l_u_c_function.html#_l_u_c_functiona6">00069</a> <span class="keywordtype">bool</span> <a class="code" href="class_l_u_c_function.html#_l_u_c_functiona6">LUCFunction::Validate</a>(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &rng, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> level)<span class="keyword"> const</span> 00070 <span class="keyword"></span>{ 00071 <span class="keywordtype">bool</span> pass = <span class="keyword">true</span>; 00072 pass = pass && m_n > <a class="code" href="class_integer.html#_integerz37_13">Integer::One</a>() && m_n.<a class="code" href="class_integer.html#_integerz41_15">IsOdd</a>(); 00073 pass = pass && m_e > <a class="code" href="class_integer.html#_integerz37_13">Integer::One</a>() && m_e.<a class="code" href="class_integer.html#_integerz41_15">IsOdd</a>() && m_e < m_n; 00074 <span class="keywordflow">return</span> pass; 00075 } 00076 <a name="l00077"></a><a class="code" href="class_l_u_c_function.html#_l_u_c_functiona7">00077</a> <span class="keywordtype">bool</span> <a class="code" href="class_l_u_c_function.html#_l_u_c_functiona7">LUCFunction::GetVoidValue</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keyword">const</span> std::type_info &valueType, <span class="keywordtype">void</span> *pValue)<span class="keyword"> const</span> 00078 <span class="keyword"></span>{ 00079 <span class="keywordflow">return</span> GetValueHelper(<span class="keyword">this</span>, name, valueType, pValue).Assignable() 00080 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) 00081 CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) 00082 ; 00083 } 00084 <a name="l00085"></a><a class="code" href="class_l_u_c_function.html#_l_u_c_functiona8">00085</a> <span class="keywordtype">void</span> <a class="code" href="class_l_u_c_function.html#_l_u_c_functiona8">LUCFunction::AssignFrom</a>(<span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &source) 00086 { 00087 AssignFromHelper(<span class="keyword">this</span>, source) 00088 CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) 00089 CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) 00090 ; 00091 } 00092 00093 <span class="comment">// *****************************************************************************</span> 00094 <span class="comment">// private key operations:</span> 00095 00096 <span class="keyword">class </span>LUCPrimeSelector : <span class="keyword">public</span> PrimeSelector 00097 { 00098 <span class="keyword">public</span>: 00099 LUCPrimeSelector(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &e) : m_e(e) {} 00100 <span class="keywordtype">bool</span> IsAcceptable(<span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &candidate)<span class="keyword"> const</span> 00101 <span class="keyword"> </span>{ 00102 <span class="keywordflow">return</span> RelativelyPrime(m_e, candidate+1) && RelativelyPrime(m_e, candidate-1); 00103 } 00104 <a class="code" href="class_integer.html">Integer</a> m_e; 00105 }; 00106 <a name="l00107"></a><a class="code" href="class_invertible_l_u_c_function.html#_invertible_l_u_c_functiona8">00107</a> <span class="keywordtype">void</span> <a class="code" href="class_invertible_l_u_c_function.html#_invertible_l_u_c_functiona8">InvertibleLUCFunction::GenerateRandom</a>(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &rng, <span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &alg) 00108 { 00109 <span class="keywordtype">int</span> modulusSize = 2048; 00110 alg.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha42">GetIntValue</a>(<span class="stringliteral">"ModulusSize"</span>, modulusSize) || alg.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha42">GetIntValue</a>(<span class="stringliteral">"KeySize"</span>, modulusSize); 00111 00112 <span class="keywordflow">if</span> (modulusSize < 16) 00113 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"InvertibleLUCFunction: specified modulus size is too small"</span>); 00114 00115 m_e = alg.<a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha40">GetValueWithDefault</a>(<span class="stringliteral">"PublicExponent"</span>, <a class="code" href="class_integer.html">Integer</a>(17)); 00116 00117 <span class="keywordflow">if</span> (m_e < 5 || m_e.<a class="code" href="class_integer.html#_integerz41_14">IsEven</a>()) 00118 <span class="keywordflow">throw</span> <a class="code" href="class_invalid_argument.html">InvalidArgument</a>(<span class="stringliteral">"InvertibleLUCFunction: invalid public exponent"</span>); 00119 00120 LUCPrimeSelector selector(m_e); 00121 <span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) 00122 (<span class="stringliteral">"PointerToPrimeSelector"</span>, selector.GetSelectorPointer()); 00123 m_p.<a class="code" href="class_integer.html#_integerz43_14">GenerateRandom</a>(rng, primeParam); 00124 m_q.<a class="code" href="class_integer.html#_integerz43_14">GenerateRandom</a>(rng, primeParam); 00125 00126 m_n = m_p * m_q; 00127 m_u = m_q.<a class="code" href="class_integer.html#_integerz49_7">InverseMod</a>(m_p); 00128 } 00129 00130 <span class="keywordtype">void</span> InvertibleLUCFunction::Initialize(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &rng, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> keybits, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &e) 00131 { 00132 GenerateRandom(rng, MakeParameters(<span class="stringliteral">"ModulusSize"</span>, (<span class="keywordtype">int</span>)keybits)(<span class="stringliteral">"PublicExponent"</span>, e)); 00133 } 00134 00135 <span class="keywordtype">void</span> InvertibleLUCFunction::BERDecode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt) 00136 { 00137 <a class="code" href="class_b_e_r_sequence_decoder.html">BERSequenceDecoder</a> seq(bt); 00138 00139 <a class="code" href="class_integer.html">Integer</a> version(seq); 00140 <span class="keywordflow">if</span> (!!version) <span class="comment">// make sure version is 0</span> 00141 BERDecodeError(); 00142 00143 m_n.<a class="code" href="class_integer.html#_integerz39_9">BERDecode</a>(seq); 00144 m_e.<a class="code" href="class_integer.html#_integerz39_9">BERDecode</a>(seq); 00145 m_p.<a class="code" href="class_integer.html#_integerz39_9">BERDecode</a>(seq); 00146 m_q.<a class="code" href="class_integer.html#_integerz39_9">BERDecode</a>(seq); 00147 m_u.<a class="code" href="class_integer.html#_integerz39_9">BERDecode</a>(seq); 00148 seq.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00149 } 00150 00151 <span class="keywordtype">void</span> InvertibleLUCFunction::DEREncode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00152 <span class="keyword"></span>{ 00153 <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> seq(bt); 00154 00155 <span class="keyword">const</span> byte version[] = {INTEGER, 1, 0}; 00156 seq.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(version, <span class="keyword">sizeof</span>(version)); 00157 m_n.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq); 00158 m_e.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq); 00159 m_p.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq); 00160 m_q.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq); 00161 m_u.<a class="code" href="class_integer.html#_integerz39_3">DEREncode</a>(seq); 00162 seq.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00163 } 00164 00165 <a class="code" href="class_integer.html">Integer</a> InvertibleLUCFunction::CalculateInverse(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &rng, <span class="keyword">const</span> <a class="code" href="class_integer.html">Integer</a> &x)<span class="keyword"> const</span> 00166 <span class="keyword"></span>{ 00167 <span class="comment">// not clear how to do blinding with LUC</span> 00168 DoQuickSanityCheck(); 00169 <span class="keywordflow">return</span> InverseLucas(m_e, x, m_q, m_p, m_u); 00170 } 00171 <a name="l00172"></a><a class="code" href="class_invertible_l_u_c_function.html#_invertible_l_u_c_functiona5">00172</a> <span class="keywordtype">bool</span> <a class="code" href="class_invertible_l_u_c_function.html#_invertible_l_u_c_functiona5">InvertibleLUCFunction::Validate</a>(<a class="code" href="class_random_number_generator.html">RandomNumberGenerator</a> &rng, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> level)<span class="keyword"> const</span> 00173 <span class="keyword"></span>{ 00174 <span class="keywordtype">bool</span> pass = LUCFunction::Validate(rng, level); 00175 pass = pass && m_p > <a class="code" href="class_integer.html#_integerz37_13">Integer::One</a>() && m_p.<a class="code" href="class_integer.html#_integerz41_15">IsOdd</a>() && m_p < m_n; 00176 pass = pass && m_q > <a class="code" href="class_integer.html#_integerz37_13">Integer::One</a>() && m_q.<a class="code" href="class_integer.html#_integerz41_15">IsOdd</a>() && m_q < m_n; 00177 pass = pass && m_u.<a class="code" href="class_integer.html#_integerz41_12">IsPositive</a>() && m_u < m_p; 00178 <span class="keywordflow">if</span> (level >= 1) 00179 { 00180 pass = pass && m_p * m_q == m_n; 00181 pass = pass && RelativelyPrime(m_e, m_p+1); 00182 pass = pass && RelativelyPrime(m_e, m_p-1); 00183 pass = pass && RelativelyPrime(m_e, m_q+1); 00184 pass = pass && RelativelyPrime(m_e, m_q-1); 00185 pass = pass && m_u * m_q % m_p == 1; 00186 } 00187 <span class="keywordflow">if</span> (level >= 2) 00188 pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); 00189 <span class="keywordflow">return</span> pass; 00190 } 00191 <a name="l00192"></a><a class="code" href="class_invertible_l_u_c_function.html#_invertible_l_u_c_functiona6">00192</a> <span class="keywordtype">bool</span> <a class="code" href="class_invertible_l_u_c_function.html#_invertible_l_u_c_functiona6">InvertibleLUCFunction::GetVoidValue</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keyword">const</span> std::type_info &valueType, <span class="keywordtype">void</span> *pValue)<span class="keyword"> const</span> 00193 <span class="keyword"></span>{ 00194 <span class="keywordflow">return</span> GetValueHelper<LUCFunction>(<span class="keyword">this</span>, name, valueType, pValue).Assignable() 00195 CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) 00196 CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) 00197 CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) 00198 ; 00199 } 00200 <a name="l00201"></a><a class="code" href="class_invertible_l_u_c_function.html#_invertible_l_u_c_functiona7">00201</a> <span class="keywordtype">void</span> <a class="code" href="class_invertible_l_u_c_function.html#_invertible_l_u_c_functiona7">InvertibleLUCFunction::AssignFrom</a>(<span class="keyword">const</span> <a class="code" href="class_name_value_pairs.html">NameValuePairs</a> &source) 00202 { 00203 AssignFromHelper<LUCFunction>(<span class="keyword">this</span>, source) 00204 CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) 00205 CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) 00206 CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) 00207 ; 00208 } 00209 00210 NAMESPACE_END </div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:58 2004 for Crypto++ by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.7 </small></address> </body> </html>