Skip to content

Commit fcba359

Browse files
committed
ecc/p384: use of complete projective formulas for scalar multiplication.
1 parent 5e1bae8 commit fcba359

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

ecc/p384/p384opt.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,33 +94,32 @@ func (c curve) scalarMultOmega(x1, y1 *big.Int, k []byte, omega uint) (x, y *big
9494
const bitsN = uint(384)
9595
L := math.SignedDigit(&scalar, omega, bitsN)
9696

97-
var R jacobianPoint
98-
Q := zeroPoint().toJacobian()
99-
TabP := newAffinePoint(x1, y1).oddMultiples(omega)
97+
var R projectivePoint
98+
Q := zeroPoint().toProjective()
99+
TabP := newAffinePoint(x1, y1).oddMultiplesProy(omega)
100100
for i := len(L) - 1; i > 0; i-- {
101101
for j := uint(0); j < omega-1; j++ {
102-
Q.double()
102+
Q.completeAdd(Q, Q)
103103
}
104104
idx := absolute(L[i]) >> 1
105105
for j := range TabP {
106106
R.cmov(&TabP[j], subtle.ConstantTimeEq(int32(j), idx))
107107
}
108108
R.cneg(int(L[i]>>31) & 1)
109-
Q.add(Q, &R)
109+
Q.completeAdd(Q, &R)
110110
}
111111
// Calculate the last iteration using complete addition formula.
112112
for j := uint(0); j < omega-1; j++ {
113-
Q.double()
113+
Q.completeAdd(Q, Q)
114114
}
115115
idx := absolute(L[0]) >> 1
116116
for j := range TabP {
117117
R.cmov(&TabP[j], subtle.ConstantTimeEq(int32(j), idx))
118118
}
119119
R.cneg(int(L[0]>>31) & 1)
120-
QQ := Q.toProjective()
121-
QQ.completeAdd(QQ, R.toProjective())
122-
QQ.cneg(isEvenK)
123-
return QQ.toAffine().toInt()
120+
Q.completeAdd(Q, &R)
121+
Q.cneg(isEvenK)
122+
return Q.toAffine().toInt()
124123
}
125124

126125
// ScalarBaseMult returns k*G, where G is the base point of the group

ecc/p384/point.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,24 @@ func (ap affinePoint) oddMultiples(n uint) []jacobianPoint {
8787
return t
8888
}
8989

90+
// OddMultiplesProy calculates the points iP for i={1,3,5,7,..., 2^(n-1)-1}
91+
// Ensure that 1 < n < 31, otherwise it returns an empty slice.
92+
func (ap affinePoint) oddMultiplesProy(n uint) []projectivePoint {
93+
var t []projectivePoint
94+
if n > 1 && n < 31 {
95+
P := ap.toProjective()
96+
s := int32(1) << (n - 1)
97+
t = make([]projectivePoint, s)
98+
t[0] = *P
99+
var _2P projectivePoint
100+
_2P.completeAdd(P, P)
101+
for i := int32(1); i < s; i++ {
102+
t[i].completeAdd(&t[i-1], &_2P)
103+
}
104+
}
105+
return t
106+
}
107+
90108
// p2Point is a point in P^2
91109
type p2Point struct{ x, y, z fp384 }
92110

@@ -303,6 +321,8 @@ func (P *projectivePoint) isZero() bool {
303321
return P.x == zero && P.y != zero && P.z == zero
304322
}
305323

324+
func (P *projectivePoint) cmov(Q *projectivePoint, b int) { P.p2Point.cmov(&Q.p2Point, b) }
325+
306326
func (P *projectivePoint) toAffine() *affinePoint {
307327
var aP affinePoint
308328
z := &fp384{}

0 commit comments

Comments
 (0)