// 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.

//go:build ignore

package main

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"
	"io"
	"math/big"
)

var (
	p256                  elliptic.Curve
	zero, one, p, R, Rinv *big.Int
	deterministicRand     io.Reader
)

type coordinates int

const (
	affine coordinates = iota
	jacobian
)

func init() {
	p256 = elliptic.P256()

	zero = new(big.Int)
	one = new(big.Int).SetInt64(1)

	p = p256.Params().P

	R = new(big.Int)
	R.SetBit(R, 256, 1)
	R.Mod(R, p)

	Rinv = new(big.Int).ModInverse(R, p)

	deterministicRand = newDeterministicRand()
}

func modMul(z, x, y *big.Int) *big.Int {
	z.Mul(x, y)
	return z.Mod(z, p)
}

func toMontgomery(z, x *big.Int) *big.Int {
	return modMul(z, x, R)
}

func fromMontgomery(z, x *big.Int) *big.Int {
	return modMul(z, x, Rinv)
}

func isAffineInfinity(x, y *big.Int) bool {
	// Infinity, in affine coordinates, is represented as (0, 0) by
	// both Go, p256-x86_64-asm.pl and p256-armv8-asm.pl.
	return x.Sign() == 0 && y.Sign() == 0
}

func randNonZeroInt(max *big.Int) *big.Int {
	for {
		r, err := rand.Int(deterministicRand, max)
		if err != nil {
			panic(err)
		}
		if r.Sign() != 0 {
			return r
		}
	}
}

func randPoint() (x, y *big.Int) {
	k := randNonZeroInt(p256.Params().N)
	return p256.ScalarBaseMult(k.Bytes())
}

func toJacobian(xIn, yIn *big.Int) (x, y, z *big.Int) {
	if isAffineInfinity(xIn, yIn) {
		// The Jacobian representation of infinity has Z = 0. Depending
		// on the implementation, X and Y may be further constrained.
		// Generalizing the curve equation to Jacobian coordinates for
		// non-zero Z gives:
		//
		//   y² = x³ - 3x + b, where x = X/Z² and y = Y/Z³
		//   Y² = X³ + aXZ⁴ + bZ⁶
		//
		// Taking that formula at Z = 0 gives Y² = X³. This constraint
		// allows removing a special case in the point-on-curve check.
		//
		// BoringSSL, however, historically generated infinities with
		// arbitrary X and Y and include the special case. We also have
		// not verified that add and double preserve this
		// property. Thus, generate test vectors with unrelated X and Y,
		// to test that p256-x86_64-asm.pl and p256-armv8-asm.pl correctly
		// handle unconstrained representations of infinity.
		x = randNonZeroInt(p)
		y = randNonZeroInt(p)
		z = zero
		return
	}

	z = randNonZeroInt(p)

	// X = xZ²
	y = modMul(new(big.Int), z, z)
	x = modMul(new(big.Int), xIn, y)

	// Y = yZ³
	modMul(y, y, z)
	modMul(y, y, yIn)
	return
}

func printMontgomery(name string, a *big.Int) {
	a = toMontgomery(new(big.Int), a)
	fmt.Printf("%s = %064x\n", name, a)
}

func printTestCase(ax, ay *big.Int, aCoord coordinates, bx, by *big.Int, bCoord coordinates) {
	rx, ry := p256.Add(ax, ay, bx, by)

	var az *big.Int
	if aCoord == jacobian {
		ax, ay, az = toJacobian(ax, ay)
	} else if isAffineInfinity(ax, ay) {
		az = zero
	} else {
		az = one
	}

	var bz *big.Int
	if bCoord == jacobian {
		bx, by, bz = toJacobian(bx, by)
	} else if isAffineInfinity(bx, by) {
		bz = zero
	} else {
		bz = one
	}

	fmt.Printf("Test = PointAdd\n")
	printMontgomery("A.X", ax)
	printMontgomery("A.Y", ay)
	printMontgomery("A.Z", az)
	printMontgomery("B.X", bx)
	printMontgomery("B.Y", by)
	printMontgomery("B.Z", bz)
	printMontgomery("Result.X", rx)
	printMontgomery("Result.Y", ry)
	fmt.Printf("\n")
}

func main() {
	fmt.Printf("# ∞ + ∞ = ∞.\n")
	printTestCase(zero, zero, affine, zero, zero, affine)

	fmt.Printf("# ∞ + ∞ = ∞, with an alternate representation of ∞.\n")
	printTestCase(zero, zero, jacobian, zero, zero, jacobian)

	gx, gy := p256.Params().Gx, p256.Params().Gy
	fmt.Printf("# g + ∞ = g.\n")
	printTestCase(gx, gy, affine, zero, zero, affine)

	fmt.Printf("# g + ∞ = g, with an alternate representation of ∞.\n")
	printTestCase(gx, gy, affine, zero, zero, jacobian)

	fmt.Printf("# g + -g = ∞.\n")
	minusGy := new(big.Int).Sub(p, gy)
	printTestCase(gx, gy, affine, gx, minusGy, affine)

	fmt.Printf("# Test some random Jacobian sums.\n")
	for i := 0; i < 4; i++ {
		ax, ay := randPoint()
		bx, by := randPoint()
		printTestCase(ax, ay, jacobian, bx, by, jacobian)
	}

	fmt.Printf("# Test some random Jacobian doublings.\n")
	for i := 0; i < 4; i++ {
		ax, ay := randPoint()
		printTestCase(ax, ay, jacobian, ax, ay, jacobian)
	}

	fmt.Printf("# Test some random affine sums.\n")
	for i := 0; i < 4; i++ {
		ax, ay := randPoint()
		bx, by := randPoint()
		printTestCase(ax, ay, affine, bx, by, affine)
	}

	fmt.Printf("# Test some random affine doublings.\n")
	for i := 0; i < 4; i++ {
		ax, ay := randPoint()
		printTestCase(ax, ay, affine, ax, ay, affine)
	}
}

type deterministicRandom struct {
	stream cipher.Stream
}

func newDeterministicRand() io.Reader {
	block, err := aes.NewCipher(make([]byte, 128/8))
	if err != nil {
		panic(err)
	}
	stream := cipher.NewCTR(block, make([]byte, block.BlockSize()))
	return &deterministicRandom{stream}
}

func (r *deterministicRandom) Read(b []byte) (n int, err error) {
	for i := range b {
		b[i] = 0
	}
	r.stream.XORKeyStream(b, b)
	return len(b), nil
}
