<!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++: ec2n.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>ec2n.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// ec2n.cpp - written and placed in the public domain by Wei Dai</span> 00002 00003 <span class="preprocessor">#include "pch.h"</span> 00004 00005 <span class="preprocessor">#ifndef CRYPTOPP_IMPORTS</span> 00006 <span class="preprocessor"></span> 00007 <span class="preprocessor">#include "ec2n.h"</span> 00008 <span class="preprocessor">#include "asn.h"</span> 00009 00010 <span class="preprocessor">#include "algebra.cpp"</span> 00011 <span class="preprocessor">#include "eprecomp.cpp"</span> 00012 00013 NAMESPACE_BEGIN(CryptoPP) 00014 00015 <a class="code" href="class_e_c2_n.html">EC2N</a>::<a class="code" href="class_e_c2_n.html">EC2N</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt) 00016 : m_field(BERDecodeGF2NP(bt)) 00017 { 00018 <a class="code" href="class_b_e_r_sequence_decoder.html">BERSequenceDecoder</a> seq(bt); 00019 m_field->BERDecodeElement(seq, m_a); 00020 m_field->BERDecodeElement(seq, m_b); 00021 <span class="comment">// skip optional seed</span> 00022 <span class="keywordflow">if</span> (!seq.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera4">EndReached</a>()) 00023 BERDecodeOctetString(seq, TheBitBucket()); 00024 seq.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00025 } 00026 00027 <span class="keywordtype">void</span> EC2N::DEREncode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00028 <span class="keyword"></span>{ 00029 m_field->DEREncode(bt); 00030 <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> seq(bt); 00031 m_field->DEREncodeElement(seq, m_a); 00032 m_field->DEREncodeElement(seq, m_b); 00033 seq.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00034 } 00035 00036 <span class="keywordtype">bool</span> EC2N::DecodePoint(<a class="code" href="struct_e_c2_n_point.html">EC2N::Point</a> &P, <span class="keyword">const</span> byte *encodedPoint, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> encodedPointLen)<span class="keyword"> const</span> 00037 <span class="keyword"></span>{ 00038 <a class="code" href="class_string_store.html">StringStore</a> store(encodedPoint, encodedPointLen); 00039 <span class="keywordflow">return</span> DecodePoint(P, store, encodedPointLen); 00040 } 00041 00042 <span class="keywordtype">bool</span> EC2N::DecodePoint(<a class="code" href="struct_e_c2_n_point.html">EC2N::Point</a> &P, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> encodedPointLen)<span class="keyword"> const</span> 00043 <span class="keyword"></span>{ 00044 byte type; 00045 <span class="keywordflow">if</span> (encodedPointLen < 1 || !bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(type)) 00046 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00047 00048 <span class="keywordflow">switch</span> (type) 00049 { 00050 <span class="keywordflow">case</span> 0: 00051 P.identity = <span class="keyword">true</span>; 00052 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00053 <span class="keywordflow">case</span> 2: 00054 <span class="keywordflow">case</span> 3: 00055 { 00056 <span class="keywordflow">if</span> (encodedPointLen != EncodedPointSize(<span class="keyword">true</span>)) 00057 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00058 00059 P.identity = <span class="keyword">false</span>; 00060 P.x.Decode(bt, m_field->MaxElementByteLength()); 00061 00062 <span class="keywordflow">if</span> (P.x.IsZero()) 00063 { 00064 P.y = m_field->SquareRoot(m_b); 00065 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00066 } 00067 00068 FieldElement z = m_field->Square(P.x); 00069 assert(P.x == m_field->SquareRoot(z)); 00070 P.y = m_field->Divide(m_field->Add(m_field->Multiply(z, m_field->Add(P.x, m_a)), m_b), z); 00071 assert(P.x == m_field->Subtract(m_field->Divide(m_field->Subtract(m_field->Multiply(P.y, z), m_b), z), m_a)); 00072 z = m_field->SolveQuadraticEquation(P.y); 00073 assert(m_field->Add(m_field->Square(z), z) == P.y); 00074 z.SetCoefficient(0, type & 1); 00075 00076 P.y = m_field->Multiply(z, P.x); 00077 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00078 } 00079 <span class="keywordflow">case</span> 4: 00080 { 00081 <span class="keywordflow">if</span> (encodedPointLen != EncodedPointSize(<span class="keyword">false</span>)) 00082 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00083 00084 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = m_field->MaxElementByteLength(); 00085 P.identity = <span class="keyword">false</span>; 00086 P.x.Decode(bt, len); 00087 P.y.Decode(bt, len); 00088 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00089 } 00090 <span class="keywordflow">default</span>: 00091 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00092 } 00093 } 00094 00095 <span class="keywordtype">void</span> EC2N::EncodePoint(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keyword">const</span> Point &P, <span class="keywordtype">bool</span> compressed)<span class="keyword"> const</span> 00096 <span class="keyword"></span>{ 00097 <span class="keywordflow">if</span> (P.identity) 00098 <a class="code" href="class_null_store.html">NullStore</a>().TransferTo(bt, EncodedPointSize(compressed)); 00099 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (compressed) 00100 { 00101 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(2 + (!P.x ? 0 : m_field->Divide(P.y, P.x).GetBit(0))); 00102 P.x.Encode(bt, m_field->MaxElementByteLength()); 00103 } 00104 <span class="keywordflow">else</span> 00105 { 00106 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = m_field->MaxElementByteLength(); 00107 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(4); <span class="comment">// uncompressed</span> 00108 P.x.Encode(bt, len); 00109 P.y.Encode(bt, len); 00110 } 00111 } 00112 00113 <span class="keywordtype">void</span> EC2N::EncodePoint(byte *encodedPoint, <span class="keyword">const</span> Point &P, <span class="keywordtype">bool</span> compressed)<span class="keyword"> const</span> 00114 <span class="keyword"></span>{ 00115 <a class="code" href="class_array_sink.html">ArraySink</a> sink(encodedPoint, EncodedPointSize(compressed)); 00116 EncodePoint(sink, P, compressed); 00117 assert(sink.<a class="code" href="class_array_sink.html#_array_xor_sinka4">TotalPutLength</a>() == EncodedPointSize(compressed)); 00118 } 00119 00120 <a class="code" href="struct_e_c2_n_point.html">EC2N::Point</a> EC2N::BERDecodePoint(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00121 <span class="keyword"></span>{ 00122 <a class="code" href="class_sec_block.html">SecByteBlock</a> str; 00123 BERDecodeOctetString(bt, str); 00124 Point P; 00125 <span class="keywordflow">if</span> (!DecodePoint(P, str, str.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>())) 00126 BERDecodeError(); 00127 <span class="keywordflow">return</span> P; 00128 } 00129 00130 <span class="keywordtype">void</span> EC2N::DEREncodePoint(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keyword">const</span> Point &P, <span class="keywordtype">bool</span> compressed)<span class="keyword"> const</span> 00131 <span class="keyword"></span>{ 00132 <a class="code" href="class_sec_block.html">SecByteBlock</a> str(EncodedPointSize(compressed)); 00133 EncodePoint(str, P, compressed); 00134 DEREncodeOctetString(bt, str); 00135 } 00136 00137 <span class="keywordtype">bool</span> EC2N::ValidateParameters(<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> 00138 <span class="keyword"></span>{ 00139 <span class="keywordtype">bool</span> pass = !!m_b; 00140 pass = pass && m_a.CoefficientCount() <= m_field->MaxElementBitLength(); 00141 pass = pass && m_b.CoefficientCount() <= m_field->MaxElementBitLength(); 00142 00143 <span class="keywordflow">if</span> (level >= 1) 00144 pass = pass && m_field->GetModulus().IsIrreducible(); 00145 00146 <span class="keywordflow">return</span> pass; 00147 } 00148 00149 <span class="keywordtype">bool</span> EC2N::VerifyPoint(<span class="keyword">const</span> Point &P)<span class="keyword"> const</span> 00150 <span class="keyword"></span>{ 00151 <span class="keyword">const</span> FieldElement &x = P.x, &y = P.y; 00152 <span class="keywordflow">return</span> P.identity || 00153 (x.CoefficientCount() <= m_field->MaxElementBitLength() 00154 && y.CoefficientCount() <= m_field->MaxElementBitLength() 00155 && !(((x+m_a)*x*x+m_b-(x+y)*y)%m_field->GetModulus())); 00156 } 00157 00158 <span class="keywordtype">bool</span> EC2N::Equal(<span class="keyword">const</span> Point &P, <span class="keyword">const</span> Point &Q)<span class="keyword"> const</span> 00159 <span class="keyword"></span>{ 00160 <span class="keywordflow">if</span> (P.identity && Q.identity) 00161 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00162 00163 <span class="keywordflow">if</span> (P.identity && !Q.identity) 00164 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00165 00166 <span class="keywordflow">if</span> (!P.identity && Q.identity) 00167 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00168 00169 <span class="keywordflow">return</span> (m_field->Equal(P.x,Q.x) && m_field->Equal(P.y,Q.y)); 00170 } 00171 00172 <span class="keyword">const</span> <a class="code" href="struct_e_c2_n_point.html">EC2N::Point</a>& EC2N::Identity()<span class="keyword"> const</span> 00173 <span class="keyword"></span>{ 00174 <span class="keywordflow">return</span> <a class="code" href="class_singleton.html">Singleton<Point></a>().Ref(); 00175 } 00176 00177 <span class="keyword">const</span> <a class="code" href="struct_e_c2_n_point.html">EC2N::Point</a>& EC2N::Inverse(<span class="keyword">const</span> Point &P)<span class="keyword"> const</span> 00178 <span class="keyword"></span>{ 00179 <span class="keywordflow">if</span> (P.identity) 00180 <span class="keywordflow">return</span> P; 00181 <span class="keywordflow">else</span> 00182 { 00183 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo0">identity</a> = <span class="keyword">false</span>; 00184 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo2">y</a> = m_field->Add(P.x, P.y); 00185 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a> = P.x; 00186 <span class="keywordflow">return</span> m_R; 00187 } 00188 } 00189 00190 <span class="keyword">const</span> <a class="code" href="struct_e_c2_n_point.html">EC2N::Point</a>& EC2N::Add(<span class="keyword">const</span> Point &P, <span class="keyword">const</span> Point &Q)<span class="keyword"> const</span> 00191 <span class="keyword"></span>{ 00192 <span class="keywordflow">if</span> (P.identity) <span class="keywordflow">return</span> Q; 00193 <span class="keywordflow">if</span> (Q.identity) <span class="keywordflow">return</span> P; 00194 <span class="keywordflow">if</span> (Equal(P, Q)) <span class="keywordflow">return</span> Double(P); 00195 <span class="keywordflow">if</span> (m_field->Equal(P.x, Q.x) && m_field->Equal(P.y, m_field->Add(Q.x, Q.y))) <span class="keywordflow">return</span> Identity(); 00196 00197 FieldElement t = m_field->Add(P.y, Q.y); 00198 t = m_field->Divide(t, m_field->Add(P.x, Q.x)); 00199 FieldElement x = m_field->Square(t); 00200 m_field->Accumulate(x, t); 00201 m_field->Accumulate(x, Q.x); 00202 m_field->Accumulate(x, m_a); 00203 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo2">y</a> = m_field->Add(P.y, m_field->Multiply(t, x)); 00204 m_field->Accumulate(x, P.x); 00205 m_field->Accumulate(m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo2">y</a>, x); 00206 00207 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a>.<a class="code" href="class_polynomial_mod2.html#_polynomial_mod2z25_14">swap</a>(x); 00208 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo0">identity</a> = <span class="keyword">false</span>; 00209 <span class="keywordflow">return</span> m_R; 00210 } 00211 00212 <span class="keyword">const</span> <a class="code" href="struct_e_c2_n_point.html">EC2N::Point</a>& EC2N::Double(<span class="keyword">const</span> Point &P)<span class="keyword"> const</span> 00213 <span class="keyword"></span>{ 00214 <span class="keywordflow">if</span> (P.identity) <span class="keywordflow">return</span> P; 00215 <span class="keywordflow">if</span> (!m_field->IsUnit(P.x)) <span class="keywordflow">return</span> Identity(); 00216 00217 FieldElement t = m_field->Divide(P.y, P.x); 00218 m_field->Accumulate(t, P.x); 00219 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo2">y</a> = m_field->Square(P.x); 00220 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a> = m_field->Square(t); 00221 m_field->Accumulate(m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a>, t); 00222 m_field->Accumulate(m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a>, m_a); 00223 m_field->Accumulate(m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo2">y</a>, m_field->Multiply(t, m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a>)); 00224 m_field->Accumulate(m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo2">y</a>, m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a>); 00225 00226 m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo0">identity</a> = <span class="keyword">false</span>; 00227 <span class="keywordflow">return</span> m_R; 00228 } 00229 00230 <span class="comment">// ********************************************************</span> 00231 00232 <span class="comment">/*</span> 00233 <span class="comment">EcPrecomputation<EC2N>& EcPrecomputation<EC2N>::operator=(const EcPrecomputation<EC2N> &rhs)</span> 00234 <span class="comment">{</span> 00235 <span class="comment"> m_ec = rhs.m_ec;</span> 00236 <span class="comment"> m_ep = rhs.m_ep;</span> 00237 <span class="comment"> m_ep.m_group = m_ec.get();</span> 00238 <span class="comment"> return *this;</span> 00239 <span class="comment">}</span> 00240 <span class="comment"></span> 00241 <span class="comment">void EcPrecomputation<EC2N>::SetCurveAndBase(const EC2N &ec, const EC2N::Point &base)</span> 00242 <span class="comment">{</span> 00243 <span class="comment"> m_ec.reset(new EC2N(ec));</span> 00244 <span class="comment"> m_ep.SetGroupAndBase(*m_ec, base);</span> 00245 <span class="comment">}</span> 00246 <span class="comment"></span> 00247 <span class="comment">void EcPrecomputation<EC2N>::Precompute(unsigned int maxExpBits, unsigned int storage)</span> 00248 <span class="comment">{</span> 00249 <span class="comment"> m_ep.Precompute(maxExpBits, storage);</span> 00250 <span class="comment">}</span> 00251 <span class="comment"></span> 00252 <span class="comment">void EcPrecomputation<EC2N>::Load(BufferedTransformation &bt)</span> 00253 <span class="comment">{</span> 00254 <span class="comment"> BERSequenceDecoder seq(bt);</span> 00255 <span class="comment"> word32 version;</span> 00256 <span class="comment"> BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1);</span> 00257 <span class="comment"> m_ep.m_exponentBase.BERDecode(seq);</span> 00258 <span class="comment"> m_ep.m_windowSize = m_ep.m_exponentBase.BitCount() - 1;</span> 00259 <span class="comment"> m_ep.m_bases.clear();</span> 00260 <span class="comment"> while (!seq.EndReached())</span> 00261 <span class="comment"> m_ep.m_bases.push_back(m_ec->BERDecodePoint(seq));</span> 00262 <span class="comment"> seq.MessageEnd();</span> 00263 <span class="comment">}</span> 00264 <span class="comment"></span> 00265 <span class="comment">void EcPrecomputation<EC2N>::Save(BufferedTransformation &bt) const</span> 00266 <span class="comment">{</span> 00267 <span class="comment"> DERSequenceEncoder seq(bt);</span> 00268 <span class="comment"> DEREncodeUnsigned<word32>(seq, 1); // version</span> 00269 <span class="comment"> m_ep.m_exponentBase.DEREncode(seq);</span> 00270 <span class="comment"> for (unsigned i=0; i<m_ep.m_bases.size(); i++)</span> 00271 <span class="comment"> m_ec->DEREncodePoint(seq, m_ep.m_bases[i]);</span> 00272 <span class="comment"> seq.MessageEnd();</span> 00273 <span class="comment">}</span> 00274 <span class="comment"></span> 00275 <span class="comment">EC2N::Point EcPrecomputation<EC2N>::Exponentiate(const Integer &exponent) const</span> 00276 <span class="comment">{</span> 00277 <span class="comment"> return m_ep.Exponentiate(exponent);</span> 00278 <span class="comment">}</span> 00279 <span class="comment"></span> 00280 <span class="comment">EC2N::Point EcPrecomputation<EC2N>::CascadeExponentiate(const Integer &exponent, const DL_FixedBasePrecomputation<Element> &pc2, const Integer &exponent2) const</span> 00281 <span class="comment">{</span> 00282 <span class="comment"> return m_ep.CascadeExponentiate(exponent, static_cast<const EcPrecomputation<EC2N> &>(pc2).m_ep, exponent2);</span> 00283 <span class="comment">}</span> 00284 <span class="comment">*/</span> 00285 00286 NAMESPACE_END 00287 00288 <span class="preprocessor">#endif</span> </div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:57 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>