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
62ECP::ECP(
const ECP &ecp,
bool convertToMontgomeryRepresentation)
75 : m_fieldPtr(new Field(bt))
78 GetField().BERDecodeElement(seq, m_a);
79 GetField().BERDecodeElement(seq, m_b);
81 if (!seq.EndReached())
108 if (encodedPointLen < 1 || !bt.
Get(type))
129 P.x.Decode(bt, GetField().MaxElementByteLength());
130 P.y = ((P.x*P.x+m_a)*P.x+m_b) % p;
137 if ((type & 1) != P.y.GetBit(0))
164 bt.
Put((
byte)(2U + P.y.GetBit(0)));
165 P.x.Encode(bt, GetField().MaxElementByteLength());
176void ECP::EncodePoint(
byte *encodedPoint,
const Point &P,
bool compressed)
const
204 bool pass = p.
IsOdd();
208 pass = pass && ((4*m_a*m_a*m_a+27*m_b*m_b)%p).IsPositive();
218 const FieldElement &x = P.x, &y = P.y;
221 (!x.IsNegative() && x<p && !y.
IsNegative() && y<p
222 && !(((x*x+m_a)*x+m_b-y*y)%p));
225bool ECP::Equal(
const Point &P,
const Point &Q)
const
227 if (P.identity && Q.identity)
230 if (P.identity && !Q.identity)
233 if (!P.identity && Q.identity)
236 return (GetField().
Equal(P.x,Q.x) && GetField().
Equal(P.y,Q.y));
241#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY)
243#elif defined(CRYPTOPP_CXX11_STATIC_INIT)
257 m_R.identity =
false;
259 m_R.y = GetField().
Inverse(P.y);
266 if (P.identity)
return Q;
267 if (Q.identity)
return P;
268 if (GetField().
Equal(P.x, Q.x))
271 FieldElement t = GetField().
Subtract(Q.y, P.y);
274 m_R.y = GetField().
Subtract(GetField().Multiply(t, GetField().
Subtract(P.x, x)), P.y);
277 m_R.identity =
false;
285 FieldElement t = GetField().
Square(P.x);
286 t = GetField().
Add(GetField().
Add(GetField().
Double(t), t), m_a);
289 m_R.y = GetField().
Subtract(GetField().Multiply(t, GetField().
Subtract(P.x, x)), P.y);
292 m_R.identity =
false;
296template <
class T,
class Iterator>
void ParallelInvert(
const AbstractRing<T> &ring, Iterator begin, Iterator end)
298 size_t n = end-begin;
303 std::vector<T> vec((n+1)/2);
307 for (i=0, it=begin; i<n/2; i++, it+=2)
308 vec[i] = ring.
Multiply(*it, *(it+1));
312 ParallelInvert(ring, vec.begin(), vec.end());
314 for (i=0, it=begin; i<n/2; i++, it+=2)
323 std::swap(*it, *(it+1));
325 *(it+1) = ring.
Multiply(*(it+1), vec[i]);
333class ProjectiveDoubling
339 CRYPTOPP_UNUSED(m_b);
342 sixteenY4 = P.x = P.y = mr.MultiplicativeIdentity();
343 aZ4 = P.z = mr.Identity();
349 sixteenY4 = P.z = mr.MultiplicativeIdentity();
356 twoY = mr.Double(P.y);
357 P.z = mr.Multiply(P.z, twoY);
358 fourY2 = mr.Square(twoY);
359 S = mr.Multiply(fourY2, P.x);
360 aZ4 = mr.Multiply(aZ4, sixteenY4);
362 M = mr.Add(mr.Add(mr.Double(M), M), aZ4);
367 P.y = mr.Multiply(M, S);
368 sixteenY4 = mr.Square(fourY2);
369 mr.Reduce(P.y, mr.Half(sixteenY4));
374 Integer sixteenY4, aZ4, twoY, fourY2, S, M;
380 ZIterator(std::vector<ProjectivePoint>::iterator it) : it(it) {}
381 Integer& operator*() {
return it->z;}
382 int operator-(ZIterator it2) {
return int(it-it2.it);}
383 ZIterator
operator+(
int i) {
return ZIterator(it+i);}
384 ZIterator& operator+=(
int i) {it+=i;
return *
this;}
385 std::vector<ProjectivePoint>::iterator it;
400 if (!GetField().IsMontgomeryRepresentation())
402 ECP ecpmr(*
this,
true);
405 for (
unsigned int i=0; i<expCount; i++)
406 results[i] = FromMontgomery(mr, results[i]);
410 ProjectiveDoubling rd(GetField(), m_a, m_b, P);
411 std::vector<ProjectivePoint> bases;
412 std::vector<WindowSlider> exponents;
413 exponents.reserve(expCount);
414 std::vector<std::vector<word32> > baseIndices(expCount);
415 std::vector<std::vector<bool> > negateBase(expCount);
416 std::vector<std::vector<word32> > exponentWindows(expCount);
419 for (i=0; i<expCount; i++)
423 exponents[i].FindNextWindow();
426 unsigned int expBitPosition = 0;
432 bool baseAdded =
false;
433 for (i=0; i<expCount; i++)
435 if (!exponents[i].finished && expBitPosition == exponents[i].windowBegin)
439 bases.push_back(rd.P);
443 exponentWindows[i].push_back(exponents[i].expWindow);
444 baseIndices[i].push_back((
word32)bases.size()-1);
445 negateBase[i].push_back(exponents[i].negateNext);
447 exponents[i].FindNextWindow();
449 notDone = notDone || !exponents[i].finished;
460 ParallelInvert(GetField(), ZIterator(bases.begin()), ZIterator(bases.end()));
461 for (i=0; i<bases.size(); i++)
463 if (bases[i].z.NotZero())
465 bases[i].y = GetField().
Multiply(bases[i].y, bases[i].z);
466 bases[i].z = GetField().
Square(bases[i].z);
467 bases[i].x = GetField().
Multiply(bases[i].x, bases[i].z);
468 bases[i].y = GetField().
Multiply(bases[i].y, bases[i].z);
472 std::vector<BaseAndExponent<Point, Integer> > finalCascade;
473 for (i=0; i<expCount; i++)
475 finalCascade.resize(baseIndices[i].size());
476 for (
unsigned int j=0; j<baseIndices[i].size(); j++)
478 ProjectivePoint &base = bases[baseIndices[i][j]];
480 finalCascade[j].base.identity =
true;
483 finalCascade[j].base.identity =
false;
484 finalCascade[j].base.x = base.x;
485 if (negateBase[i][j])
486 finalCascade[j].base.y = GetField().
Inverse(base.y);
488 finalCascade[j].base.y = base.y;
492 results[i] = GeneralCascadeMultiplication(*
this, finalCascade.begin(), finalCascade.end());
498 if (!GetField().IsMontgomeryRepresentation())
500 ECP ecpmr(*
this,
true);
502 return FromMontgomery(mr, ecpmr.CascadeScalarMultiply(ToMontgomery(mr, P), k1, ToMontgomery(mr, Q), k2));
Classes and functions for working with ANS.1 objects.
CRYPTOPP_DLL size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
OID operator+(const OID &lhs, unsigned long rhs)
Append a value to an OID.
CRYPTOPP_DLL size_t DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen)
DER encode octet string.
CRYPTOPP_DLL size_t BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
BER decode octet string.
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.
Elliptic Curve over GF(p), where p is prime.
bool InversionIsFast() const
Determine if inversion is fast.
const Point & Double(const Point &P) const
Doubles an element in the group.
Point ScalarMultiply(const Point &P, const Integer &k) const
Performs a scalar multiplication.
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.
Point CascadeScalarMultiply(const Point &P, const Integer &k1, const Point &Q, const Integer &k2) const
TODO.
const Point & Inverse(const Point &P) const
Inverts the element in the group.
const Point & Identity() const
Provides the Identity element.
Point BERDecodePoint(BufferedTransformation &bt) const
BER Decodes an elliptic curve point.
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.
void DEREncode(BufferedTransformation &bt) const
DER Encode.
const Point & Add(const Point &P, const Point &Q) const
Adds elements in the group.
void SimultaneousMultiply(Point *results, const Point &base, const Integer *exponents, unsigned int exponentsCount) const
Multiplies a base to multiple exponents in a group.
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.
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.
static const Integer & One()
Integer representing 1.
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.
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.
virtual bool IsMontgomeryRepresentation() const
Retrieves the representation.
bool Equal(const Integer &a, const Integer &b) const
Compare two elements for equality.
const Integer & GetModulus() const
Retrieves the modulus.
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.
const T & Ref(...) 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.
Crypto++ library namespace.
Classes and functions for number theoretic operations.
CRYPTOPP_DLL int Jacobi(const Integer &a, const Integer &b)
Calculate the Jacobi symbol.
CRYPTOPP_DLL bool IsPrime(const Integer &p)
Verifies a number is probably prime.
CRYPTOPP_DLL Integer ModularSquareRoot(const Integer &a, const Integer &p)
Extract a modular square root.
CRYPTOPP_DLL bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level=1)
Verifies a number is probably prime.
Elliptical Curve Point over GF(p), where p is prime.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.