package gcltests

import (
	"bytes"
	"encoding/hex"

	"xdx.jelly/xgcl/grand"
	"xdx.jelly/xgcl/sm/sm2"
)

// 算法正确性测试
func hexDecode(s string) []byte {
	b, err := hex.DecodeString(s)
	if err != nil {
		panic(err)
	}
	return b
}

// SM2SignTest SM2签名算法正确性测试
func SM2SignTest() bool {
	// 先检测SM2签名验证
	if !SM2VerifyTest() {
		return false
	}
	sk := &sm2.PrivateKey{}
	sk.SetBytes(hexDecode("C242939DDAB6FCC07B6676C07D2DC117EC68A09142C25C008630B9756786162D"))

	pk := &sm2.PublicKey{}
	pk.SetBytes(hexDecode("5CA4E440C508C45FE7D758AB10C45D8237C4F9559F7D466185F295399F0AA37D59AD8A3CD17903287681BF9D21DA2EB316A0CE8FD41C89CE1E2B3F1B8E041ABA"))

	e := hexDecode("3854C463FA3F73783621B1CE4EF83F7C78048AAC79B221FCDD290866CC131174")

	sig, err := sm2.Sign(e, grand.GetRandom(32), sk)
	if err != nil {
		return false
	}
	return sm2.Verify(e, pk, sig)
}

// SM2VerifyTest SM2签名算法正确性测试
func SM2VerifyTest() bool {
	sk := &sm2.PrivateKey{}
	sk.SetBytes(hexDecode("C242939DDAB6FCC07B6676C07D2DC117EC68A09142C25C008630B9756786162D"))

	pk := &sm2.PublicKey{}
	pk.SetBytes(hexDecode("5CA4E440C508C45FE7D758AB10C45D8237C4F9559F7D466185F295399F0AA37D59AD8A3CD17903287681BF9D21DA2EB316A0CE8FD41C89CE1E2B3F1B8E041ABA"))

	e := hexDecode("3854C463FA3F73783621B1CE4EF83F7C78048AAC79B221FCDD290866CC131174")
	sig := &sm2.Signature{}
	sig.SetBytes(hexDecode("6E5DB49DBD0992B97040080A96003C721CDB9CF64C88D74321FC2F630ADF37742F6DFF453DFC8D7A506D3F52301BEE529E62FDDD38948F0D5D2CBCBC55900CFA"))

	return sm2.Verify(e, pk, sig)
}

func SM2DecryptionTest() bool {
	sk := &sm2.PrivateKey{}
	sk.SetBytes(hexDecode("E7CB09606A53320B347F61F3F142DCB118F723A9BC27879F2805BE778F24AEE5"))

	pk := &sm2.PublicKey{}
	pk.SetBytes(hexDecode("C4F7D581BEFEF25C8BBB6DAD52A6AB8234FA7DB7A988592BC592DAF2BE630647E3746788CBDC59042D85260DD48B6A7347D82C5314E8AC261588A33151DFCA17"))

	msg := hexDecode("31323334353637383132333435363738")

	cipher := &sm2.Cipher{}
	cipher.SetBytes(hexDecode("0E09E2BC01614B47F906C2A5F7F660F09DD2207B70E4AEF1B600A65BF273D0B1932E76AD4CE56EC20ED1D8F373E7E5AB09E2248104C7E7023D688F716730180DEF894C493E8D338D091F0F98F23A87AFE4E8AAA4F4FB4BE135B9A1B2073157B66B68E3ADFD914B61E61BA1FC65E5038D"))

	plain, err := sm2.Decrypt(sk, cipher)
	if err != nil {
		return false
	}
	if !bytes.Equal(msg, plain) {
		return false
	}
	return true
}

func SM2EncryptionTest() bool {
	// 先进行SM2解密测试
	if !SM2DecryptionTest() {
		return false
	}

	sk := &sm2.PrivateKey{}
	sk.SetBytes(hexDecode("E7CB09606A53320B347F61F3F142DCB118F723A9BC27879F2805BE778F24AEE5"))

	pk := &sm2.PublicKey{}
	pk.SetBytes(hexDecode("C4F7D581BEFEF25C8BBB6DAD52A6AB8234FA7DB7A988592BC592DAF2BE630647E3746788CBDC59042D85260DD48B6A7347D82C5314E8AC261588A33151DFCA17"))

	msg := hexDecode("31323334353637383132333435363738")
	cipher, err := sm2.Encrypt(pk, msg, grand.GetRandom(32))
	if err != nil {
		return false
	}

	plain, err := sm2.Decrypt(sk, cipher)
	if err != nil {
		return false
	}
	if !bytes.Equal(msg, plain) {
		return false
	}
	return true
}
