Source file src/crypto/elliptic/gen_p256_table.go

     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 ignore
     6  
     7  package main
     8  
     9  import (
    10  	"crypto/elliptic"
    11  	"encoding/binary"
    12  	"log"
    13  	"os"
    14  )
    15  
    16  func main() {
    17  	// Generate precomputed p256 tables.
    18  	var pre [43][32 * 8]uint64
    19  	basePoint := []uint64{
    20  		0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, 0x18905f76a53755c6,
    21  		0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, 0x8571ff1825885d85,
    22  		0x0000000000000001, 0xffffffff00000000, 0xffffffffffffffff, 0x00000000fffffffe,
    23  	}
    24  	t1 := make([]uint64, 12)
    25  	t2 := make([]uint64, 12)
    26  	copy(t2, basePoint)
    27  	zInv := make([]uint64, 4)
    28  	zInvSq := make([]uint64, 4)
    29  	for j := 0; j < 32; j++ {
    30  		copy(t1, t2)
    31  		for i := 0; i < 43; i++ {
    32  			// The window size is 6 so we need to double 6 times.
    33  			if i != 0 {
    34  				for k := 0; k < 6; k++ {
    35  					elliptic.P256PointDoubleAsm(t1, t1)
    36  				}
    37  			}
    38  			// Convert the point to affine form. (Its values are
    39  			// still in Montgomery form however.)
    40  			elliptic.P256Inverse(zInv, t1[8:12])
    41  			elliptic.P256Sqr(zInvSq, zInv, 1)
    42  			elliptic.P256Mul(zInv, zInv, zInvSq)
    43  			elliptic.P256Mul(t1[:4], t1[:4], zInvSq)
    44  			elliptic.P256Mul(t1[4:8], t1[4:8], zInv)
    45  			copy(t1[8:12], basePoint[8:12])
    46  			// Update the table entry
    47  			copy(pre[i][j*8:], t1[:8])
    48  		}
    49  		if j == 0 {
    50  			elliptic.P256PointDoubleAsm(t2, basePoint)
    51  		} else {
    52  			elliptic.P256PointAddAsm(t2, t2, basePoint)
    53  		}
    54  	}
    55  
    56  	var bin []byte
    57  
    58  	// Dump the precomputed tables, flattened, little-endian.
    59  	// These tables are used directly by assembly on little-endian platforms.
    60  	// go:embedding the data into a string lets it be stored readonly.
    61  	for i := range &pre {
    62  		for _, v := range &pre[i] {
    63  			var u8 [8]byte
    64  			binary.LittleEndian.PutUint64(u8[:], v)
    65  			bin = append(bin, u8[:]...)
    66  		}
    67  	}
    68  
    69  	err := os.WriteFile("p256_asm_table.bin", bin, 0644)
    70  	if err != nil {
    71  		log.Fatal(err)
    72  	}
    73  }
    74  

View as plain text