mirror of
https://github.com/emmansun/gmsm.git
synced 2025-05-12 03:56:17 +08:00
Updated High‐assurance field inversion for curve‐based cryptography (markdown)
parent
541ee1c0df
commit
1317fd0134
@ -1,3 +1,232 @@
|
|||||||
|
# 尝试1
|
||||||
|
使用**fiat-crypto**生成的代码,来事先模求逆:
|
||||||
|
代码片段1是原有的通过**addchain**生成的模求逆:
|
||||||
|
```go
|
||||||
|
// Invert sets e = 1/x, and returns e.
|
||||||
|
//
|
||||||
|
// If x == 0, Invert returns e = 0.
|
||||||
|
func (e *SM2P256Element) Invert(x *SM2P256Element) *SM2P256Element {
|
||||||
|
// Inversion is implemented as exponentiation with exponent p − 2.
|
||||||
|
// The sequence of 14 multiplications and 255 squarings is derived from the
|
||||||
|
// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
|
||||||
|
//
|
||||||
|
// _10 = 2*1
|
||||||
|
// _11 = 1 + _10
|
||||||
|
// _110 = 2*_11
|
||||||
|
// _111 = 1 + _110
|
||||||
|
// _111000 = _111 << 3
|
||||||
|
// _111111 = _111 + _111000
|
||||||
|
// _1111110 = 2*_111111
|
||||||
|
// _1111111 = 1 + _1111110
|
||||||
|
// x12 = _1111110 << 5 + _111111
|
||||||
|
// x24 = x12 << 12 + x12
|
||||||
|
// x31 = x24 << 7 + _1111111
|
||||||
|
// i39 = x31 << 2
|
||||||
|
// i68 = i39 << 29
|
||||||
|
// x62 = x31 + i68
|
||||||
|
// i71 = i68 << 2
|
||||||
|
// x64 = i39 + i71 + _11
|
||||||
|
// i265 = ((i71 << 32 + x64) << 64 + x64) << 94
|
||||||
|
// return (x62 + i265) << 2 + 1
|
||||||
|
//
|
||||||
|
var z = new(SM2P256Element).Set(e)
|
||||||
|
var t0 = new(SM2P256Element)
|
||||||
|
var t1 = new(SM2P256Element)
|
||||||
|
var t2 = new(SM2P256Element)
|
||||||
|
|
||||||
|
z.Square(x)
|
||||||
|
t0.Mul(x, z)
|
||||||
|
z.Square(t0)
|
||||||
|
z.Mul(x, z)
|
||||||
|
t1.Square(z)
|
||||||
|
for s := 1; s < 3; s++ {
|
||||||
|
t1.Square(t1)
|
||||||
|
}
|
||||||
|
t1.Mul(z, t1)
|
||||||
|
t2.Square(t1)
|
||||||
|
z.Mul(x, t2)
|
||||||
|
for s := 0; s < 5; s++ {
|
||||||
|
t2.Square(t2)
|
||||||
|
}
|
||||||
|
t1.Mul(t1, t2)
|
||||||
|
t2.Square(t1)
|
||||||
|
for s := 1; s < 12; s++ {
|
||||||
|
t2.Square(t2)
|
||||||
|
}
|
||||||
|
t1.Mul(t1, t2)
|
||||||
|
for s := 0; s < 7; s++ {
|
||||||
|
t1.Square(t1)
|
||||||
|
}
|
||||||
|
z.Mul(z, t1)
|
||||||
|
t2.Square(z)
|
||||||
|
for s := 1; s < 2; s++ {
|
||||||
|
t2.Square(t2)
|
||||||
|
}
|
||||||
|
t1.Square(t2)
|
||||||
|
for s := 1; s < 29; s++ {
|
||||||
|
t1.Square(t1)
|
||||||
|
}
|
||||||
|
z.Mul(z, t1)
|
||||||
|
for s := 0; s < 2; s++ {
|
||||||
|
t1.Square(t1)
|
||||||
|
}
|
||||||
|
t2.Mul(t2, t1)
|
||||||
|
t0.Mul(t0, t2)
|
||||||
|
for s := 0; s < 32; s++ {
|
||||||
|
t1.Square(t1)
|
||||||
|
}
|
||||||
|
t1.Mul(t0, t1)
|
||||||
|
for s := 0; s < 64; s++ {
|
||||||
|
t1.Square(t1)
|
||||||
|
}
|
||||||
|
t0.Mul(t0, t1)
|
||||||
|
for s := 0; s < 94; s++ {
|
||||||
|
t0.Square(t0)
|
||||||
|
}
|
||||||
|
z.Mul(z, t0)
|
||||||
|
for s := 0; s < 2; s++ {
|
||||||
|
z.Square(z)
|
||||||
|
}
|
||||||
|
z.Mul(x, z)
|
||||||
|
return e.Set(z)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
代码片段2通过**safegcd**介绍的最基本方法模求逆:
|
||||||
|
```go
|
||||||
|
// Reference https://github.com/mit-plv/fiat-crypto/blob/master/inversion/c/inversion_template.c
|
||||||
|
func P256Inverse(g *[4]uint64) *[4]uint64 {
|
||||||
|
var precomp, v, out4, out5 [4]uint64
|
||||||
|
var d, out1 uint64
|
||||||
|
var f, out2, out3, gs [5]uint64
|
||||||
|
var r sm2p256MontgomeryDomainFieldElement
|
||||||
|
r1 := (*[4]uint64)(&r)
|
||||||
|
sm2p256DivstepPrecomp(&precomp)
|
||||||
|
sm2p256Msat(&f)
|
||||||
|
sm2p256SetOne(&r)
|
||||||
|
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
gs[i] = g[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 370 = (256 * 49 + 57) / 17 - 1
|
||||||
|
for i := 0; i < 370; i++ {
|
||||||
|
sm2p256Divstep(&out1, &out2, &out3, &out4, &out5, d, &f, &gs, &v, r1)
|
||||||
|
sm2p256Divstep(&d, &f, &gs, &v, r1, out1, &out2, &out3, &out4, &out5)
|
||||||
|
}
|
||||||
|
|
||||||
|
sm2p256Divstep(&out1, &out2, &out3, &out4, &out5, d, &f, &gs, &v, r1)
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
v[i] = out4[i]
|
||||||
|
f[i] = out2[i]
|
||||||
|
}
|
||||||
|
f[4] = out2[4]
|
||||||
|
|
||||||
|
var out sm2p256MontgomeryDomainFieldElement
|
||||||
|
sm2p256Opp(&out, (*sm2p256MontgomeryDomainFieldElement)(&v))
|
||||||
|
sm2p256Selectznz(&v, (sm2p256Uint1)(f[4]>>63), &v, (*[4]uint64)(&out))
|
||||||
|
|
||||||
|
sm2p256Mul(&out, (*sm2p256MontgomeryDomainFieldElement)(&v), (*sm2p256MontgomeryDomainFieldElement)(&precomp))
|
||||||
|
return (*[4]uint64)(&out)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
以下是测试代码:
|
||||||
|
```go
|
||||||
|
package fiat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
var testValues = []string{
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000002",
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000003",
|
||||||
|
"1000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"1000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
"1000000000000000000000000000000000000000000000000000000000000002",
|
||||||
|
"1000000000000000000000000000000000000000000000000000000000000003",
|
||||||
|
"8356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988",
|
||||||
|
"981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1",
|
||||||
|
"d6833540d019e0438a5dd73b414f26ab43d8064b99671206944e284dbd969093",
|
||||||
|
"6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85",
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestP256Inverse(t *testing.T) {
|
||||||
|
for _, v := range testValues {
|
||||||
|
vBytes, _ := hex.DecodeString(v)
|
||||||
|
|
||||||
|
in, err := new(SM2P256Element).SetBytes(vBytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("SetBytes failed: %v", err)
|
||||||
|
}
|
||||||
|
in2 := *(*[4]uint64)(&in.x)
|
||||||
|
out1 := new(SM2P256Element).Invert(in)
|
||||||
|
out1r := (*[4]uint64)(&out1.x)
|
||||||
|
out2 := P256Inverse(&in2)
|
||||||
|
tmp := (*sm2p256NonMontgomeryDomainFieldElement)(out2)
|
||||||
|
out3 := new(sm2p256MontgomeryDomainFieldElement)
|
||||||
|
sm2p256ToMontgomery(out3, tmp)
|
||||||
|
if *out3 != *out1r {
|
||||||
|
t.Errorf("got %v, want %v", out3, &out1.x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkP256Inverse(b *testing.B) {
|
||||||
|
vBytes, _ := hex.DecodeString(testValues[0])
|
||||||
|
|
||||||
|
in, _ := new(SM2P256Element).SetBytes(vBytes)
|
||||||
|
in2 := *(*[4]uint64)(&in.x)
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
P256Inverse(&in2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkInvert(b *testing.B) {
|
||||||
|
vBytes, _ := hex.DecodeString(testValues[0])
|
||||||
|
|
||||||
|
in, _ := new(SM2P256Element).SetBytes(vBytes)
|
||||||
|
out := new(SM2P256Element)
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
out.Invert(in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
1. 还有就是fiat-cyrpto目前的实现,输入、输出有些小问题:输入是蒙哥马利型,输出是非蒙哥马利型;输入是非蒙哥马利型,输出是蒙哥马利型。这个是已知问题。https://github.com/mit-plv/fiat-crypto/issues/1020
|
||||||
|
```
|
||||||
|
goos: windows
|
||||||
|
goarch: amd64
|
||||||
|
pkg: github.com/emmansun/gmsm/internal/sm2ec/fiat
|
||||||
|
cpu: Intel(R) Core(TM) i5-9500 CPU @ 3.00GHz
|
||||||
|
BenchmarkInvert
|
||||||
|
BenchmarkInvert-6
|
||||||
|
227496 5806 ns/op 0 B/op 0 allocs/op
|
||||||
|
PASS
|
||||||
|
ok github.com/emmansun/gmsm/internal/sm2ec/fiat 1.792s
|
||||||
|
|
||||||
|
goos: windows
|
||||||
|
goarch: amd64
|
||||||
|
pkg: github.com/emmansun/gmsm/internal/sm2ec/fiat
|
||||||
|
cpu: Intel(R) Core(TM) i5-9500 CPU @ 3.00GHz
|
||||||
|
BenchmarkP256Inverse
|
||||||
|
BenchmarkP256Inverse-6
|
||||||
|
58394 20644 ns/op 32 B/op 1 allocs/op
|
||||||
|
PASS
|
||||||
|
ok github.com/emmansun/gmsm/internal/sm2ec/fiat 1.793s
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 用devsteps2事先的模求逆并没有比经过addchain优化的模求逆方法性能好。
|
||||||
|
|
||||||
# Reference
|
# Reference
|
||||||
- [High-assurance field inversion for curve-based cryptography](https://eprint.iacr.org/2021/549.pdf)
|
- [High-assurance field inversion for curve-based cryptography](https://eprint.iacr.org/2021/549.pdf)
|
||||||
- [Fast constant-time gcd and modular inversion](https://gcd.cr.yp.to/papers.html#safegcd)
|
- [Fast constant-time gcd and modular inversion](https://gcd.cr.yp.to/papers.html#safegcd)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user