5 #ifndef CRYPTOPP_IMPORTS
10 #include "algebra.cpp"
11 #include "eprecomp.cpp"
13 NAMESPACE_BEGIN(CryptoPP)
16 : m_field(BERDecodeGF2NP(bt))
19 m_field->BERDecodeElement(seq, m_a);
20 m_field->BERDecodeElement(seq, m_b);
22 if (!seq.EndReached())
26 BERDecodeBitString(seq, seed, unused);
33 m_field->DEREncode(bt);
35 m_field->DEREncodeElement(seq, m_a);
36 m_field->DEREncodeElement(seq, m_b);
40 bool EC2N::DecodePoint(
EC2N::Point &P,
const byte *encodedPoint,
size_t encodedPointLen)
const
43 return DecodePoint(P, store, encodedPointLen);
49 if (encodedPointLen < 1 || !bt.
Get(type))
60 if (encodedPointLen != EncodedPointSize(
true))
64 P.x.Decode(bt, m_field->MaxElementByteLength());
68 P.y = m_field->SquareRoot(m_b);
72 FieldElement z = m_field->Square(P.x);
73 assert(P.x == m_field->SquareRoot(z));
74 P.y = m_field->Divide(m_field->Add(m_field->Multiply(z, m_field->Add(P.x, m_a)), m_b), z);
75 assert(P.x == m_field->Subtract(m_field->Divide(m_field->Subtract(m_field->Multiply(P.y, z), m_b), z), m_a));
76 z = m_field->SolveQuadraticEquation(P.y);
77 assert(m_field->Add(m_field->Square(z), z) == P.y);
78 z.SetCoefficient(0, type & 1);
80 P.y = m_field->Multiply(z, P.x);
85 if (encodedPointLen != EncodedPointSize(
false))
88 unsigned int len = m_field->MaxElementByteLength();
105 bt.
Put(2 + (!P.x ? 0 : m_field->Divide(P.y, P.x).GetBit(0)));
106 P.x.Encode(bt, m_field->MaxElementByteLength());
110 unsigned int len = m_field->MaxElementByteLength();
117 void EC2N::EncodePoint(byte *encodedPoint,
const Point &P,
bool compressed)
const
119 ArraySink sink(encodedPoint, EncodedPointSize(compressed));
120 EncodePoint(sink, P, compressed);
121 assert(sink.TotalPutLength() == EncodedPointSize(compressed));
127 BERDecodeOctetString(bt, str);
129 if (!DecodePoint(P, str, str.size()))
137 EncodePoint(str, P, compressed);
138 DEREncodeOctetString(bt, str);
144 pass = pass && m_a.CoefficientCount() <= m_field->MaxElementBitLength();
145 pass = pass && m_b.CoefficientCount() <= m_field->MaxElementBitLength();
148 pass = pass && m_field->GetModulus().IsIrreducible();
153 bool EC2N::VerifyPoint(
const Point &P)
const
155 const FieldElement &x = P.x, &y = P.y;
157 (x.CoefficientCount() <= m_field->MaxElementBitLength()
158 && y.CoefficientCount() <= m_field->MaxElementBitLength()
159 && !(((x+m_a)*x*x+m_b-(x+y)*y)%m_field->GetModulus()));
162 bool EC2N::Equal(
const Point &P,
const Point &Q)
const
164 if (P.identity && Q.identity)
167 if (P.identity && !Q.identity)
170 if (!P.identity && Q.identity)
173 return (m_field->Equal(P.x,Q.x) && m_field->Equal(P.y,Q.y));
181 const EC2N::Point& EC2N::Inverse(
const Point &P)
const
187 m_R.identity =
false;
188 m_R.y = m_field->Add(P.x, P.y);
194 const EC2N::Point& EC2N::Add(
const Point &P,
const Point &Q)
const
196 if (P.identity)
return Q;
197 if (Q.identity)
return P;
198 if (Equal(P, Q))
return Double(P);
199 if (m_field->Equal(P.x, Q.x) && m_field->Equal(P.y, m_field->Add(Q.x, Q.y)))
return Identity();
201 FieldElement t = m_field->Add(P.y, Q.y);
202 t = m_field->Divide(t, m_field->Add(P.x, Q.x));
203 FieldElement x = m_field->Square(t);
204 m_field->Accumulate(x, t);
205 m_field->Accumulate(x, Q.x);
206 m_field->Accumulate(x, m_a);
207 m_R.y = m_field->Add(P.y, m_field->Multiply(t, x));
208 m_field->Accumulate(x, P.x);
209 m_field->Accumulate(m_R.y, x);
212 m_R.identity =
false;
216 const EC2N::Point& EC2N::Double(
const Point &P)
const
218 if (P.identity)
return P;
219 if (!m_field->IsUnit(P.x))
return Identity();
221 FieldElement t = m_field->Divide(P.y, P.x);
222 m_field->Accumulate(t, P.x);
223 m_R.y = m_field->Square(P.x);
224 m_R.x = m_field->Square(t);
225 m_field->Accumulate(m_R.x, t);
226 m_field->Accumulate(m_R.x, m_a);
227 m_field->Accumulate(m_R.y, m_field->Multiply(t, m_R.x));
228 m_field->Accumulate(m_R.y, m_R.x);
230 m_R.identity =
false;