Avoid branches in Montgomery Add() (GH #869)

pull/873/head
Jeffrey Walton 2019-08-06 03:14:03 -04:00
parent 5ae70e22b9
commit 0ded32192e
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
1 changed files with 42 additions and 12 deletions

54
ecp.cpp
View File

@ -868,22 +868,52 @@ ECP::Point ECP::AdditionFunction::operator()(const Point& P, const Point& Q) con
} }
else // A_Montgomery else // A_Montgomery
{ {
ECP::Point& m_R = m_ecp.m_R;
const ECP::Field& field = m_ecp.GetField(); const ECP::Field& field = m_ecp.GetField();
const FieldElement& a = m_ecp.m_a;
ECP::Point& R = m_ecp.m_R, S = m_ecp.m_R, T;
if (P.identity) return Q; // More gyrations
if (Q.identity) return P; bool return_Q = P.identity;
if (field.Equal(P.x, Q.x)) bool return_P = Q.identity;
return field.Equal(P.y, Q.y) ? m_ecp.Double(P) : m_ecp.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);
FieldElement t = field.Subtract(Q.y, P.y); // This code taken from Double(P)
t = field.Divide(t, field.Subtract(Q.x, P.x)); identity |= double_P * (P.identity | P.y==field.Identity());
FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), Q.x);
m_R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y);
m_R.x.swap(x); if (double_P)
m_R.identity = false; {
return m_R; // This code taken from Double(P)
FieldElement t = field.Square(P.x);
t = field.Add(field.Add(field.Double(t), t), a);
t = field.Divide(t, field.Double(P.y));
FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), P.x);
T.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y);
T.x.swap(x);
}
else
{
// Original Double (P,Q) code
FieldElement t = field.Subtract(Q.y, P.y);
t = field.Divide(t, field.Subtract(Q.x, P.x));
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 if (double_P)
return (T = R), R;
else
return (T = R), R;
} }
} }