Date: Thursday, January 7, 2021 @ 13:10:41 Author: alucryd Revision: 811708
upgpkg: crypto++ 8.4.0-1 Modified: crypto++/trunk/PKGBUILD Deleted: crypto++/trunk/cve-2019-14318.patch ----------------------+ PKGBUILD | 23 - cve-2019-14318.patch | 640 ------------------------------------------------- 2 files changed, 5 insertions(+), 658 deletions(-) Modified: PKGBUILD =================================================================== --- PKGBUILD 2021-01-07 13:10:23 UTC (rev 811707) +++ PKGBUILD 2021-01-07 13:10:41 UTC (rev 811708) @@ -7,8 +7,8 @@ # Contributor: jlvsimoes <[email protected]> pkgname=crypto++ -pkgver=8.2.0 -pkgrel=3 +pkgver=8.4.0 +pkgrel=1 pkgdesc='A free C++ class library of cryptographic schemes' arch=(x86_64) url=https://www.cryptopp.com/ @@ -18,29 +18,16 @@ git unzip ) -source=( - git+https://github.com/weidai11/cryptopp.git#tag=9dcc26c58213abb8351fbb1b2a7a1d2c667366e4 - #git+https://github.com/weidai11/cryptopp.git?signed#tag=9dcc26c58213abb8351fbb1b2a7a1d2c667366e4 - cve-2019-14318.patch -) -sha256sums=( - SKIP - d9cabc1eab0dfbab1d4bfff75fa99766995089e52b83a175918e738516efbb41 -) +_tag=434e3189db61ff4ced13b47fe450a42b3c8cb676 +source=(git+https://github.com/weidai11/cryptopp.git#tag=${_tag}) +b2sums=(SKIP) validpgpkeys=(B8CC19802062211A508B2F5CCE0586AF1F8E37BD) # Jeffrey Walton <[email protected]> pkgver() { cd cryptopp - git describe --tags | sed 's/^CRYPTOPP_//; s/_/./g' } -prepare() { - cd cryptopp - - patch -Np0 -i ../cve-2019-14318.patch -} - build() { export CXXFLAGS="$CXXFLAGS -DNDEBUG -fPIC" make -C cryptopp dynamic cryptest.exe libcryptopp.pc Deleted: cve-2019-14318.patch =================================================================== --- cve-2019-14318.patch 2021-01-07 13:10:23 UTC (rev 811707) +++ cve-2019-14318.patch 2021-01-07 13:10:41 UTC (rev 811708) @@ -1,640 +0,0 @@ -# Patch for Crypto++ timing leaks in EC gear (GH #869) -# diff of Crypto++ 8.2 and Master 04b2a20c5da5 ---- pubkey.h -+++ pubkey.h -@@ -886,7 +886,7 @@ - /// \brief Retrieves the encoded element's size - /// \param reversible flag indicating the encoding format - /// \return encoded element's size, in bytes -- /// \details The format of the encoded element varies by the underlyinhg type of the element and the -+ /// \details The format of the encoded element varies by the underlying type of the element and the - /// reversible flag. GetEncodedElementSize() must be implemented in a derived class. - /// \sa GetEncodedElementSize(), EncodeElement(), DecodeElement() - virtual unsigned int GetEncodedElementSize(bool reversible) const =0; -@@ -1604,10 +1604,10 @@ - if (rng.CanIncorporateEntropy()) - rng.IncorporateEntropy(representative, representative.size()); - -- Integer k; -+ Integer k, ks; -+ const Integer& q = params.GetSubgroupOrder(); - if (alg.IsDeterministic()) - { -- const Integer& q = params.GetSubgroupOrder(); - const Integer& x = key.GetPrivateExponent(); - const DeterministicSignatureAlgorithm& det = dynamic_cast<const DeterministicSignatureAlgorithm&>(alg); - k = det.GenerateRandom(x, q, e); -@@ -1617,8 +1617,15 @@ - k.Randomize(rng, 1, params.GetSubgroupOrder()-1); - } - -+ // Due to timing attack on nonce length by Jancar -+ // https://github.com/weidai11/cryptopp/issues/869 -+ ks = k + q; -+ if (ks.BitCount() == q.BitCount()) { -+ ks += q; -+ } -+ - Integer r, s; -- r = params.ConvertElementToInteger(params.ExponentiateBase(k)); -+ r = params.ConvertElementToInteger(params.ExponentiateBase(ks)); - alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); - - /* -@@ -1630,7 +1637,7 @@ - alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s); - */ - -- size_t rLen = alg.RLen(params); -+ const size_t rLen = alg.RLen(params); - r.Encode(signature, rLen); - s.Encode(signature+rLen, alg.SLen(params)); - ---- ecp.cpp -+++ ecp.cpp -@@ -15,10 +15,12 @@ - ANONYMOUS_NAMESPACE_BEGIN - - using CryptoPP::ECP; -+using CryptoPP::Integer; - using CryptoPP::ModularArithmetic; - - #if defined(HAVE_GCC_INIT_PRIORITY) -- const ECP::Point g_identity __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 51))) = ECP::Point(); -+ #define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 50))) -+ const ECP::Point g_identity INIT_ATTRIBUTE = ECP::Point(); - #elif defined(HAVE_MSC_INIT_PRIORITY) - #pragma warning(disable: 4075) - #pragma init_seg(".CRT$XCU") -@@ -39,6 +41,502 @@ - return P.identity ? P : ECP::Point(mr.ConvertOut(P.x), mr.ConvertOut(P.y)); - } - -+inline Integer IdentityToInteger(bool val) -+{ -+ return val ? Integer::One() : Integer::Zero(); -+} -+ -+struct ProjectivePoint -+{ -+ ProjectivePoint() {} -+ ProjectivePoint(const Integer &x, const Integer &y, const Integer &z) -+ : x(x), y(y), z(z) {} -+ -+ Integer x, y, z; -+}; -+ -+/// \brief Addition and Double functions -+/// \sa <A HREF="https://eprint.iacr.org/2015/1060.pdf">Complete -+/// addition formulas for prime order elliptic curves</A> -+struct AdditionFunction -+{ -+ explicit AdditionFunction(const ECP::Field& field, -+ const ECP::FieldElement &a, const ECP::FieldElement &b, ECP::Point &r); -+ -+ // Double(P) -+ ECP::Point operator()(const ECP::Point& P) const; -+ // Add(P, Q) -+ ECP::Point operator()(const ECP::Point& P, const ECP::Point& Q) const; -+ -+protected: -+ /// \brief Parameters and representation for Addition -+ /// \details Addition and Doubling will use different algorithms, -+ /// depending on the <tt>A</tt> coefficient and the representation -+ /// (Affine or Montgomery with precomputation). -+ enum Alpha { -+ /// \brief Coefficient A is 0 -+ A_0 = 1, -+ /// \brief Coefficient A is -3 -+ A_3 = 2, -+ /// \brief Coefficient A is arbitrary -+ A_Star = 4, -+ /// \brief Representation is Montgomery -+ A_Montgomery = 8 -+ }; -+ -+ const ECP::Field& field; -+ const ECP::FieldElement &a, &b; -+ ECP::Point &R; -+ -+ Alpha m_alpha; -+}; -+ -+#define X p.x -+#define Y p.y -+#define Z p.z -+ -+#define X1 p.x -+#define Y1 p.y -+#define Z1 p.z -+ -+#define X2 q.x -+#define Y2 q.y -+#define Z2 q.z -+ -+#define X3 r.x -+#define Y3 r.y -+#define Z3 r.z -+ -+AdditionFunction::AdditionFunction(const ECP::Field& field, -+ const ECP::FieldElement &a, const ECP::FieldElement &b, ECP::Point &r) -+ : field(field), a(a), b(b), R(r), m_alpha(static_cast<Alpha>(0)) -+{ -+ if (field.IsMontgomeryRepresentation()) -+ { -+ m_alpha = A_Montgomery; -+ } -+ else -+ { -+ if (a == 0) -+ { -+ m_alpha = A_0; -+ } -+ else if (a == -3 || (a - field.GetModulus()) == -3) -+ { -+ m_alpha = A_3; -+ } -+ else -+ { -+ m_alpha = A_Star; -+ } -+ } -+} -+ -+ECP::Point AdditionFunction::operator()(const ECP::Point& P) const -+{ -+ if (m_alpha == A_3) -+ { -+ // Gyrations attempt to maintain constant-timeness -+ // We need either (P.x, P.y, 1) or (0, 1, 0). -+ const Integer x = P.x * IdentityToInteger(!P.identity); -+ const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity); -+ const Integer z = 1 * IdentityToInteger(!P.identity); -+ -+ ProjectivePoint p(x, y, z), r; -+ -+ ECP::FieldElement t0 = field.Square(X); -+ ECP::FieldElement t1 = field.Square(Y); -+ ECP::FieldElement t2 = field.Square(Z); -+ ECP::FieldElement t3 = field.Multiply(X, Y); -+ t3 = field.Add(t3, t3); -+ Z3 = field.Multiply(X, Z); -+ Z3 = field.Add(Z3, Z3); -+ Y3 = field.Multiply(b, t2); -+ Y3 = field.Subtract(Y3, Z3); -+ X3 = field.Add(Y3, Y3); -+ Y3 = field.Add(X3, Y3); -+ X3 = field.Subtract(t1, Y3); -+ Y3 = field.Add(t1, Y3); -+ Y3 = field.Multiply(X3, Y3); -+ X3 = field.Multiply(X3, t3); -+ t3 = field.Add(t2, t2); -+ t2 = field.Add(t2, t3); -+ Z3 = field.Multiply(b, Z3); -+ Z3 = field.Subtract(Z3, t2); -+ Z3 = field.Subtract(Z3, t0); -+ t3 = field.Add(Z3, Z3); -+ Z3 = field.Add(Z3, t3); -+ t3 = field.Add(t0, t0); -+ t0 = field.Add(t3, t0); -+ t0 = field.Subtract(t0, t2); -+ t0 = field.Multiply(t0, Z3); -+ Y3 = field.Add(Y3, t0); -+ t0 = field.Multiply(Y, Z); -+ t0 = field.Add(t0, t0); -+ Z3 = field.Multiply(t0, Z3); -+ X3 = field.Subtract(X3, Z3); -+ Z3 = field.Multiply(t0, t1); -+ Z3 = field.Add(Z3, Z3); -+ Z3 = field.Add(Z3, Z3); -+ -+ const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3); -+ X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv); -+ -+ // More gyrations -+ R.x = X3*Z3.NotZero(); -+ R.y = Y3*Z3.NotZero(); -+ R.identity = Z3.IsZero(); -+ -+ return R; -+ } -+ else if (m_alpha == A_0) -+ { -+ const ECP::FieldElement b3 = field.Multiply(b, 3); -+ -+ // Gyrations attempt to maintain constant-timeness -+ // We need either (P.x, P.y, 1) or (0, 1, 0). -+ const Integer x = P.x * IdentityToInteger(!P.identity); -+ const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity); -+ const Integer z = 1 * IdentityToInteger(!P.identity); -+ -+ ProjectivePoint p(x, y, z), r; -+ -+ ECP::FieldElement t0 = field.Square(Y); -+ Z3 = field.Add(t0, t0); -+ Z3 = field.Add(Z3, Z3); -+ Z3 = field.Add(Z3, Z3); -+ ECP::FieldElement t1 = field.Add(Y, Z); -+ ECP::FieldElement t2 = field.Square(Z); -+ t2 = field.Multiply(b3, t2); -+ X3 = field.Multiply(t2, Z3); -+ Y3 = field.Add(t0, t2); -+ Z3 = field.Multiply(t1, Z3); -+ t1 = field.Add(t2, t2); -+ t2 = field.Add(t1, t2); -+ t0 = field.Subtract(t0, t2); -+ Y3 = field.Multiply(t0, Y3); -+ Y3 = field.Add(X3, Y3); -+ t1 = field.Multiply(X, Y); -+ X3 = field.Multiply(t0, t1); -+ X3 = field.Add(X3, X3); -+ -+ const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3); -+ X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv); -+ -+ // More gyrations -+ R.x = X3*Z3.NotZero(); -+ R.y = Y3*Z3.NotZero(); -+ R.identity = Z3.IsZero(); -+ -+ return R; -+ } -+ else if (m_alpha == A_Star) -+ { -+ const ECP::FieldElement b3 = field.Multiply(b, 3); -+ -+ // Gyrations attempt to maintain constant-timeness -+ // We need either (P.x, P.y, 1) or (0, 1, 0). -+ const Integer x = P.x * IdentityToInteger(!P.identity); -+ const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity); -+ const Integer z = 1 * IdentityToInteger(!P.identity); -+ -+ ProjectivePoint p(x, y, z), r; -+ -+ ECP::FieldElement t0 = field.Square(Y); -+ Z3 = field.Add(t0, t0); -+ Z3 = field.Add(Z3, Z3); -+ Z3 = field.Add(Z3, Z3); -+ ECP::FieldElement t1 = field.Add(Y, Z); -+ ECP::FieldElement t2 = field.Square(Z); -+ t2 = field.Multiply(b3, t2); -+ X3 = field.Multiply(t2, Z3); -+ Y3 = field.Add(t0, t2); -+ Z3 = field.Multiply(t1, Z3); -+ t1 = field.Add(t2, t2); -+ t2 = field.Add(t1, t2); -+ t0 = field.Subtract(t0, t2); -+ Y3 = field.Multiply(t0, Y3); -+ Y3 = field.Add(X3, Y3); -+ t1 = field.Multiply(X, Y); -+ X3 = field.Multiply(t0, t1); -+ X3 = field.Add(X3, X3); -+ -+ const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3); -+ X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv); -+ -+ // More gyrations -+ R.x = X3*Z3.NotZero(); -+ R.y = Y3*Z3.NotZero(); -+ R.identity = Z3.IsZero(); -+ -+ return R; -+ } -+ else // A_Montgomery -+ { -+ // More gyrations -+ bool identity = !!(P.identity + (P.y == field.Identity())); -+ -+ ECP::FieldElement t = field.Square(P.x); -+ t = field.Add(field.Add(field.Double(t), t), a); -+ t = field.Divide(t, field.Double(P.y)); -+ ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), P.x); -+ R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y); -+ R.x.swap(x); -+ -+ // More gyrations -+ R.x *= IdentityToInteger(!identity); -+ R.y *= IdentityToInteger(!identity); -+ R.identity = identity; -+ -+ return R; -+ } -+} -+ -+ECP::Point AdditionFunction::operator()(const ECP::Point& P, const ECP::Point& Q) const -+{ -+ if (m_alpha == A_3) -+ { -+ // Gyrations attempt to maintain constant-timeness -+ // We need either (P.x, P.y, 1) or (0, 1, 0). -+ const Integer x1 = P.x * IdentityToInteger(!P.identity); -+ const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity); -+ const Integer z1 = 1 * IdentityToInteger(!P.identity); -+ -+ const Integer x2 = Q.x * IdentityToInteger(!Q.identity); -+ const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity); -+ const Integer z2 = 1 * IdentityToInteger(!Q.identity); -+ -+ ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r; -+ -+ ECP::FieldElement t0 = field.Multiply(X1, X2); -+ ECP::FieldElement t1 = field.Multiply(Y1, Y2); -+ ECP::FieldElement t2 = field.Multiply(Z1, Z2); -+ ECP::FieldElement t3 = field.Add(X1, Y1); -+ ECP::FieldElement t4 = field.Add(X2, Y2); -+ t3 = field.Multiply(t3, t4); -+ t4 = field.Add(t0, t1); -+ t3 = field.Subtract(t3, t4); -+ t4 = field.Add(Y1, Z1); -+ X3 = field.Add(Y2, Z2); -+ t4 = field.Multiply(t4, X3); -+ X3 = field.Add(t1, t2); -+ t4 = field.Subtract(t4, X3); -+ X3 = field.Add(X1, Z1); -+ Y3 = field.Add(X2, Z2); -+ X3 = field.Multiply(X3, Y3); -+ Y3 = field.Add(t0, t2); -+ Y3 = field.Subtract(X3, Y3); -+ Z3 = field.Multiply(b, t2); -+ X3 = field.Subtract(Y3, Z3); -+ Z3 = field.Add(X3, X3); -+ X3 = field.Add(X3, Z3); -+ Z3 = field.Subtract(t1, X3); -+ X3 = field.Add(t1, X3); -+ Y3 = field.Multiply(b, Y3); -+ t1 = field.Add(t2, t2); -+ t2 = field.Add(t1, t2); -+ Y3 = field.Subtract(Y3, t2); -+ Y3 = field.Subtract(Y3, t0); -+ t1 = field.Add(Y3, Y3); -+ Y3 = field.Add(t1, Y3); -+ t1 = field.Add(t0, t0); -+ t0 = field.Add(t1, t0); -+ t0 = field.Subtract(t0, t2); -+ t1 = field.Multiply(t4, Y3); -+ t2 = field.Multiply(t0, Y3); -+ Y3 = field.Multiply(X3, Z3); -+ Y3 = field.Add(Y3, t2); -+ X3 = field.Multiply(t3, X3); -+ X3 = field.Subtract(X3, t1); -+ Z3 = field.Multiply(t4, Z3); -+ t1 = field.Multiply(t3, t0); -+ Z3 = field.Add(Z3, t1); -+ -+ const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3); -+ X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv); -+ -+ // More gyrations -+ R.x = X3*Z3.NotZero(); -+ R.y = Y3*Z3.NotZero(); -+ R.identity = Z3.IsZero(); -+ -+ return R; -+ } -+ else if (m_alpha == A_0) -+ { -+ const ECP::FieldElement b3 = field.Multiply(b, 3); -+ -+ // Gyrations attempt to maintain constant-timeness -+ // We need either (P.x, P.y, 1) or (0, 1, 0). -+ const Integer x1 = P.x * IdentityToInteger(!P.identity); -+ const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity); -+ const Integer z1 = 1 * IdentityToInteger(!P.identity); -+ -+ const Integer x2 = Q.x * IdentityToInteger(!Q.identity); -+ const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity); -+ const Integer z2 = 1 * IdentityToInteger(!Q.identity); -+ -+ ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r; -+ -+ ECP::FieldElement t0 = field.Square(Y); -+ Z3 = field.Add(t0, t0); -+ Z3 = field.Add(Z3, Z3); -+ Z3 = field.Add(Z3, Z3); -+ ECP::FieldElement t1 = field.Add(Y, Z); -+ ECP::FieldElement t2 = field.Square(Z); -+ t2 = field.Multiply(b3, t2); -+ X3 = field.Multiply(t2, Z3); -+ Y3 = field.Add(t0, t2); -+ Z3 = field.Multiply(t1, Z3); -+ t1 = field.Add(t2, t2); -+ t2 = field.Add(t1, t2); -+ t0 = field.Subtract(t0, t2); -+ Y3 = field.Multiply(t0, Y3); -+ Y3 = field.Add(X3, Y3); -+ t1 = field.Multiply(X, Y); -+ X3 = field.Multiply(t0, t1); -+ X3 = field.Add(X3, X3); -+ -+ const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3); -+ X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv); -+ -+ // More gyrations -+ R.x = X3*Z3.NotZero(); -+ R.y = Y3*Z3.NotZero(); -+ R.identity = Z3.IsZero(); -+ -+ return R; -+ } -+ else if (m_alpha == A_Star) -+ { -+ const ECP::FieldElement b3 = field.Multiply(b, 3); -+ -+ // Gyrations attempt to maintain constant-timeness -+ // We need either (P.x, P.y, 1) or (0, 1, 0). -+ const Integer x1 = P.x * IdentityToInteger(!P.identity); -+ const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity); -+ const Integer z1 = 1 * IdentityToInteger(!P.identity); -+ -+ const Integer x2 = Q.x * IdentityToInteger(!Q.identity); -+ const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity); -+ const Integer z2 = 1 * IdentityToInteger(!Q.identity); -+ -+ ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r; -+ -+ ECP::FieldElement t0 = field.Multiply(X1, X2); -+ ECP::FieldElement t1 = field.Multiply(Y1, Y2); -+ ECP::FieldElement t2 = field.Multiply(Z1, Z2); -+ ECP::FieldElement t3 = field.Add(X1, Y1); -+ ECP::FieldElement t4 = field.Add(X2, Y2); -+ t3 = field.Multiply(t3, t4); -+ t4 = field.Add(t0, t1); -+ t3 = field.Subtract(t3, t4); -+ t4 = field.Add(X1, Z1); -+ ECP::FieldElement t5 = field.Add(X2, Z2); -+ t4 = field.Multiply(t4, t5); -+ t5 = field.Add(t0, t2); -+ t4 = field.Subtract(t4, t5); -+ t5 = field.Add(Y1, Z1); -+ X3 = field.Add(Y2, Z2); -+ t5 = field.Multiply(t5, X3); -+ X3 = field.Add(t1, t2); -+ t5 = field.Subtract(t5, X3); -+ Z3 = field.Multiply(a, t4); -+ X3 = field.Multiply(b3, t2); -+ Z3 = field.Add(X3, Z3); -+ X3 = field.Subtract(t1, Z3); -+ Z3 = field.Add(t1, Z3); -+ Y3 = field.Multiply(X3, Z3); -+ t1 = field.Add(t0, t0); -+ t1 = field.Add(t1, t0); -+ t2 = field.Multiply(a, t2); -+ t4 = field.Multiply(b3, t4); -+ t1 = field.Add(t1, t2); -+ t2 = field.Subtract(t0, t2); -+ t2 = field.Multiply(a, t2); -+ t4 = field.Add(t4, t2); -+ t0 = field.Multiply(t1, t4); -+ Y3 = field.Add(Y3, t0); -+ t0 = field.Multiply(t5, t4); -+ X3 = field.Multiply(t3, X3); -+ X3 = field.Subtract(X3, t0); -+ t0 = field.Multiply(t3, t1); -+ Z3 = field.Multiply(t5, Z3); -+ Z3 = field.Add(Z3, t0); -+ -+ const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3); -+ X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv); -+ -+ // More gyrations -+ R.x = X3*Z3.NotZero(); -+ R.y = Y3*Z3.NotZero(); -+ R.identity = Z3.IsZero(); -+ -+ return R; -+ } -+ else // A_Montgomery -+ { -+ ECP::Point S = R; -+ -+ // More gyrations -+ bool return_Q = P.identity; -+ bool return_P = Q.identity; -+ bool double_P = field.Equal(P.x, Q.x) && field.Equal(P.y, Q.y); -+ bool identity = field.Equal(P.x, Q.x) && !field.Equal(P.y, Q.y); -+ -+ // This code taken from Double(P) for below -+ identity = !!((double_P * (P.identity + (P.y == field.Identity()))) + identity); -+ -+ if (double_P) -+ { -+ // This code taken from Double(P) -+ ECP::FieldElement t = field.Square(P.x); -+ t = field.Add(field.Add(field.Double(t), t), a); -+ t = field.Divide(t, field.Double(P.y)); -+ ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), P.x); -+ R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y); -+ R.x.swap(x); -+ } -+ else -+ { -+ // Original Add(P,Q) code -+ ECP::FieldElement t = field.Subtract(Q.y, P.y); -+ t = field.Divide(t, field.Subtract(Q.x, P.x)); -+ ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), Q.x); -+ R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y); -+ R.x.swap(x); -+ } -+ -+ // More gyrations -+ R.x = R.x * IdentityToInteger(!identity); -+ R.y = R.y * IdentityToInteger(!identity); -+ R.identity = identity; -+ -+ if (return_Q) -+ return (R = S), Q; -+ else if (return_P) -+ return (R = S), P; -+ else -+ return (S = R), R; -+ } -+} -+ -+#undef X -+#undef Y -+#undef Z -+ -+#undef X1 -+#undef Y1 -+#undef Z1 -+ -+#undef X2 -+#undef Y2 -+#undef Z2 -+ -+#undef X3 -+#undef Y3 -+#undef Z3 -+ - ANONYMOUS_NAMESPACE_END - - NAMESPACE_BEGIN(CryptoPP) -@@ -243,34 +741,14 @@ - - const ECP::Point& ECP::Add(const Point &P, const Point &Q) const - { -- if (P.identity) return Q; -- if (Q.identity) return P; -- if (GetField().Equal(P.x, Q.x)) -- return GetField().Equal(P.y, Q.y) ? Double(P) : Identity(); -- -- FieldElement t = GetField().Subtract(Q.y, P.y); -- t = GetField().Divide(t, GetField().Subtract(Q.x, P.x)); -- FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), Q.x); -- m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y); -- -- m_R.x.swap(x); -- m_R.identity = false; -- return m_R; -+ AdditionFunction add(GetField(), m_a, m_b, m_R); -+ return (m_R = add(P, Q)); - } - - const ECP::Point& ECP::Double(const Point &P) const - { -- if (P.identity || P.y==GetField().Identity()) return Identity(); -- -- FieldElement t = GetField().Square(P.x); -- t = GetField().Add(GetField().Add(GetField().Double(t), t), m_a); -- t = GetField().Divide(t, GetField().Double(P.y)); -- FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), P.x); -- m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y); -- -- m_R.x.swap(x); -- m_R.identity = false; -- return m_R; -+ AdditionFunction add(GetField(), m_a, m_b, m_R); -+ return (m_R = add(P)); - } - - template <class T, class Iterator> void ParallelInvert(const AbstractRing<T> &ring, Iterator begin, Iterator end) -@@ -310,20 +788,11 @@ - } - } - --struct ProjectivePoint --{ -- ProjectivePoint() {} -- ProjectivePoint(const Integer &x, const Integer &y, const Integer &z) -- : x(x), y(y), z(z) {} -- -- Integer x,y,z; --}; -- - class ProjectiveDoubling - { - public: - ProjectiveDoubling(const ModularArithmetic &m_mr, const Integer &m_a, const Integer &m_b, const ECPPoint &Q) -- : mr(m_mr), firstDoubling(true), negated(false) -+ : mr(m_mr) - { - CRYPTOPP_UNUSED(m_b); - if (Q.identity) -@@ -360,7 +829,6 @@ - - const ModularArithmetic &mr; - ProjectivePoint P; -- bool firstDoubling, negated; - Integer sixteenY4, aZ4, twoY, fourY2, S, M; - }; -
