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