internal/sm2ec: replace P256OrdInverse with generated code

This commit is contained in:
Sun Yimin 2024-08-19 13:02:02 +08:00 committed by GitHub
parent 2f0f4745d7
commit dd5b54f503
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -27,77 +27,136 @@ var RR = &p256OrdElement{0x901192af7c114f20, 0x3464504ade6fa2fa, 0x620fc84c3affe
// 1111111111111111111111111111111111111111111111111111111111111111 // 1111111111111111111111111111111111111111111111111111111111111111
// 0111001000000011110111110110101100100001110001100000010100101011 // 0111001000000011110111110110101100100001110001100000010100101011
// 0101001110111011111101000000100100111001110101010100000100100001 // 0101001110111011111101000000100100111001110101010100000100100001
//
func P256OrdInverse(k []byte) ([]byte, error) { func P256OrdInverse(k []byte) ([]byte, error) {
if len(k) != 32 { if len(k) != 32 {
return nil, errors.New("invalid scalar length") return nil, errors.New("invalid scalar length")
} }
x := new(p256OrdElement) x := new(p256OrdElement)
p256OrdBigToLittle(x, (*[32]byte)(k)) p256OrdBigToLittle(x, (*[32]byte)(k))
// Inversion is implemented as exponentiation with exponent p 2.
// Inversion is implemented as exponentiation by n - 2, per Fermat's little theorem. // The sequence of 41 multiplications and 253 squarings is derived from the
// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
// //
// The sequence of 43 multiplications and 254 squarings is derived from // _10 = 2*1
// https://briansmith.org/ecc-inversion-addition-chains-01#p256_scalar_inversion // _11 = 1 + _10
_1 := new(p256OrdElement) // _100 = 1 + _11
_11 := new(p256OrdElement) // _101 = 1 + _100
_101 := new(p256OrdElement) // _111 = _10 + _101
_111 := new(p256OrdElement) // _1001 = _10 + _111
_1111 := new(p256OrdElement) // _1101 = _100 + _1001
_10101 := new(p256OrdElement) // _1111 = _10 + _1101
_101111 := new(p256OrdElement) // _11110 = 2*_1111
t := new(p256OrdElement) // _11111 = 1 + _11110
m := new(p256OrdElement) // _111110 = 2*_11111
// _111111 = 1 + _111110
// _1111110 = 2*_111111
// i20 = _1111110 << 6 + _1111110
// x18 = i20 << 5 + _111111
// x31 = x18 << 13 + i20 + 1
// i42 = 2*x31
// i44 = i42 << 2
// i140 = ((i44 << 32 + i44) << 29 + i42) << 33
// i150 = ((i44 + i140 + _111) << 4 + _111) << 3
// i170 = ((1 + i150) << 11 + _1111) << 6 + _11111
// i183 = ((i170 << 5 + _1101) << 3 + _11) << 3
// i198 = ((1 + i183) << 7 + _111) << 5 + _11
// i219 = ((i198 << 9 + _101) << 5 + _101) << 5
// i231 = ((_1101 + i219) << 5 + _1001) << 4 + _1101
// i244 = ((i231 << 2 + _11) << 7 + _111111) << 2
// i262 = ((1 + i244) << 10 + _1001) << 5 + _111
// i277 = ((i262 << 5 + _111) << 4 + _101) << 4
// return ((_101 + i277) << 9 + _1001) << 5 + _11
//
var z = new(p256OrdElement)
var t0 = new(p256OrdElement)
var t1 = new(p256OrdElement)
var t2 = new(p256OrdElement)
var t3 = new(p256OrdElement)
var t4 = new(p256OrdElement)
var t5 = new(p256OrdElement)
var t6 = new(p256OrdElement)
var t7 = new(p256OrdElement)
var t8 = new(p256OrdElement)
var t9 = new(p256OrdElement)
p256OrdMul(_1, x, RR) // _1 , 2^0 p256OrdSqr(t3, x, 1)
p256OrdSqr(m, _1, 1) // _10, 2^1 p256OrdMul(z, x, t3)
p256OrdMul(_11, m, _1) // _11, 2^1 + 2^0 p256OrdMul(t4, x, z)
p256OrdMul(_101, m, _11) // _101, 2^2 + 2^0 p256OrdMul(t1, x, t4)
p256OrdMul(_111, m, _101) // _111, 2^2 + 2^1 + 2^0 p256OrdMul(t2, t3, t1)
p256OrdSqr(x, _101, 1) // _1010, 2^3 + 2^1 p256OrdMul(t0, t3, t2)
p256OrdMul(_1111, _101, x) // _1111, 2^3 + 2^2 + 2^1 + 2^0 p256OrdMul(t4, t4, t0)
p256OrdMul(t6, t3, t4)
p256OrdSqr(t, x, 1) // _10100, 2^4 + 2^2 p256OrdSqr(t3, t6, 1)
p256OrdMul(_10101, t, _1) // _10101, 2^4 + 2^2 + 2^0 p256OrdMul(t5, x, t3)
p256OrdSqr(x, _10101, 1) // _101010, 2^5 + 2^3 + 2^1 p256OrdSqr(t3, t5, 1)
p256OrdMul(_101111, _101, x) // _101111, 2^5 + 2^3 + 2^2 + 2^1 + 2^0 p256OrdMul(t3, x, t3)
p256OrdMul(x, _10101, x) // _111111 = x6, 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 p256OrdSqr(t7, t3, 1)
p256OrdSqr(t, x, 2) // _11111100, 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 p256OrdSqr(t8, t7, 6)
p256OrdMul(t7, t7, t8)
p256OrdMul(m, t, m) // _11111110 = x8, , 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 p256OrdSqr(t8, t7, 5)
p256OrdMul(t, t, _11) // _11111111 = x8, , 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 p256OrdMul(t8, t3, t8)
p256OrdSqr(x, t, 8) // _ff00, 2^15 + 2^14 + 2^13 + 2^12 + 2^11 + 2^10 + 2^9 + 2^8 p256OrdSqr(t8, t8, 13)
p256OrdMul(m, x, m) // _fffe p256OrdMul(t7, t7, t8)
p256OrdMul(x, x, t) // _ffff = x16, 2^15 + 2^14 + 2^13 + 2^12 + 2^11 + 2^10 + 2^9 + 2^8 + 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 p256OrdMul(t7, x, t7)
p256OrdSqr(t8, t7, 1)
p256OrdSqr(t, x, 16) // _ffff0000, 2^31 + 2^30 + 2^29 + 2^28 + 2^27 + 2^26 + 2^25 + 2^24 + 2^23 + 2^22 + 2^21 + 2^20 + 2^19 + 2^18 + 2^17 + 2^16 p256OrdSqr(t7, t8, 2)
p256OrdMul(m, t, m) // _fffffffe p256OrdSqr(t9, t7, 32)
p256OrdMul(t, t, x) // _ffffffff = x32 p256OrdMul(t9, t7, t9)
p256OrdSqr(t9, t9, 29)
p256OrdSqr(x, m, 32) // _fffffffe00000000 p256OrdMul(t8, t8, t9)
p256OrdMul(x, x, t) // _fffffffeffffffff p256OrdSqr(t8, t8, 33)
p256OrdSqr(x, x, 32) // _fffffffeffffffff00000000 p256OrdMul(t7, t7, t8)
p256OrdMul(x, x, t) // _fffffffeffffffffffffffff p256OrdMul(t7, t2, t7)
p256OrdSqr(x, x, 32) // _fffffffeffffffffffffffff00000000 p256OrdSqr(t7, t7, 4)
p256OrdMul(x, x, t) // _fffffffeffffffffffffffffffffffff p256OrdMul(t7, t2, t7)
p256OrdSqr(t7, t7, 3)
sqrs := []uint8{ p256OrdMul(t7, x, t7)
4, 3, 11, 5, 3, 5, 1, p256OrdSqr(t7, t7, 11)
3, 7, 5, 9, 7, 5, 5, p256OrdMul(t6, t6, t7)
4, 5, 2, 2, 7, 3, 5, p256OrdSqr(t6, t6, 6)
5, 6, 2, 6, 3, 5, p256OrdMul(t5, t5, t6)
} p256OrdSqr(t5, t5, 5)
muls := []*p256OrdElement{ p256OrdMul(t5, t4, t5)
_111, _1, _1111, _1111, _101, _10101, _1, p256OrdSqr(t5, t5, 3)
_1, _111, _11, _101, _10101, _10101, _111, p256OrdMul(t5, z, t5)
_111, _1111, _11, _1, _1, _1, _111, p256OrdSqr(t5, t5, 3)
_111, _10101, _1, _1, _1, _1} p256OrdMul(t5, x, t5)
p256OrdSqr(t5, t5, 7)
for i, s := range sqrs { p256OrdMul(t5, t2, t5)
p256OrdSqr(x, x, int(s)) p256OrdSqr(t5, t5, 5)
p256OrdMul(x, x, muls[i]) p256OrdMul(t5, z, t5)
} p256OrdSqr(t5, t5, 9)
return p256OrderFromMont(x), nil p256OrdMul(t5, t1, t5)
p256OrdSqr(t5, t5, 5)
p256OrdMul(t5, t1, t5)
p256OrdSqr(t5, t5, 5)
p256OrdMul(t5, t4, t5)
p256OrdSqr(t5, t5, 5)
p256OrdMul(t5, t0, t5)
p256OrdSqr(t5, t5, 4)
p256OrdMul(t4, t4, t5)
p256OrdSqr(t4, t4, 2)
p256OrdMul(t4, z, t4)
p256OrdSqr(t4, t4, 7)
p256OrdMul(t3, t3, t4)
p256OrdSqr(t3, t3, 2)
p256OrdMul(t3, x, t3)
p256OrdSqr(t3, t3, 10)
p256OrdMul(t3, t0, t3)
p256OrdSqr(t3, t3, 5)
p256OrdMul(t3, t2, t3)
p256OrdSqr(t3, t3, 5)
p256OrdMul(t2, t2, t3)
p256OrdSqr(t2, t2, 4)
p256OrdMul(t2, t1, t2)
p256OrdSqr(t2, t2, 4)
p256OrdMul(t1, t1, t2)
p256OrdSqr(t1, t1, 9)
p256OrdMul(t0, t0, t1)
p256OrdSqr(t0, t0, 5)
p256OrdMul(z, z, t0)
return p256OrderFromMont(z), nil
} }
// P256OrdMul multiplication modulo org(G). // P256OrdMul multiplication modulo org(G).