summaryrefslogtreecommitdiffstats
path: root/src/crypto/elliptic/gen_p256_table.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/elliptic/gen_p256_table.go')
-rw-r--r--src/crypto/elliptic/gen_p256_table.go73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/crypto/elliptic/gen_p256_table.go b/src/crypto/elliptic/gen_p256_table.go
new file mode 100644
index 0000000..0ebbc66
--- /dev/null
+++ b/src/crypto/elliptic/gen_p256_table.go
@@ -0,0 +1,73 @@
+// 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 ignore
+
+package main
+
+import (
+ "crypto/elliptic"
+ "encoding/binary"
+ "log"
+ "os"
+)
+
+func main() {
+ // Generate precomputed p256 tables.
+ var pre [43][32 * 8]uint64
+ basePoint := []uint64{
+ 0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6,
+ 0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, 0x8571ff1825885d85,
+ 0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe,
+ }
+ 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++ {
+ elliptic.P256PointDoubleAsm(t1, t1)
+ }
+ }
+ // Convert the point to affine form. (Its values are
+ // still in Montgomery form however.)
+ elliptic.P256Inverse(zInv, t1[8:12])
+ elliptic.P256Sqr(zInvSq, zInv, 1)
+ elliptic.P256Mul(zInv, zInv, zInvSq)
+ elliptic.P256Mul(t1[:4], t1[:4], zInvSq)
+ elliptic.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 {
+ elliptic.P256PointDoubleAsm(t2, basePoint)
+ } else {
+ elliptic.P256PointAddAsm(t2, t2, basePoint)
+ }
+ }
+
+ var bin []byte
+
+ // Dump the precomputed tables, flattened, little-endian.
+ // These tables are used directly by assembly on little-endian platforms.
+ // go:embedding the data into a string lets it be stored readonly.
+ for i := range &pre {
+ for _, v := range &pre[i] {
+ var u8 [8]byte
+ binary.LittleEndian.PutUint64(u8[:], v)
+ bin = append(bin, u8[:]...)
+ }
+ }
+
+ err := os.WriteFile("p256_asm_table.bin", bin, 0644)
+ if err != nil {
+ log.Fatal(err)
+ }
+}