/* 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 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2015, Intel Inc.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

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