package bn256

import (
	"fmt"
	"math/big"
	"testing"

	"xdx.jelly/xgcl/gmath"
)

func TestGenCurvePrecompute4(t *testing.T) {
	table := make([]*curvePoint, 0, 32)
	for i := 0; i < 16; i++ {
		c := &curvePoint{}
		c.SetInfinity()
		for j := 0; j < 4; j++ {
			t := &curvePoint{}
			k := new(big.Int)
			if (i>>j)&1 != 0 {
				k.Lsh(gmath.BigInt1, 64*uint(j))
				t.Mul(curveGen, k)
				c.Add(c, t)
			}
		}
		table = append(table, c)
	}
	for i := 0; i < 16; i++ {
		c := &curvePoint{}
		c.SetInfinity()
		for j := 0; j < 4; j++ {
			t := &curvePoint{}
			k := new(big.Int)
			if (i>>j)&1 != 0 {
				k.Lsh(gmath.BigInt1, 31+64*uint(j))
				t.Mul(curveGen, k)
				c.Add(c, t)
			}
		}
		table = append(table, c)
	}
	for _, x := range table {
		x.MakeAffine()
		fmt.Printf("&curvePoint{gfP{0x%x,0x%x,0x%x,0x%x},gfP{0x%x,0x%x,0x%x,0x%x},*newGFp(1),*newGFp(1)},\n", x.x[0], x.x[1], x.x[2], x.x[3], x.y[0], x.y[1], x.y[2], x.y[3])
	}
}

func TestGenCurvePrecompute8(t *testing.T) {
	table := make([]*curvePoint, 0, 256)
	for i := 0; i < 256; i++ {
		c := &curvePoint{}
		c.SetInfinity()
		for j := 0; j < 8; j++ {
			t := &curvePoint{}
			k := new(big.Int)
			if (i>>j)&1 != 0 {
				k.Lsh(gmath.BigInt1, 32*uint(j))
				t.Mul(curveGen, k)
				c.Add(c, t)
			}
		}
		table = append(table, c)
	}

	for _, x := range table {
		x.MakeAffine()
		//fmt.Println(x)
		fmt.Printf("&curvePoint{gfP{0x%x,0x%x,0x%x,0x%x},gfP{0x%x,0x%x,0x%x,0x%x},*newGFp(1),*newGFp(1)},\n",
			x.x[0], x.x[1], x.x[2], x.x[3],
			x.y[0], x.y[1], x.y[2], x.y[3])
	}
}

func TestGenTwistCurvePrecompute8(t *testing.T) {
	table := make([]*twistPoint, 0, 256)
	for i := 0; i < 256; i++ {
		c := &twistPoint{}
		c.SetInfinity()
		for j := 0; j < 8; j++ {
			t := &twistPoint{}
			k := new(big.Int)
			if (i>>j)&1 != 0 {
				k.Lsh(gmath.BigInt1, 32*uint(j))
				t.Mul(twistGen, k)
				c.Add(c, t)
			}
		}
		table = append(table, c)
	}

	for _, x := range table {
		x.MakeAffine()
		fmt.Println(x)
		//fmt.Printf("&twistPoint{gfP2{gfP{0x%x,0x%x,0x%x,0x%x},gfP{0x%x,0x%x,0x%x,0x%x}},gfP2{gfP{0x%x,0x%x,0x%x,0x%x},gfP{0x%x,0x%x,0x%x,0x%x}},gfP2{gfP{0},*newGFP(1)},gfP2{gfP{0},*newGFP(1)}},\n",
		//	x.x.x[0],x.x.x[1],x.x.x[2],x.x.x[3],
		//	x.x.y[0],x.x.y[1],x.x.y[2],x.x.y[3],
		//	x.y.x[0],x.y.x[1],x.y.x[2],x.y.x[3],
		//	x.y.y[0],x.y.y[1],x.y.y[2],x.y.y[3])
	}
}
