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  }