5#ifndef CRYPTOPP_IMPORTS
15ANONYMOUS_NAMESPACE_BEGIN
18using CryptoPP::Integer;
19using CryptoPP::ModularArithmetic;
21#if defined(HAVE_GCC_INIT_PRIORITY)
22 #define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 50)))
24#elif defined(HAVE_MSC_INIT_PRIORITY)
25 #pragma warning(disable: 4075)
26 #pragma init_seg(".CRT$XCU")
28 #pragma warning(default: 4075)
29#elif defined(HAVE_XLC_INIT_PRIORITY)
44inline Integer IdentityToInteger(
bool val)
58ANONYMOUS_NAMESPACE_END
60NAMESPACE_BEGIN(CryptoPP)
62ECP::
ECP(const
ECP &ecp,
bool convertToMontgomeryRepresentation)
64 if (convertToMontgomeryRepresentation && !ecp.GetField().IsMontgomeryRepresentation())
67 m_a = GetField().ConvertIn(ecp.m_a);
68 m_b = GetField().ConvertIn(ecp.m_b);
75 : m_fieldPtr(new
Field(bt))
85 BERDecodeBitString(seq, seed, unused);
108 if (encodedPointLen < 1 || !bt.
Get(type))
125 P.x.Decode(bt, GetField().MaxElementByteLength());
126 P.y = ((P.x*P.x+m_a)*P.x+m_b) % p;
128 if (Jacobi(P.y, p) !=1)
131 P.y = ModularSquareRoot(P.y, p);
133 if ((type & 1) != P.y.GetBit(0))
160 bt.
Put((
byte)(2U + P.y.GetBit(0)));
161 P.x.Encode(bt, GetField().MaxElementByteLength());
182 BERDecodeOctetString(bt, str);
193 DEREncodeOctetString(bt, str);
200 bool pass = p.
IsOdd();
204 pass = pass && ((4*m_a*m_a*m_a+27*m_b*m_b)%p).IsPositive();
207 pass = pass && VerifyPrime(rng, p);
217 (!x.IsNegative() && x<p && !y.
IsNegative() && y<p
218 && !(((x*x+m_a)*x+m_b-y*y)%p));
223 if (P.identity && Q.identity)
226 if (P.identity && !Q.identity)
229 if (!P.identity && Q.identity)
232 return (GetField().
Equal(P.x,Q.x) && GetField().
Equal(P.y,Q.y));
237#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY)
239#elif defined(CRYPTOPP_CXX11_STATIC_INIT)
253 m_R.identity =
false;
255 m_R.y = GetField().
Inverse(P.y);
262 if (P.identity)
return Q;
263 if (Q.identity)
return P;
264 if (GetField().
Equal(P.x, Q.x))
270 m_R.y = GetField().
Subtract(GetField().Multiply(t, GetField().
Subtract(P.x, x)), P.y);
273 m_R.identity =
false;
277const ECP::Point& ECP::Double(
const Point &P)
const
281 FieldElement t = GetField().
Square(P.x);
282 t = GetField().
Add(GetField().
Add(GetField().Double(t), t), m_a);
283 t = GetField().
Divide(t, GetField().Double(P.y));
285 m_R.y = GetField().
Subtract(GetField().Multiply(t, GetField().
Subtract(P.x, x)), P.y);
288 m_R.identity =
false;
292template <
class T,
class Iterator>
void ParallelInvert(
const AbstractRing<T> &ring, Iterator begin, Iterator end)
294 size_t n = end-begin;
299 std::vector<T> vec((n+1)/2);
303 for (i=0, it=begin; i<n/2; i++, it+=2)
304 vec[i] = ring.
Multiply(*it, *(it+1));
308 ParallelInvert(ring, vec.begin(), vec.end());
310 for (i=0, it=begin; i<n/2; i++, it+=2)
319 std::swap(*it, *(it+1));
321 *(it+1) = ring.
Multiply(*(it+1), vec[i]);
335 CRYPTOPP_UNUSED(m_b);
338 sixteenY4 = P.x = P.y = mr.MultiplicativeIdentity();
339 aZ4 = P.z = mr.Identity();
345 sixteenY4 = P.z = mr.MultiplicativeIdentity();
352 twoY = mr.Double(P.y);
353 P.z = mr.Multiply(P.z, twoY);
354 fourY2 = mr.Square(twoY);
355 S = mr.Multiply(fourY2, P.x);
356 aZ4 = mr.Multiply(aZ4, sixteenY4);
358 M = mr.Add(mr.Add(mr.Double(M), M), aZ4);
363 P.y = mr.Multiply(M, S);
364 sixteenY4 = mr.Square(fourY2);
365 mr.Reduce(P.y, mr.Half(sixteenY4));
368 const ModularArithmetic &mr;
370 Integer sixteenY4, aZ4, twoY, fourY2, S, M;
376 ZIterator(std::vector<ProjectivePoint>::iterator it) : it(it) {}
377 Integer& operator*() {
return it->z;}
378 int operator-(
ZIterator it2) {
return int(it-it2.it);}
380 ZIterator& operator+=(
int i) {it+=i;
return *
this;}
381 std::vector<ProjectivePoint>::iterator it;
390 ECP::SimultaneousMultiply(&result, P, &k, 1);
396 if (!GetField().IsMontgomeryRepresentation())
398 ECP ecpmr(*
this,
true);
401 for (
unsigned int i=0; i<expCount; i++)
402 results[i] = FromMontgomery(mr, results[i]);
407 std::vector<ProjectivePoint> bases;
408 std::vector<WindowSlider> exponents;
409 exponents.reserve(expCount);
410 std::vector<std::vector<word32> > baseIndices(expCount);
411 std::vector<std::vector<bool> > negateBase(expCount);
412 std::vector<std::vector<word32> > exponentWindows(expCount);
415 for (i=0; i<expCount; i++)
419 exponents[i].FindNextWindow();
422 unsigned int expBitPosition = 0;
428 bool baseAdded =
false;
429 for (i=0; i<expCount; i++)
431 if (!exponents[i].finished && expBitPosition == exponents[i].windowBegin)
435 bases.push_back(rd.P);
439 exponentWindows[i].push_back(exponents[i].expWindow);
440 baseIndices[i].push_back((
word32)bases.size()-1);
441 negateBase[i].push_back(exponents[i].negateNext);
443 exponents[i].FindNextWindow();
445 notDone = notDone || !exponents[i].finished;
457 for (i=0; i<bases.size(); i++)
459 if (bases[i].z.NotZero())
461 bases[i].y = GetField().
Multiply(bases[i].y, bases[i].z);
462 bases[i].z = GetField().
Square(bases[i].z);
463 bases[i].x = GetField().
Multiply(bases[i].x, bases[i].z);
464 bases[i].y = GetField().
Multiply(bases[i].y, bases[i].z);
468 std::vector<BaseAndExponent<Point, Integer> > finalCascade;
469 for (i=0; i<expCount; i++)
471 finalCascade.resize(baseIndices[i].size());
472 for (
unsigned int j=0; j<baseIndices[i].size(); j++)
476 finalCascade[j].base.identity =
true;
479 finalCascade[j].base.identity =
false;
480 finalCascade[j].base.x = base.x;
481 if (negateBase[i][j])
482 finalCascade[j].base.y = GetField().
Inverse(base.y);
484 finalCascade[j].base.y = base.y;
488 results[i] = GeneralCascadeMultiplication(*
this, finalCascade.begin(), finalCascade.end());
494 if (!GetField().IsMontgomeryRepresentation())
496 ECP ecpmr(*
this,
true);
498 return FromMontgomery(mr, ecpmr.CascadeScalarMultiply(ToMontgomery(mr, P), k1, ToMontgomery(mr, Q), k2));
Classes and functions for working with ANS.1 objects.
void BERDecodeError()
Raises a BERDecodeErr.
virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
TODO.
virtual void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
Multiplies a base to multiple exponents in a group.
virtual const Element & Subtract(const Element &a, const Element &b) const
Subtracts elements in the group.
virtual const Element & Multiply(const Element &a, const Element &b) const =0
Multiplies elements in the group.
virtual const Element & MultiplicativeInverse(const Element &a) const =0
Calculate the multiplicative inverse of an element in the group.
Copy input to a memory buffer.
lword TotalPutLength()
Provides the number of bytes written to the Sink.
bool EndReached() const
Determine end of stream.
void MessageEnd()
Signals the end of messages to the object.
void MessageEnd()
Signals the end of messages to the object.
Elliptic Curve over GF(p), where p is prime.
bool InversionIsFast() const
Determine if inversion is fast.
void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const
Encodes an elliptic curve point.
bool Equal(const Point &P, const Point &Q) const
Compare two points.
void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const
DER Encodes an elliptic curve point.
bool VerifyPoint(const Point &P) const
Verifies points on elliptic curve.
unsigned int EncodedPointSize(bool compressed=false) const
Determines encoded point size.
bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const
Decodes an elliptic curve point.
const Point & Inverse(const Point &P) const
Inverts the element in the group.
Point BERDecodePoint(BufferedTransformation &bt) const
BER Decodes an elliptic curve point.
void DEREncode(BufferedTransformation &bt) const
DER Encode.
const Point & Add(const Point &P, const Point &Q) const
Adds elements in the group.
const Point & Identity() const
Provides the Identity element.
Multiple precision integer with arithmetic operations.
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
bool NotNegative() const
Determines if the Integer is non-negative.
static const Integer &CRYPTOPP_API One()
Integer representing 1.
void swap(Integer &a)
Swaps this Integer with another Integer.
bool IsNegative() const
Determines if the Integer is negative.
@ POSITIVE
the value is positive or 0
bool IsOdd() const
Determines if the Integer is odd parity.
Ring of congruence classes modulo n.
const Integer & Square(const Integer &a) const
Square an element in the ring.
const Integer & Inverse(const Integer &a) const
Inverts the element in the ring.
void BERDecodeElement(BufferedTransformation &in, Element &a) const
Decodes element in DER format.
unsigned int MaxElementByteLength() const
Provides the maximum byte size of an element in the ring.
void DEREncodeElement(BufferedTransformation &out, const Element &a) const
Encodes element in DER format.
bool Equal(const Integer &a, const Integer &b) const
Compare two elements for equality.
const Integer & Multiply(const Integer &a, const Integer &b) const
Multiplies elements in the ring.
virtual Integer ConvertOut(const Integer &a) const
Reduces an element in the congruence class.
const Integer & Subtract(const Integer &a, const Integer &b) const
Subtracts elements in the ring.
const Integer & Divide(const Integer &a, const Integer &b) const
Divides elements in the ring.
const Integer & Add(const Integer &a, const Integer &b) const
Adds elements in the ring.
virtual Integer ConvertIn(const Integer &a) const
Reduces an element in the congruence class.
void DEREncode(BufferedTransformation &bt) const
Encodes in DER format.
Performs modular arithmetic in Montgomery representation for increased speed.
Interface for random number generators.
size_type size() const
Provides the count of elements in the SecBlock.
Restricts the instantiation of a class to one static object without locks.
CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
Return a reference to the inner Singleton object.
String-based implementation of Store interface.
unsigned int word32
32-bit unsigned datatype
Classes for Elliptic Curves over prime fields.
Implementation of BufferedTransformation's attachment interface.
Multiple precision integer with arithmetic operations.
Class file for performing modular arithmetic.
Classes and functions for number theoretic operations.
Elliptical Curve Point over GF(p), where p is prime.