package sm9

import (
	"math/big"

	"xdx.jelly/xgcl/sm/sm9/errors"
	"xdx.jelly/xgcl/sm/sm9/internal/bn256"
)

const (
	// Sm9RefMaxBits defined in GMT 0018
	Sm9RefMaxBits = 256

	// Sm9RefMaxLen defined in GMT 0018
	Sm9RefMaxLen = (Sm9RefMaxBits + 7) / 8

	byteSize = Sm9RefMaxLen

	// Sm9Strict UnmarshalBinary check data strict
	Sm9Strict = false

	// hidSign 签名hid
	hidSign byte = 1

	// hidKeyExchange 密钥交换hid
	hidKeyExchange byte = 3

	// hidKeyEncapsule 密钥封装hid
	hidKeyEncapsule byte = 3

	// hidEncryption 加解密hid
	hidEncryption byte = 3
)

// G1 is the group G<sup>1</sup>
type G1 = bn256.G1

// G2 is the group G2
type G2 = bn256.G2

// GT is the group GT
type GT = bn256.GT

type PublicKey = []byte

var (
	// Pairing is the pairing funcition e: G1 x G2 -> GT.
	Pairing func(g1 *G1, g2 *G2) *GT    = bn256.Pair
	pairing func(e *GT, g1 *G1, g2 *G2) = bn256.PairLol

	// N is the group order of G1, G2 and GT
	N = bn256.N

	// P is the character of finite field where E lives.
	P = bn256.P

	g1Gen     *G1 = new(G1).ScalarBaseMult(new(big.Int).SetInt64(1))
	g2Gen     *G2 = new(G2).ScalarBaseMult(new(big.Int).SetInt64(1))
	gtGen     *GT = Pairing(g1Gen, g2Gen)
	nMinusOne     = new(big.Int).Sub(N, new(big.Int).SetInt64(1))
)

// ByteSize returns the size of the bytes number of order (which is 32).
func ByteSize() int {
	return byteSize
}

// OrderN return the order of group G1, G2 and GT
// Deprecated: use Order instead.
var OrderN = Order

// Order returns the order of group G1, G2 and GT.
func Order() *big.Int {
	return N
}

// Prime returns the character of finite field.
func Prime() *big.Int {
	return P
}

// G1Generator returns the generator of G1.
func G1Generator() *G1 {
	return g1Gen
}

// G2Generator returns the generator of G2.
func G2Generator() *G2 {
	return g2Gen
}

// GTGenerator returns the generator of GT.
func GTGenerator() *GT {
	return gtGen
}

var ErrKGCRebuildKey = errors.ErrKGCRebuildKey
