• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* Copyright (c) 2018, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15package main
16
17import (
18	"crypto/elliptic"
19	"fmt"
20	"math/big"
21	"os"
22)
23
24const fileHeader = `/* Copyright (c) 2015, Intel Inc.
25 *
26 * Permission to use, copy, modify, and/or distribute this software for any
27 * purpose with or without fee is hereby granted, provided that the above
28 * copyright notice and this permission notice appear in all copies.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
31 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
32 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
33 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
35 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
36 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
37
38// This is the precomputed constant time access table for the code in
39// p256-x86_64.c, for the default generator. The table consists of 37
40// subtables, each subtable contains 64 affine points. The affine points are
41// encoded as eight uint64's, four for the x coordinate and four for the y.
42// Both values are in little-endian order. There are 37 tables because a
43// signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37.
44// Within each table there are 64 values because the 6-bit wNAF value can take
45// 64 values, ignoring the sign bit, which is implemented by performing a
46// negation of the affine point when required. We would like to align it to 2MB
47// in order to increase the chances of using a large page but that appears to
48// lead to invalid ELF files being produced.
49
50// This file is generated by make_p256-x86_64-table.go.
51
52static const alignas(4096) PRECOMP256_ROW ecp_nistz256_precomputed[37] = {
53`
54
55func main() {
56	os.Stdout.WriteString(fileHeader)
57
58	scalar, tmp := new(big.Int), new(big.Int)
59	p256 := elliptic.P256()
60	p := p256.Params().P
61
62	// The wNAF windows are 7 bits wide, so advance across the 256-bit scalar
63	// space in 7-bit increments.
64	for shift := uint(0); shift < 256; shift += 7 {
65		// For each window, encode 64 multiples of the base point.
66		for multiple := 1; multiple <= 64; multiple++ {
67			scalar.SetInt64(int64(multiple))
68			scalar.Lsh(scalar, shift)
69
70			x, y := p256.ScalarBaseMult(scalar.Bytes())
71
72			toMontgomery(x, p)
73			toMontgomery(y, p)
74
75			if multiple == 1 {
76				os.Stdout.WriteString("        {{")
77			} else {
78				os.Stdout.WriteString("         {")
79			}
80			printNum(x, tmp)
81
82			os.Stdout.WriteString(",\n          ")
83			printNum(y, tmp)
84
85			if multiple == 64 {
86				os.Stdout.WriteString("}}")
87			} else {
88				os.Stdout.WriteString("},\n")
89			}
90		}
91
92		if shift+7 < 256 {
93			os.Stdout.WriteString(",\n")
94		} else {
95			os.Stdout.WriteString("};\n")
96		}
97	}
98}
99
100var mask, R *big.Int
101
102func init() {
103	mask = new(big.Int).SetUint64(0xffffffffffffffff)
104	R = new(big.Int).SetInt64(1)
105	R.Lsh(R, 256)
106}
107
108func printNum(n, tmp *big.Int) {
109	fmt.Printf("{")
110	for i := 0; i < 4; i++ {
111		tmp.And(n, mask)
112		limb := tmp.Uint64()
113		fmt.Printf("TOBN(0x%08x, 0x%08x)", uint32(limb>>32), uint32(limb))
114		n.Rsh(n, 64)
115
116		switch i {
117		case 0, 2:
118			os.Stdout.WriteString(", ")
119		case 1:
120			os.Stdout.WriteString(",\n           ")
121		}
122	}
123	fmt.Printf("}")
124}
125
126// toMontgomery sets n to be n×R mod p
127func toMontgomery(n, p *big.Int) {
128	n.Mul(n, R)
129	n.Mod(n, p)
130}
131