chang to use NAF method in miller loop

This commit is contained in:
Sun Yimin 2022-06-10 14:44:51 +08:00 committed by GitHub
parent e8d3b67446
commit dff29c24c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 8 deletions

View File

@ -132,6 +132,9 @@ func miller(q *twistPoint, p *curvePoint) *gfP12 {
aAffine.Set(q)
aAffine.MakeAffine()
minusA := &twistPoint{}
minusA.Neg(aAffine)
bAffine := &curvePoint{}
bAffine.Set(p)
bAffine.MakeAffine()
@ -141,17 +144,25 @@ func miller(q *twistPoint, p *curvePoint) *gfP12 {
r2 := (&gfP2{}).Square(&aAffine.y)
for i := sixUPlus2.BitLen() - 2; i >= 0; i-- {
for i := len(sixUPlus2NAF) - 1; i > 0; i-- {
a, b, c, d, newR := lineFunctionDouble(r, bAffine)
if i != len(sixUPlus2NAF)-1 {
ret.Square(ret)
retDen.Square(retDen)
a, b, c, d, newR := lineFunctionDouble(r, bAffine)
mulLine(ret, retDen, a, b, c, d)
r = newR
if sixUPlus2.Bit(i) == 1 {
a, b, c, d, newR = lineFunctionAdd(r, aAffine, bAffine, r2)
mulLine(ret, retDen, a, b, c, d)
r = newR
}
mulLine(ret, retDen, a, b, c, d)
r = newR
switch sixUPlus2NAF[i-1] {
case 1:
a, b, c, d, newR = lineFunctionAdd(r, aAffine, bAffine, r2)
case -1:
a, b, c, d, newR = lineFunctionAdd(r, minusA, bAffine, r2)
default:
continue
}
mulLine(ret, retDen, a, b, c, d)
r = newR
}
q1 := &twistPoint{}
q1.x.Conjugate(&aAffine.x)

View File

@ -6,6 +6,8 @@ var u = bigFromHex("600000000058f98a")
// sixUPlus2 = 6*u+2
var sixUPlus2 = bigFromHex("02400000000215d93e")
var sixUPlus2NAF = []int8{0, -1, 0, 0, 0, 0, 1, 0, 1, 0, 0, -1, 0, -1, 0, 0, 0, -1, 0, -1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1}
// sixUPlus5 = 6*u+5
var sixUPlus5 = bigFromHex("02400000000215d941")

View File

@ -80,9 +80,10 @@ func (master *SignMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*Sign
if t1.Sign() == 0 {
return nil, errors.New("sm9: need to re-generate sign master private key")
}
t1.ModInverse(t1, Order)
t1 = fermatInverse(t1, Order)
t2 := new(big.Int).Mul(t1, master.D)
t2.Mod(t2, Order)
priv := new(SignPrivateKey)
priv.SignMasterPublicKey = master.SignMasterPublicKey
priv.PrivateKey = new(G1).ScalarBaseMult(t2)
@ -186,7 +187,7 @@ func (master *EncryptMasterPrivateKey) GenerateUserKey(uid []byte, hid byte) (*E
if t1.Sign() == 0 {
return nil, errors.New("sm9: need to re-generate encrypt master private key")
}
t1.ModInverse(t1, Order)
t1 = fermatInverse(t1, Order)
t2 := new(big.Int).Mul(t1, master.D)
t2.Mod(t2, Order)
@ -288,3 +289,14 @@ func (priv *EncryptPrivateKey) UnmarshalASN1(der []byte) error {
priv.PrivateKey = g
return nil
}
// fermatInverse calculates the inverse of k in GF(P) using Fermat's method
// (exponentiation modulo P - 2, per Euler's theorem). This has better
// constant-time properties than Euclid's method (implemented in
// math/big.Int.ModInverse and FIPS 186-4, Appendix C.1) although math/big
// itself isn't strictly constant-time so it's not perfect.
func fermatInverse(k, N *big.Int) *big.Int {
two := big.NewInt(2)
nMinus2 := new(big.Int).Sub(N, two)
return new(big.Int).Exp(k, nMinus2, N)
}