package sm2

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"math/big"
	"testing"

	"xdx.jelly/xgcl/grand"
)

func TestKeyExchange(t *testing.T) {
	sponsorID := []byte("Sponsor")
	responsorID := []byte("Responsor")
	// Set random test data
	ska, _ := GenPrivateKey(nil)
	skb, _ := GenPrivateKey(nil)

	// 使用默认id传入nil或GetDefaultID
	s := NewSponsor(sponsorID, ska)
	rs := NewResponsor(responsorID, skb)
	// NEVER FORGET CLEAR
	defer ska.Clear()
	defer skb.Clear()
	defer s.Clear()
	defer rs.Clear()

	// 多次密钥交换是可以重复使用Sponsor和Responsor的-只要其私钥和id不变
	for keylen := 1; keylen < 256; keylen++ {
		// t.Log("key exchange test for key length = ", keylen)

		// key exchange
		tempKeyOfSponsor, _ := s.GenerateAgreementData(nil)
		keyOfResponsor, tempKeyOfResponsor, _ := rs.GenerateAgreementDataAndKey(sponsorID, GenPublicKey(ska), tempKeyOfSponsor, keylen, nil)
		keyOfSponsor, _ := s.GenerateKey(responsorID, GenPublicKey(skb), tempKeyOfResponsor, keylen)

		// check if OK
		printlen := 32
		if keylen < printlen {
			printlen = keylen
		}
		// t.Log("responsor: ", hex.EncodeToString(keyOfResponsor[:printlen]), "...")
		// t.Log("sponsor  : ", hex.EncodeToString(keyOfSponsor[:printlen]), "...")
		if bytes.Compare(keyOfResponsor, keyOfSponsor) != 0 {
			t.Fail()
			return
		}
		// t.Log("OK\n")

	}
}

func TestKeyExchange2(t *testing.T) {
	sponsorID := []byte("Alice")
	responsorID := []byte("Bob")
	// Set random test data
	ska, _ := GenPrivateKey(nil)
	skb, _ := GenPrivateKey(nil)
	aliceC := new(big.Int)
	aliceC.SetString("0f136aaf135e03c43ed91131f45ea81d1defdef283efbd8493c4769886a6c677", 16)
	aliceS := new(big.Int)
	aliceS.SetString("70f88a29a9664d41f0aadb56b5802c116c4b6c69075550e246f2e6a168a157e9", 16)
	bobC := new(big.Int)
	bobC.SetString("0c16e4a0fe04131454dccf03243492c95f0126b71a5d804c7d11fc899d4ab9b2", 16)
	bobS := new(big.Int)
	bobS.SetString("f4b87de5b4c6559cd09d5539b3cd1a41eb898dbf9397af33b5e6afa4c7bd4c71", 16)

	N := sm2Curve.Params().N
	ska.D.Add(aliceC, aliceS)
	ska.D.Mod(ska.D, N)
	skb.D.Add(bobC, bobS)
	skb.D.Mod(skb.D, N)

	// 使用默认id传入nil或GetDefaultID
	s := NewSponsor(sponsorID, ska)
	rs := NewResponsor(responsorID, skb)
	// NEVER FORGET CLEAR
	defer ska.Clear()
	defer skb.Clear()
	defer s.Clear()
	defer rs.Clear()

	// 多次密钥交换是可以重复使用Sponsor和Responsor的-只要其私钥和id不变

	// t.Log("key exchange test for key length = ", keylen)
	keylen := 32
	// key exchange
	tempKeyOfSponsor, _ := s.GenerateAgreementData(nil)

	keyOfResponsor, tempKeyOfResponsor, _ := rs.GenerateAgreementDataAndKey(sponsorID, GenPublicKey(ska), tempKeyOfSponsor, keylen, nil)
	keyOfSponsor, _ := s.GenerateKey(responsorID, GenPublicKey(skb), tempKeyOfResponsor, keylen)
	fmt.Println("Ra=", tempKeyOfSponsor)
	fmt.Println("Rb=", tempKeyOfResponsor)
	// check if OK
	t.Log("responsor: ", hex.EncodeToString(keyOfResponsor[:]), "...")
	t.Log("sponsor  : ", hex.EncodeToString(keyOfSponsor[:]), "...")
	if bytes.Compare(keyOfResponsor, keyOfSponsor) != 0 {
		t.Fail()
		return

		// t.Log("OK\n")

	}
}

