package gcltests

import (
	"bytes"

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

// SM2协同签名密钥生成
func SM2TPCKeyGenTest() bool {
	// 先进行SM2签名验证测试
	if !SM2VerifyTest() {
		return false
	}
	// 生成签名密钥分量和公钥
	serverKeyCtx := sm2a.NewServerSignKeyGenContext()
	clientKeyCtx := sm2a.NewClientSignKeyGenContext(grand.Reader)

	buf, err := serverKeyCtx.ServerGenKey_one(grand.Reader)
	if err != nil {
		return false
	}
	buf, err = clientKeyCtx.ClientKeyGen_one(buf)
	if err != nil {
		return false
	}
	buf, err = serverKeyCtx.ServerGenKey_two(buf, grand.Reader)
	if err != nil {
		return false
	}
	buf, err = clientKeyCtx.ClientKeyGen_two(buf)
	if err != nil {
		return false
	}
	err = serverKeyCtx.ServerGenKey_three(buf)
	if err != nil {
		return false
	}
	dc, _ := clientKeyCtx.GetClientKey()  // 客户端私钥分量
	ds, _ := serverKeyCtx.GetServerKey()  // 服务端私钥分量
	pkc, _ := clientKeyCtx.GetPublicKey() // 客户端公钥
	pks, _ := serverKeyCtx.GetPublicKey() // 服务端公钥
	if !pkc.Equals(pks) {
		return false
	}
	pk := pkc

	// 协同计算签名
	e := hexDecode("6F18CAF30D3E0C2F1C59DE6080BA23AF2F4DD49DE5173C4579B8A7FE03A57096")
	clientSign := sm2a.NewClientSignContext(pk, grand.Reader)
	buf, _ = clientSign.Initial(e)
	buf, _ = sm2a.ServerSign(ds, pk, buf, grand.Reader)
	sig, _ := clientSign.Final(dc, buf)

	// 签名验证
	if !sm2.Verify(e, pk, sig) {
		return false
	}
	return true
}

// SM2协同签名验证
func SM2TPCSignTest() bool {
	// 先进行SM2签名验证测试
	if !SM2VerifyTest() {
		return false
	}
	dc := &sm2.PrivateKey{}
	dc.SetBytes(hexDecode("5F16B93817200830863BB55A523E131563C639880DA8D5F663C9CA32E872C621"))

	ds := &sm2.PrivateKey{}
	ds.SetBytes(hexDecode("5749BD354348F66F9905254E784C97BDE700DB7968219829F2DB5EC80D0AB0DF"))
	pk := &sm2.PublicKey{}
	pk.SetBytes(hexDecode("C31ED61795626AA8D8D26BB17359160F3CCB63786D50DF2C350C9DD27539DBDA5C2D7FAE4D9360CC77F9C0F7E66DB80ED35CF9969E68A0496BE1120020A4396A"))

	// 协同计算签名
	e := hexDecode("6F18CAF30D3E0C2F1C59DE6080BA23AF2F4DD49DE5173C4579B8A7FE03A57096")
	clientSign := sm2a.NewClientSignContext(pk, grand.Reader)
	buf, _ := clientSign.Initial(e)
	buf, _ = sm2a.ServerSign(ds, pk, buf, grand.Reader)
	sig, _ := clientSign.Final(dc, buf)

	// 签名验证
	if !sm2.Verify(e, pk, sig) {
		return false
	}
	return true
}

// SM2协同解密验证
func SM2TPCDecTest() bool {
	if !SM2EncryptionTest() {
		return false
	}
	dc := &sm2.PrivateKey{}
	dc.SetBytes(hexDecode("A17EE7749FC8882D876A1CCE1BCAB13A4F42E28E7EA30B6E81CD068806FE943C"))

	ds := &sm2.PrivateKey{}
	ds.SetBytes(hexDecode("566760699576E8B3882489B7FB9ED0DE4B467260665156EC131665D929684309"))
	pk := &sm2.PublicKey{}
	pk.SetBytes(hexDecode("2B2E90C71D9B16CC4F33D1775E76F5D7C0F283F2D7123504B718788FA38FDB2BBF7F7D94683C498947F365C91C42D7BDC10159E092C158B97BE7B035868949F8"))

	stdPlain := hexDecode("31323334353637383132333435363738")
	cipher := &sm2.Cipher{}
	cipher.SetBytes(hexDecode("A098DB078468335D160DCE7A8876B88D56E16173421E96D455FED5039BB3A2F9E4E940F2BA4644C230E63087974EDA8B9C22B0FB116809395060FA73F970D5B3BB43CEDBABC75E8F4F925DC1B58DC9243B4A92668FBA980E4C73DA579B360479A1EEEAEE29BFBD171821EAECBECE675B"))

	// 协同解密
	clientDecCtx := sm2a.NewClientDecContext()
	buf, _ := clientDecCtx.Decrypt_one(cipher)
	buf, _ = sm2a.ServerDecrypt(buf, ds)
	plain, _ := clientDecCtx.Decrypt_two(buf, dc)

	if !bytes.Equal(plain, stdPlain) {
		return false
	}
	return true
}
