github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/sm2/gen_p256_table.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build amd64 6 // +build amd64 7 8 package sm2 9 10 import ( 11 "bytes" 12 "encoding/binary" 13 "fmt" 14 "go/format" 15 ) 16 17 //goland:noinspection GoUnusedExportedFunction 18 func GenTables() { 19 buf := new(bytes.Buffer) 20 _, err := fmt.Fprint(buf, ` 21 // Generated by gen_p256_table.go. DO NOT EDIT. 22 //go:build amd64 23 // +build amd64 24 25 package sm2 26 `[1:]) 27 if err != nil { 28 panic(err) 29 } 30 31 // Generate precomputed p256 tables. 32 var pre [43][32 * 8]uint64 33 basePoint := []uint64{ 34 0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05, 35 0xc1354e593c2d0ddd, 0xc1f5e5788d3295fa, 0x8d4cfb066e2a48f8, 0x63cd65d481d735bd, 36 0x0000000000000001, 0x00000000ffffffff, 0x0000000000000000, 0x0000000100000000, 37 } 38 t1 := make([]uint64, 12) 39 t2 := make([]uint64, 12) 40 copy(t2, basePoint) 41 zInv := make([]uint64, 4) 42 zInvSq := make([]uint64, 4) 43 for j := 0; j < 32; j++ { 44 copy(t1, t2) 45 for i := 0; i < 43; i++ { 46 // The window size is 6 so we need to double 6 times. 47 if i != 0 { 48 for k := 0; k < 6; k++ { 49 p256PointDoubleAsm(t1, t1) 50 } 51 } 52 // Convert the point to affine form. (Its values are 53 // still in Montgomery form however.) 54 p256Inverse(zInv, t1[8:12]) 55 p256Sqr(zInvSq, zInv, 1) 56 p256Mul(zInv, zInv, zInvSq) 57 p256Mul(t1[:4], t1[:4], zInvSq) 58 p256Mul(t1[4:8], t1[4:8], zInv) 59 copy(t1[8:12], basePoint[8:12]) 60 // Update the table entry 61 copy(pre[i][j*8:], t1[:8]) 62 } 63 if j == 0 { 64 p256PointDoubleAsm(t2, basePoint) 65 } else { 66 p256PointAddAsm(t2, t2, basePoint) 67 } 68 } 69 70 _, err = fmt.Fprint(buf, "const p256Precomputed = \"\" +\n\n") 71 if err != nil { 72 panic(err) 73 } 74 75 // Dump the precomputed tables, flattened, little-endian. 76 // These tables are used directly by assembly on little-endian platforms. 77 // Putting the data in a const string lets it be stored readonly. 78 for i := range &pre { 79 for j, v := range &pre[i] { 80 _, err := fmt.Fprintf(buf, "\"") 81 if err != nil { 82 panic(err) 83 } 84 var u8 [8]byte 85 binary.LittleEndian.PutUint64(u8[:], v) 86 for _, b := range &u8 { 87 _, err := fmt.Fprintf(buf, "\\x%02x", b) 88 if err != nil { 89 panic(err) 90 } 91 } 92 _, err = fmt.Fprintf(buf, "\"") 93 if err != nil { 94 panic(err) 95 } 96 fmt.Fprintf(buf, "\"") 97 if i < len(pre)-1 || j < len(pre[i])-1 { 98 fmt.Fprint(buf, "+") 99 } 100 if j%8 == 7 { 101 _, err := fmt.Fprint(buf, "\n") 102 if err != nil { 103 panic(err) 104 } 105 } 106 } 107 _, err := fmt.Fprint(buf, "\n") 108 if err != nil { 109 panic(err) 110 } 111 } 112 113 src := buf.Bytes() 114 fmtsrc, fmterr := format.Source(src) 115 // If formatting failed, keep the original source for debugging. 116 if fmterr == nil { 117 src = fmtsrc 118 } 119 fmt.Println(string(src)) 120 }