mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 20:26:19 +08:00
chang to use NAF method in miller loop
This commit is contained in:
parent
e8d3b67446
commit
dff29c24c6
@ -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)
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user