#undef CAR2
// p256PointAddAsm(P3, P1, P2 *p256Point)
-#define P3ptr R1
-#define P1ptr R2
-#define P2ptr R3
-#define CPOOL R4
+#define P3ptr R1
+#define P1ptr R2
+#define P2ptr R3
+#define CPOOL R4
+#define ISZERO R5
+#define TRUE R6
// Temporaries in REGs
#define T1L V16
// SUB(H<H-T) // H = H-U1
p256SubInternal(HH,HL,HH,HL,T1,T0)
+ // if H == 0 or H^P == 0 then ret=1 else ret=0
+ // clobbers T1H and T1L
+ MOVD $0, ISZERO
+ MOVD $1, TRUE
+ VZERO ZER
+ VO HL, HH, T1H
+ VCEQGS ZER, T1H, T1H
+ MOVDEQ TRUE, ISZERO
+ VX HL, PL, T1L
+ VX HH, PH, T1H
+ VO T1L, T1H, T1H
+ VCEQGS ZER, T1H, T1H
+ MOVDEQ TRUE, ISZERO
+ MOVD ISZERO, ret+24(FP)
+
// X=Z1; Y=Z2; MUL; T- // Z3 = Z1*Z2
VL 64(P1ptr), X1 // Z1H
VL 80(P1ptr), X0 // Z1L
// SUB(R<T-S1) // R = T-S1
p256SubInternal(RH,RL,T1,T0,S1H,S1L)
+ // if R == 0 or R^P == 0 then ret=ret else ret=0
+ // clobbers T1H and T1L
+ MOVD $0, ISZERO
+ MOVD $1, TRUE
+ VZERO ZER
+ VO RL, RH, T1H
+ VCEQGS ZER, T1H, T1H
+ MOVDEQ TRUE, ISZERO
+ VX RL, PL, T1L
+ VX RH, PH, T1H
+ VO T1L, T1H, T1H
+ VCEQGS ZER, T1H, T1H
+ MOVDEQ TRUE, ISZERO
+ AND ret+24(FP), ISZERO
+ MOVD ISZERO, ret+24(FP)
+
// X=H ; Y=H ; MUL; T- // T1 = H*H
VLR HL, X0
VLR HH, X1
package elliptic
import (
+ "crypto/subtle"
"math/big"
)
var hasVX = hasVectorFacility()
func initP256Arch() {
- // Assembly implementation is temporarily disabled until issue
- // #20215 is fixed.
- // if hasVX {
- if false {
+ if hasVX {
p256 = p256CurveFast{p256Params}
initTable()
return
func p256PointAddAffineAsm(P3, P1, P2 *p256Point, sign, sel, zero int)
// Point add
-func p256PointAddAsm(P3, P1, P2 *p256Point)
+func p256PointAddAsm(P3, P1, P2 *p256Point) int
func p256PointDoubleAsm(P3, P1 *p256Point)
func (curve p256CurveFast) Inverse(k *big.Int) *big.Int {
func (curve p256CurveFast) CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int) {
var r1, r2 p256Point
- r1.p256BaseMult(p256GetMultiplier(baseScalar))
+ scalarReduced := p256GetMultiplier(baseScalar)
+ r1IsInfinity := scalarIsZero(scalarReduced)
+ r1.p256BaseMult(scalarReduced)
copy(r2.x[:], fromBig(maybeReduceModP(bigX)))
copy(r2.y[:], fromBig(maybeReduceModP(bigY)))
p256MulAsm(r2.x[:], r2.x[:], rr[:])
p256MulAsm(r2.y[:], r2.y[:], rr[:])
+ scalarReduced = p256GetMultiplier(scalar)
+ r2IsInfinity := scalarIsZero(scalarReduced)
r2.p256ScalarMult(p256GetMultiplier(scalar))
- p256PointAddAsm(&r1, &r1, &r2)
- return r1.p256PointToAffine()
+
+ var sum, double p256Point
+ pointsEqual := p256PointAddAsm(&sum, &r1, &r2)
+ p256PointDoubleAsm(&double, &r1)
+ p256MovCond(&sum, &double, &sum, pointsEqual)
+ p256MovCond(&sum, &r1, &sum, r2IsInfinity)
+ p256MovCond(&sum, &r2, &sum, r1IsInfinity)
+ return sum.p256PointToAffine()
}
func (curve p256CurveFast) ScalarBaseMult(scalar []byte) (x, y *big.Int) {
return r.p256PointToAffine()
}
+// scalarIsZero returns 1 if scalar represents the zero value, and zero
+// otherwise.
+func scalarIsZero(scalar []byte) int {
+ b := byte(0)
+ for _, s := range scalar {
+ b |= s
+ }
+ return subtle.ConstantTimeByteEq(b, 0)
+}
+
func (p *p256Point) p256PointToAffine() (x, y *big.Int) {
zInv := make([]byte, 32)
zInvSq := make([]byte, 32)