boringssl/crypto/fipsmodule/ec/make_p256-x86_64-table.go
David Benjamin f18bd55240 Remove pointer cast in P-256 table.
We expect the table to have a slightly nested structure, so just
generate it that way. Avoid risking strict aliasing problems. Thanks to
Brian Smith for pointing this out.

Change-Id: Ie21610c4afab07a610d914265079135dba17b3b7
Reviewed-on: https://boringssl-review.googlesource.com/c/34264
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2019-01-15 00:16:17 +00:00

131 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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)
}