|  | /* Copyright (c) 2018, Google Inc. | 
|  | * | 
|  | * Permission to use, copy, modify, and/or distribute this software for any | 
|  | * purpose with or without fee is hereby granted, provided that the above | 
|  | * copyright notice and this permission notice appear in all copies. | 
|  | * | 
|  | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 
|  | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 
|  | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | 
|  | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
|  | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | 
|  | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | 
|  | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ | 
|  |  | 
|  | package main | 
|  |  | 
|  | import ( | 
|  | "crypto/elliptic" | 
|  | "fmt" | 
|  | "math/big" | 
|  | "os" | 
|  | ) | 
|  |  | 
|  | const fileHeader = `/* Copyright (c) 2015, Intel Inc. | 
|  | * | 
|  | * Permission to use, copy, modify, and/or distribute this software for any | 
|  | * purpose with or without fee is hereby granted, provided that the above | 
|  | * copyright notice and this permission notice appear in all copies. | 
|  | * | 
|  | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 
|  | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 
|  | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | 
|  | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
|  | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | 
|  | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | 
|  | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ | 
|  |  | 
|  | // This is the precomputed constant time access table for the code in | 
|  | // p256-x86_64.c, for the default generator. The table consists of 37 | 
|  | // subtables, each subtable contains 64 affine points. The affine points are | 
|  | // encoded as eight uint64's, four for the x coordinate and four for the y. | 
|  | // Both values are in little-endian order. There are 37 tables because a | 
|  | // signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37. | 
|  | // Within each table there are 64 values because the 6-bit wNAF value can take | 
|  | // 64 values, ignoring the sign bit, which is implemented by performing a | 
|  | // negation of the affine point when required. We would like to align it to 2MB | 
|  | // in order to increase the chances of using a large page but that appears to | 
|  | // lead to invalid ELF files being produced. | 
|  |  | 
|  | // This file is generated by make_p256-x86_64-table.go. | 
|  |  | 
|  | static const alignas(4096) PRECOMP256_ROW ecp_nistz256_precomputed[37] = { | 
|  | ` | 
|  |  | 
|  | func main() { | 
|  | os.Stdout.WriteString(fileHeader) | 
|  |  | 
|  | scalar, tmp := new(big.Int), new(big.Int) | 
|  | p256 := elliptic.P256() | 
|  | p := p256.Params().P | 
|  |  | 
|  | // The wNAF windows are 7 bits wide, so advance across the 256-bit scalar | 
|  | // space in 7-bit increments. | 
|  | for shift := uint(0); shift < 256; shift += 7 { | 
|  | // For each window, encode 64 multiples of the base point. | 
|  | for multiple := 1; multiple <= 64; multiple++ { | 
|  | scalar.SetInt64(int64(multiple)) | 
|  | scalar.Lsh(scalar, shift) | 
|  |  | 
|  | x, y := p256.ScalarBaseMult(scalar.Bytes()) | 
|  |  | 
|  | toMontgomery(x, p) | 
|  | toMontgomery(y, p) | 
|  |  | 
|  | if multiple == 1 { | 
|  | os.Stdout.WriteString("        {{") | 
|  | } else { | 
|  | os.Stdout.WriteString("         {") | 
|  | } | 
|  | printNum(x, tmp) | 
|  |  | 
|  | os.Stdout.WriteString(",\n          ") | 
|  | printNum(y, tmp) | 
|  |  | 
|  | if multiple == 64 { | 
|  | os.Stdout.WriteString("}}") | 
|  | } else { | 
|  | os.Stdout.WriteString("},\n") | 
|  | } | 
|  | } | 
|  |  | 
|  | if shift+7 < 256 { | 
|  | os.Stdout.WriteString(",\n") | 
|  | } else { | 
|  | os.Stdout.WriteString("};\n") | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | var mask, R *big.Int | 
|  |  | 
|  | func init() { | 
|  | mask = new(big.Int).SetUint64(0xffffffffffffffff) | 
|  | R = new(big.Int).SetInt64(1) | 
|  | R.Lsh(R, 256) | 
|  | } | 
|  |  | 
|  | func printNum(n, tmp *big.Int) { | 
|  | fmt.Printf("{") | 
|  | for i := 0; i < 4; i++ { | 
|  | tmp.And(n, mask) | 
|  | limb := tmp.Uint64() | 
|  | fmt.Printf("TOBN(0x%08x, 0x%08x)", uint32(limb>>32), uint32(limb)) | 
|  | n.Rsh(n, 64) | 
|  |  | 
|  | switch i { | 
|  | case 0, 2: | 
|  | os.Stdout.WriteString(", ") | 
|  | case 1: | 
|  | os.Stdout.WriteString(",\n           ") | 
|  | } | 
|  | } | 
|  | fmt.Printf("}") | 
|  | } | 
|  |  | 
|  | // toMontgomery sets n to be n×R mod p | 
|  | func toMontgomery(n, p *big.Int) { | 
|  | n.Mul(n, R) | 
|  | n.Mod(n, p) | 
|  | } |