5 #ifndef CRYPTOPP_IMPORTS 13 #include "algebra.cpp" 15 ANONYMOUS_NAMESPACE_BEGIN
18 using CryptoPP::Integer;
19 using 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) 44 inline Integer IdentityToInteger(
bool val)
49 struct ProjectivePoint
61 struct AdditionFunction
63 explicit AdditionFunction(
const ECP::Field& field,
110 AdditionFunction::AdditionFunction(
const ECP::Field& field,
112 : field(field), a(a), b(b), R(r), m_alpha(static_cast<Alpha>(0))
116 m_alpha = A_Montgomery;
124 else if (a == -3 || (a - field.
GetModulus()) == -3)
141 const Integer x = P.x * IdentityToInteger(!P.identity);
142 const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
143 const Integer z = 1 * IdentityToInteger(!P.identity);
145 ProjectivePoint p(x, y, z), r;
151 t3 = field.
Add(t3, t3);
153 Z3 = field.
Add(Z3, Z3);
156 X3 = field.
Add(Y3, Y3);
157 Y3 = field.
Add(X3, Y3);
159 Y3 = field.
Add(t1, Y3);
162 t3 = field.
Add(t2, t2);
163 t2 = field.
Add(t2, t3);
167 t3 = field.
Add(Z3, Z3);
168 Z3 = field.
Add(Z3, t3);
169 t3 = field.
Add(t0, t0);
170 t0 = field.
Add(t3, t0);
173 Y3 = field.
Add(Y3, t0);
175 t0 = field.
Add(t0, t0);
179 Z3 = field.
Add(Z3, Z3);
180 Z3 = field.
Add(Z3, Z3);
186 R.x = X3*Z3.NotZero();
187 R.y = Y3*Z3.NotZero();
188 R.identity = Z3.IsZero();
192 else if (m_alpha == A_0)
196 const Integer x = P.x * IdentityToInteger(!P.identity);
197 const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
198 const Integer z = 1 * IdentityToInteger(!P.identity);
200 ProjectivePoint p(x, y, z), r;
204 Z3 = field.
Add(t0, t0);
205 Z3 = field.
Add(Z3, Z3);
206 Z3 = field.
Add(Z3, Z3);
211 Y3 = field.
Add(t0, t2);
213 t1 = field.
Add(t2, t2);
214 t2 = field.
Add(t1, t2);
217 Y3 = field.
Add(X3, Y3);
220 X3 = field.
Add(X3, X3);
226 R.x = X3*Z3.NotZero();
227 R.y = Y3*Z3.NotZero();
228 R.identity = Z3.IsZero();
234 else if (m_alpha == A_Star)
238 const Integer x = P.x * IdentityToInteger(!P.identity);
239 const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
240 const Integer z = 1 * IdentityToInteger(!P.identity);
242 ProjectivePoint p(x, y, z), r;
246 Z3 = field.
Add(t0, t0);
247 Z3 = field.
Add(Z3, Z3);
248 Z3 = field.
Add(Z3, Z3);
253 Y3 = field.
Add(t0, t2);
255 t1 = field.
Add(t2, t2);
256 t2 = field.
Add(t1, t2);
259 Y3 = field.
Add(X3, Y3);
262 X3 = field.
Add(X3, X3);
268 R.x = X3*Z3.NotZero();
269 R.y = Y3*Z3.NotZero();
270 R.identity = Z3.IsZero();
278 bool identity = !!(P.identity + (P.y == field.
Identity()));
288 R.x *= IdentityToInteger(!identity);
289 R.y *= IdentityToInteger(!identity);
290 R.identity = identity;
302 const Integer x1 = P.x * IdentityToInteger(!P.identity);
303 const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
304 const Integer z1 = 1 * IdentityToInteger(!P.identity);
306 const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
307 const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
308 const Integer z2 = 1 * IdentityToInteger(!Q.identity);
310 ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
318 t4 = field.
Add(t0, t1);
320 t4 = field.
Add(Y1, Z1);
321 X3 = field.
Add(Y2, Z2);
323 X3 = field.
Add(t1, t2);
325 X3 = field.
Add(X1, Z1);
326 Y3 = field.
Add(X2, Z2);
328 Y3 = field.
Add(t0, t2);
332 Z3 = field.
Add(X3, X3);
333 X3 = field.
Add(X3, Z3);
335 X3 = field.
Add(t1, X3);
337 t1 = field.
Add(t2, t2);
338 t2 = field.
Add(t1, t2);
341 t1 = field.
Add(Y3, Y3);
342 Y3 = field.
Add(t1, Y3);
343 t1 = field.
Add(t0, t0);
344 t0 = field.
Add(t1, t0);
349 Y3 = field.
Add(Y3, t2);
354 Z3 = field.
Add(Z3, t1);
360 R.x = X3*Z3.NotZero();
361 R.y = Y3*Z3.NotZero();
362 R.identity = Z3.IsZero();
366 else if (m_alpha == A_0)
370 const Integer x1 = P.x * IdentityToInteger(!P.identity);
371 const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
372 const Integer z1 = 1 * IdentityToInteger(!P.identity);
374 const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
375 const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
376 const Integer z2 = 1 * IdentityToInteger(!Q.identity);
378 ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
382 Z3 = field.
Add(t0, t0);
383 Z3 = field.
Add(Z3, Z3);
384 Z3 = field.
Add(Z3, Z3);
389 Y3 = field.
Add(t0, t2);
391 t1 = field.
Add(t2, t2);
392 t2 = field.
Add(t1, t2);
395 Y3 = field.
Add(X3, Y3);
398 X3 = field.
Add(X3, X3);
404 R.x = X3*Z3.NotZero();
405 R.y = Y3*Z3.NotZero();
406 R.identity = Z3.IsZero();
412 else if (m_alpha == A_Star)
416 const Integer x1 = P.x * IdentityToInteger(!P.identity);
417 const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
418 const Integer z1 = 1 * IdentityToInteger(!P.identity);
420 const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
421 const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
422 const Integer z2 = 1 * IdentityToInteger(!Q.identity);
424 ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
433 t4 = field.
Add(t0, t1);
435 t4 = field.
Add(X1, Z1);
438 t5 = field.
Add(t0, t2);
440 t5 = field.
Add(Y1, Z1);
441 X3 = field.
Add(Y2, Z2);
443 X3 = field.
Add(t1, t2);
447 Z3 = field.
Add(X3, Z3);
449 Z3 = field.
Add(t1, Z3);
451 t1 = field.
Add(t0, t0);
452 t1 = field.
Add(t1, t0);
455 t1 = field.
Add(t1, t2);
458 t4 = field.
Add(t4, t2);
460 Y3 = field.
Add(Y3, t0);
466 Z3 = field.
Add(Z3, t0);
472 R.x = X3*Z3.NotZero();
473 R.y = Y3*Z3.NotZero();
474 R.identity = Z3.IsZero();
482 bool return_Q = P.identity;
483 bool return_P = Q.identity;
484 bool double_P = field.
Equal(P.x, Q.x) && field.
Equal(P.y, Q.y);
485 bool identity = field.
Equal(P.x, Q.x) && !field.
Equal(P.y, Q.y);
488 identity = !!((double_P * (P.identity + (P.y == field.
Identity()))) + identity);
512 R.x = R.x * IdentityToInteger(!identity);
513 R.y = R.y * IdentityToInteger(!identity);
514 R.identity = identity;
541 ANONYMOUS_NAMESPACE_END
545 ECP::
ECP(const
ECP &ecp,
bool convertToMontgomeryRepresentation)
547 if (convertToMontgomeryRepresentation && !ecp.GetField().IsMontgomeryRepresentation())
550 m_a = GetField().ConvertIn(ecp.m_a);
551 m_b = GetField().ConvertIn(ecp.m_b);
558 : m_fieldPtr(new
Field(bt))
591 if (encodedPointLen < 1 || !bt.
Get(type))
608 P.x.
Decode(bt, GetField().MaxElementByteLength());
609 P.y = ((P.x*P.x+m_a)*P.x+m_b) % p;
616 if ((type & 1) != P.y.
GetBit(0))
644 P.x.
Encode(bt, GetField().MaxElementByteLength());
683 bool pass = p.
IsOdd();
687 pass = pass && ((4*m_a*m_a*m_a+27*m_b*m_b)%p).
IsPositive();
701 && !(((x*x+m_a)*x+m_b-y*y)%p));
706 if (P.identity && Q.identity)
709 if (P.identity && !Q.identity)
712 if (!P.identity && Q.identity)
715 return (GetField().
Equal(P.x,Q.x) && GetField().
Equal(P.y,Q.y));
720 #if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY) 722 #elif defined(CRYPTOPP_CXX11_STATIC_INIT) 736 m_R.identity =
false;
738 m_R.y = GetField().
Inverse(P.y);
745 AdditionFunction add(GetField(), m_a, m_b, m_R);
746 return (m_R = add(P, Q));
751 AdditionFunction add(GetField(), m_a, m_b, m_R);
752 return (m_R = add(P));
755 template <
class T,
class Iterator>
void ParallelInvert(
const AbstractRing<T> &ring, Iterator begin, Iterator end)
757 size_t n = end-begin;
762 std::vector<T> vec((n+1)/2);
766 for (i=0, it=begin; i<n/2; i++, it+=2)
767 vec[i] = ring.
Multiply(*it, *(it+1));
771 ParallelInvert(ring, vec.begin(), vec.end());
773 for (i=0, it=begin; i<n/2; i++, it+=2)
784 *(it+1) = ring.
Multiply(*(it+1), vec[i]);
798 CRYPTOPP_UNUSED(m_b);
827 sixteenY4 = mr.
Square(fourY2);
833 Integer sixteenY4, aZ4, twoY, fourY2, S, M;
839 ZIterator(std::vector<ProjectivePoint>::iterator it) : it(it) {}
843 ZIterator& operator+=(
int i) {it+=i;
return *
this;}
844 std::vector<ProjectivePoint>::iterator it;
859 if (!GetField().IsMontgomeryRepresentation())
861 ECP ecpmr(*
this,
true);
864 for (
unsigned int i=0; i<expCount; i++)
865 results[i] = FromMontgomery(mr, results[i]);
870 std::vector<ProjectivePoint> bases;
871 std::vector<WindowSlider> exponents;
872 exponents.reserve(expCount);
873 std::vector<std::vector<word32> > baseIndices(expCount);
874 std::vector<std::vector<bool> > negateBase(expCount);
875 std::vector<std::vector<word32> > exponentWindows(expCount);
878 for (i=0; i<expCount; i++)
882 exponents[i].FindNextWindow();
885 unsigned int expBitPosition = 0;
891 bool baseAdded =
false;
892 for (i=0; i<expCount; i++)
894 if (!exponents[i].finished && expBitPosition == exponents[i].windowBegin)
898 bases.push_back(rd.P);
902 exponentWindows[i].push_back(exponents[i].expWindow);
903 baseIndices[i].push_back((word32)bases.size()-1);
904 negateBase[i].push_back(exponents[i].negateNext);
906 exponents[i].FindNextWindow();
908 notDone = notDone || !exponents[i].finished;
920 for (i=0; i<bases.size(); i++)
924 bases[i].y = GetField().Multiply(bases[i].y, bases[i].z);
925 bases[i].z = GetField().Square(bases[i].z);
926 bases[i].x = GetField().Multiply(bases[i].x, bases[i].z);
927 bases[i].y = GetField().Multiply(bases[i].y, bases[i].z);
931 std::vector<BaseAndExponent<Point, Integer> > finalCascade;
932 for (i=0; i<expCount; i++)
934 finalCascade.resize(baseIndices[i].size());
935 for (
unsigned int j=0; j<baseIndices[i].size(); j++)
937 ProjectivePoint &base = bases[baseIndices[i][j]];
939 finalCascade[j].base.identity =
true;
942 finalCascade[j].base.identity =
false;
943 finalCascade[j].base.x = base.x;
944 if (negateBase[i][j])
945 finalCascade[j].base.y = GetField().Inverse(base.y);
947 finalCascade[j].base.y = base.y;
951 results[i] = GeneralCascadeMultiplication(*
this, finalCascade.begin(), finalCascade.end());
957 if (!GetField().IsMontgomeryRepresentation())
959 ECP ecpmr(*
this,
true);
961 return FromMontgomery(mr, ecpmr.
CascadeScalarMultiply(ToMontgomery(mr, P), k1, ToMontgomery(mr, Q), k2));
const Integer & Double(const Integer &a) const
Doubles an element in the ring.
bool VerifyPoint(const Point &P) const
Verifies points on elliptic curve.
Integer & Reduce(Integer &a, const Integer &b) const
TODO.
bool NotZero() const
Determines if the Integer is non-0.
inline ::Integer operator*(const ::Integer &a, const ::Integer &b)
Multiplication.
bool Equal(const Integer &a, const Integer &b) const
Compare two elements for equality.
const Integer & Square(const Integer &a) const
Square an element in the ring.
const Integer & Divide(const Integer &a, const Integer &b) const
Divides elements in the ring.
Restricts the instantiation of a class to one static object without locks.
Elliptical Curve Point over GF(p), where p is prime.
virtual const Element & Multiply(const Element &a, const Element &b) const =0
Multiplies elements in the group.
Classes for Elliptic Curves over prime fields.
void MessageEnd()
Signals the end of messages to the object.
Elliptic Curve over GF(p), where p is prime.
virtual Integer ConvertOut(const Integer &a) const
Reduces an element in the congruence class.
const Integer & Inverse(const Integer &a) const
Inverts the element in the ring.
bool InversionIsFast() const
Determine if inversion is fast.
const Integer & Subtract(const Integer &a, const Integer &b) const
Subtracts elements in the ring.
const Integer & MultiplicativeInverse(const Integer &a) const
Calculate the multiplicative inverse of an element in the ring.
unsigned int MaxElementByteLength() const
Provides the maximum byte size of an element in the ring.
bool IsNegative() const
Determines if the Integer is negative.
CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen)
DER encode octet string.
Ring of congruence classes modulo n.
Interface for random number generators.
bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const
Decodes an elliptic curve point.
bool IsPositive() const
Determines if the Integer is positive.
bool NotNegative() const
Determines if the Integer is non-negative.
virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const
TODO.
const Integer & Add(const Integer &a, const Integer &b) const
Adds elements in the ring.
static const Integer &CRYPTOPP_API One()
Integer representing 1.
const Integer & Identity() const
Provides the Identity element.
const Point & Identity() const
Provides the Identity element.
void DEREncodeElement(BufferedTransformation &out, const Element &a) const
Encodes element in DER format.
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.
Copy input to a memory buffer.
inline ::Integer operator-(const ::Integer &a, const ::Integer &b)
Subtraction.
void BERDecodeElement(BufferedTransformation &in, Element &a) const
Decodes element in DER format.
bool EndReached() const
Determine end of stream.
Point ScalarMultiply(const Point &P, const Integer &k) const
Performs a scalar multiplication.
const Integer & Multiply(const Integer &a, const Integer &b) const
Multiplies elements in the ring.
bool Equal(const Point &P, const Point &Q) const
Compare two points.
CRYPTOPP_DLL Integer CRYPTOPP_API ModularSquareRoot(const Integer &a, const Integer &p)
Extract a modular square root.
virtual const Element & MultiplicativeInverse(const Element &a) const =0
Calculate the multiplicative inverse of an element in the group.
Multiple precision integer with arithmetic operations.
CRYPTOPP_DLL size_t CRYPTOPP_API 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.
const Integer & GetModulus() const
Retrieves the modulus.
const Integer & Half(const Integer &a) const
Divides an element by 2.
String-based implementation of Store interface.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
void BERDecodeError()
Raises a BERDecodeErr.
virtual Integer ConvertIn(const Integer &a) const
Reduces an element in the congruence class.
Classes and functions for working with ANS.1 objects.
void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const
DER Encodes an elliptic curve point.
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Implementation of BufferedTransformation's attachment interface.
void MessageEnd()
Signals the end of messages to the object.
Classes and functions for number theoretic operations.
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
BER decode octet string.
const Point & Double(const Point &P) const
Doubles an element in the group.
Performs modular arithmetic in Montgomery representation for increased speed.
void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const
Encodes an elliptic curve point.
void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED)
Decode from big-endian byte array.
Multiple precision integer with arithmetic operations.
CRYPTOPP_DLL bool CRYPTOPP_API VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level=1)
Verifies a number is probably prime.
unsigned int EncodedPointSize(bool compressed=false) const
Determines encoded point size.
Class file for performing modular arithmetic.
Crypto++ library namespace.
bool GetBit(size_t i) const
Provides the i-th bit of the Integer.
void DEREncode(BufferedTransformation &bt) const
DER Encode.
void swap(::SecBlock< T, A > &a, ::SecBlock< T, A > &b)
Swap two SecBlocks.
const Integer & MultiplicativeIdentity() const
Retrieves the multiplicative identity.
Point BERDecodePoint(BufferedTransformation &bt) const
BER Decodes an elliptic curve point.
void SimultaneousMultiply(Point *results, const Point &base, const Integer *exponents, unsigned int exponentsCount) const
Multiplies a base to multiple exponents in a group.
size_type size() const
Provides the count of elements in the SecBlock.
lword TotalPutLength()
Provides the number of bytes written to the Sink.
void DEREncode(BufferedTransformation &bt) const
Encodes in DER format.
const Point & Add(const Point &P, const Point &Q) const
Adds elements in the group.
the value is positive or 0
bool IsOdd() const
Determines if the Integer is odd parity.
CRYPTOPP_DLL int CRYPTOPP_API Jacobi(const Integer &a, const Integer &b)
Calculate the Jacobi symbol.
virtual bool IsMontgomeryRepresentation() const
Retrieves the representation.