Sophie

Sophie

distrib > Mandriva > 10.2 > i586 > media > contrib > by-pkgid > 7457b841ac8136d3a1a9d3d960c5252e > files > 1221

libcryptopp-doc-5.2.1-2mdk.i586.rpm

<!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&nbsp;Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class&nbsp;Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical&nbsp;List</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="namespacemembers.html">Namespace&nbsp;Members</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="globals.html">File&nbsp;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> &amp;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-&gt;BERDecodeElement(seq, m_a);
00020         m_field-&gt;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> &amp;bt)<span class="keyword"> const</span>
00028 <span class="keyword"></span>{
00029         m_field-&gt;DEREncode(bt);
00030         <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> seq(bt);
00031         m_field-&gt;DEREncodeElement(seq, m_a);
00032         m_field-&gt;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> &amp;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> &amp;P, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &amp;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 &lt; 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-&gt;MaxElementByteLength()); 
00061 
00062                 <span class="keywordflow">if</span> (P.x.IsZero())
00063                 {
00064                         P.y = m_field-&gt;SquareRoot(m_b);
00065                         <span class="keywordflow">return</span> <span class="keyword">true</span>;
00066                 }
00067 
00068                 FieldElement z = m_field-&gt;Square(P.x);
00069                 assert(P.x == m_field-&gt;SquareRoot(z));
00070                 P.y = m_field-&gt;Divide(m_field-&gt;Add(m_field-&gt;Multiply(z, m_field-&gt;Add(P.x, m_a)), m_b), z);
00071                 assert(P.x == m_field-&gt;Subtract(m_field-&gt;Divide(m_field-&gt;Subtract(m_field-&gt;Multiply(P.y, z), m_b), z), m_a));
00072                 z = m_field-&gt;SolveQuadraticEquation(P.y);
00073                 assert(m_field-&gt;Add(m_field-&gt;Square(z), z) == P.y);
00074                 z.SetCoefficient(0, type &amp; 1);
00075 
00076                 P.y = m_field-&gt;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-&gt;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> &amp;bt, <span class="keyword">const</span> Point &amp;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-&gt;Divide(P.y, P.x).GetBit(0)));
00102                 P.x.Encode(bt, m_field-&gt;MaxElementByteLength());
00103         }
00104         <span class="keywordflow">else</span>
00105         {
00106                 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len = m_field-&gt;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 &amp;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> &amp;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> &amp;bt, <span class="keyword">const</span> Point &amp;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> &amp;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 &amp;&amp; m_a.CoefficientCount() &lt;= m_field-&gt;MaxElementBitLength();
00141         pass = pass &amp;&amp; m_b.CoefficientCount() &lt;= m_field-&gt;MaxElementBitLength();
00142 
00143         <span class="keywordflow">if</span> (level &gt;= 1)
00144                 pass = pass &amp;&amp; m_field-&gt;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 &amp;P)<span class="keyword"> const</span>
00150 <span class="keyword"></span>{
00151         <span class="keyword">const</span> FieldElement &amp;x = P.x, &amp;y = P.y;
00152         <span class="keywordflow">return</span> P.identity || 
00153                 (x.CoefficientCount() &lt;= m_field-&gt;MaxElementBitLength()
00154                 &amp;&amp; y.CoefficientCount() &lt;= m_field-&gt;MaxElementBitLength()
00155                 &amp;&amp; !(((x+m_a)*x*x+m_b-(x+y)*y)%m_field-&gt;GetModulus()));
00156 }
00157 
00158 <span class="keywordtype">bool</span> EC2N::Equal(<span class="keyword">const</span> Point &amp;P, <span class="keyword">const</span> Point &amp;Q)<span class="keyword"> const</span>
00159 <span class="keyword"></span>{
00160         <span class="keywordflow">if</span> (P.identity &amp;&amp; Q.identity)
00161                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
00162 
00163         <span class="keywordflow">if</span> (P.identity &amp;&amp; !Q.identity)
00164                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00165 
00166         <span class="keywordflow">if</span> (!P.identity &amp;&amp; Q.identity)
00167                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
00168 
00169         <span class="keywordflow">return</span> (m_field-&gt;Equal(P.x,Q.x) &amp;&amp; m_field-&gt;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>&amp; 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&lt;Point&gt;</a>().Ref();
00175 }
00176 
00177 <span class="keyword">const</span> <a class="code" href="struct_e_c2_n_point.html">EC2N::Point</a>&amp; EC2N::Inverse(<span class="keyword">const</span> Point &amp;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-&gt;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>&amp; EC2N::Add(<span class="keyword">const</span> Point &amp;P, <span class="keyword">const</span> Point &amp;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-&gt;Equal(P.x, Q.x) &amp;&amp; m_field-&gt;Equal(P.y, m_field-&gt;Add(Q.x, Q.y))) <span class="keywordflow">return</span> Identity();
00196 
00197         FieldElement t = m_field-&gt;Add(P.y, Q.y);
00198         t = m_field-&gt;Divide(t, m_field-&gt;Add(P.x, Q.x));
00199         FieldElement x = m_field-&gt;Square(t);
00200         m_field-&gt;Accumulate(x, t);
00201         m_field-&gt;Accumulate(x, Q.x);
00202         m_field-&gt;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-&gt;Add(P.y, m_field-&gt;Multiply(t, x));
00204         m_field-&gt;Accumulate(x, P.x);
00205         m_field-&gt;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>&amp; EC2N::Double(<span class="keyword">const</span> Point &amp;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-&gt;IsUnit(P.x)) <span class="keywordflow">return</span> Identity();
00216 
00217         FieldElement t = m_field-&gt;Divide(P.y, P.x);
00218         m_field-&gt;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-&gt;Square(P.x);
00220         m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a> = m_field-&gt;Square(t);
00221         m_field-&gt;Accumulate(m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a>, t);
00222         m_field-&gt;Accumulate(m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a>, m_a);
00223         m_field-&gt;Accumulate(m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo2">y</a>, m_field-&gt;Multiply(t, m_R.<a class="code" href="struct_e_c2_n_point.html#_e_c2_n_pointo1">x</a>));
00224         m_field-&gt;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&lt;EC2N&gt;&amp; EcPrecomputation&lt;EC2N&gt;::operator=(const EcPrecomputation&lt;EC2N&gt; &amp;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&lt;EC2N&gt;::SetCurveAndBase(const EC2N &amp;ec, const EC2N::Point &amp;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&lt;EC2N&gt;::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&lt;EC2N&gt;::Load(BufferedTransformation &amp;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&lt;word32&gt;(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-&gt;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&lt;EC2N&gt;::Save(BufferedTransformation &amp;bt) const</span>
00266 <span class="comment">{</span>
00267 <span class="comment">        DERSequenceEncoder seq(bt);</span>
00268 <span class="comment">        DEREncodeUnsigned&lt;word32&gt;(seq, 1);      // version</span>
00269 <span class="comment">        m_ep.m_exponentBase.DEREncode(seq);</span>
00270 <span class="comment">        for (unsigned i=0; i&lt;m_ep.m_bases.size(); i++)</span>
00271 <span class="comment">                m_ec-&gt;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&lt;EC2N&gt;::Exponentiate(const Integer &amp;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&lt;EC2N&gt;::CascadeExponentiate(const Integer &amp;exponent, const DL_FixedBasePrecomputation&lt;Element&gt; &amp;pc2, const Integer &amp;exponent2) const</span>
00281 <span class="comment">{</span>
00282 <span class="comment">        return m_ep.CascadeExponentiate(exponent, static_cast&lt;const EcPrecomputation&lt;EC2N&gt; &amp;&gt;(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>