gmsm/sm2/gen_p256_table.go
2021-11-04 13:07:00 +08:00

98 lines
2.5 KiB
Go

// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build amd64
// +build amd64
package sm2
import (
"bytes"
"encoding/binary"
"fmt"
"go/format"
)
func GenTables() {
buf := new(bytes.Buffer)
fmt.Fprint(buf, `
// Generated by gen_p256_table.go. DO NOT EDIT.
//go:build amd64
// +build amd64
package sm2
`[1:])
// Generate precomputed p256 tables.
var pre [43][32 * 8]uint64
basePoint := []uint64{
0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05,
0xc1354e593c2d0ddd, 0xc1f5e5788d3295fa, 0x8d4cfb066e2a48f8, 0x63cd65d481d735bd,
0x0000000000000001, 0x00000000ffffffff, 0x0000000000000000, 0x0000000100000000,
}
t1 := make([]uint64, 12)
t2 := make([]uint64, 12)
copy(t2, basePoint)
zInv := make([]uint64, 4)
zInvSq := make([]uint64, 4)
for j := 0; j < 32; j++ {
copy(t1, t2)
for i := 0; i < 43; i++ {
// The window size is 6 so we need to double 6 times.
if i != 0 {
for k := 0; k < 6; k++ {
p256PointDoubleAsm(t1, t1)
}
}
// Convert the point to affine form. (Its values are
// still in Montgomery form however.)
p256Inverse(zInv, t1[8:12])
p256Sqr(zInvSq, zInv, 1)
p256Mul(zInv, zInv, zInvSq)
p256Mul(t1[:4], t1[:4], zInvSq)
p256Mul(t1[4:8], t1[4:8], zInv)
copy(t1[8:12], basePoint[8:12])
// Update the table entry
copy(pre[i][j*8:], t1[:8])
}
if j == 0 {
p256PointDoubleAsm(t2, basePoint)
} else {
p256PointAddAsm(t2, t2, basePoint)
}
}
fmt.Fprint(buf, "const p256Precomputed = \"\" +\n\n")
// Dump the precomputed tables, flattened, little-endian.
// These tables are used directly by assembly on little-endian platforms.
// Putting the data in a const string lets it be stored readonly.
for i := range &pre {
for j, v := range &pre[i] {
fmt.Fprintf(buf, "\"")
var u8 [8]byte
binary.LittleEndian.PutUint64(u8[:], v)
for _, b := range &u8 {
fmt.Fprintf(buf, "\\x%02x", b)
}
fmt.Fprintf(buf, "\"")
if i < len(pre)-1 || j < len(pre[i])-1 {
fmt.Fprint(buf, "+")
}
if j%8 == 7 {
fmt.Fprint(buf, "\n")
}
}
fmt.Fprint(buf, "\n")
}
src := buf.Bytes()
fmtsrc, fmterr := format.Source(src)
// If formatting failed, keep the original source for debugging.
if fmterr == nil {
src = fmtsrc
}
fmt.Println(string(src))
}