func TestKeyExchange3(t *testing.T) {
	ida := []byte("Sponsor")
	idb := []byte("Responsor")
	ska, _ := GenerateKey(Curve(), grand.Reader)
	skb, _ := GenerateKey(Curve(), grand.Reader)
	keyLen := 64

	pa, err := GenerateAgreementData(grand.Reader)
	if err != nil {
		t.Fatal("GenerateAgreementData: " + err.Error())
	}
	kb, pb, err := GenerateAgreementDataAndKey(idb, skb, ida, &ska.PublicKey, pa.PublicKey(), keyLen, grand.Reader)
	if err != nil {
		t.Fatal("GenerateAgreementDataAndKey: " + err.Error())
	}
	ka, err := GenerateSharedKey(pa, ida, ska, idb, &skb.PublicKey, pb.PublicKey(), keyLen)
	if err != nil {
		t.Fatal("GenerateSharedKey: " + err.Error())
	}
	if bytes.Compare(ka, kb) != 0 {
		t.Fatal("bytes.Compare not equal")
		return
	}
}

//x2rb=  4218415632c9e1dc64847e0eec2d389fabc363a050323e55c577ffc134b46014
//x1Ra=  a8e1a22f6684166804e1b9618f021306398669caded533f0cb22ddcbe6b07b1b 9b0cb1c02167fa8f449b03b8972b26689b2fdba41b5ea29ce3091882a96e6270
//响应方V=  ca53c881f2fc9d4863f8e484482ee029dcb1ee9f2f0001327d8140267ada7f37 80c869a8cab20c73ca497aba68a6574e5371b964fb8727682c66abacd848e45d
//x1ra=  d9231754b214e5d6adc81e2dbde50a777ad7d0609020f566dc8a91f2b2a4621f
//x2Rb=  2a223af3c1012c753ab4f4aa51f1d9388e016c5a925715be1632d1710825043e c555b658c20d17a32dccb421f044bb26b4ad53c3ca574fe4999cdb8a2e582016

func TestU(t *testing.T) {
	ux := new(big.Int)
	ux.SetString("76c72b6b721c07e98a179e37bfd8f871276abe81e3097a44883394fac89ff3fd", 16)
	uy := new(big.Int)
	uy.SetString("663085bc7794789eb4593b8b8a7abf422e4acf5ec475b7078c5baf03b3a115b8", 16)
	aliceC := new(big.Int)
	aliceC.SetString("0f136aaf135e03c43ed91131f45ea81d1defdef283efbd8493c4769886a6c677", 16)
	aliceS := new(big.Int)
	aliceS.SetString("70f88a29a9664d41f0aadb56b5802c116c4b6c69075550e246f2e6a168a157e9", 16)
	bobC := new(big.Int)
	bobC.SetString("0c16e4a0fe04131454dccf03243492c95f0126b71a5d804c7d11fc899d4ab9b2", 16)
	bobS := new(big.Int)
	bobS.SetString("f4b87de5b4c6559cd09d5539b3cd1a41eb898dbf9397af33b5e6afa4c7bd4c71", 16)

	x, y := sm2Curve.ScalarMult(ux, uy, aliceS.Bytes())
	fmt.Println("发起方服务端返回数据= ", x.Text(16), y.Text(16))

	ux.SetString("21c77774c165bcc3c128908a9128acd63418accfed1a4699e34bd09ed80915f7", 16)
	uy.SetString("f69ea4620a47dfb40957b80f675de2304893c4dd00cad15aa6aaa16bbd023ca7", 16)
	x, y = sm2Curve.ScalarMult(ux, uy, aliceS.Bytes())
	fmt.Println("响应方服务端返回数据= ", x.Text(16), y.Text(16))
}
