package common

const (
	// corresponds to words in P751
	FpMaxWords = 12
	// corresponds to byte size of P751 SIDH private key for B
	MaxSidhPrivateKeyBsz = 48
	// corresponds to byte size of P751 SIKE private key for B
	MaxSikePrivateKeyBsz = MaxSidhPrivateKeyBsz + MaxMsgBsz
	// corresponds to SIKE max length of 'n' (see 1.4 of SIKE spec in NIST PQC round 1)
	MaxMsgBsz = 40
	// corresponds to byte size of shared secret generated by SIKEp751
	MaxSharedSecretBsz = 188
	// correponds to by size of the P751 public key
	MaxPublicKeySz = 3 * FpMaxWords * 64
	// correponds to by size of the ciphertext produced by SIKE/P751
	MaxCiphertextBsz = MaxMsgBsz + MaxPublicKeySz
)

// Id's correspond to bitlength of the prime field characteristic
// Currently Fp751 is the only one supported by this implementation
const (
	Fp503 uint8 = iota
	Fp751
	Fp434
)

// Representation of an element of the base field F_p.
//
// No particular meaning is assigned to the representation -- it could represent
// an element in Montgomery form, or not.  Tracking the meaning of the field
// element is left to higher types.
type Fp [FpMaxWords]uint64

// Represents an intermediate product of two elements of the base field F_p.
type FpX2 [2 * FpMaxWords]uint64

// Represents an element of the extended field Fp^2 = Fp(x+i)
type Fp2 struct {
	A Fp
	B Fp
}

type DomainParams struct {
	// P, Q and R=P-Q base points
	AffineP, AffineQ, AffineR Fp2
	// Size of a compuatation strategy for x-torsion group
	IsogenyStrategy []uint32
	// Max size of secret key for x-torsion group
	SecretBitLen uint
	// Max size of secret key for x-torsion group
	SecretByteLen uint
}

type SidhParams struct {
	ID uint8
	// Bytelen of P
	Bytelen int
	// The public key size, in bytes.
	PublicKeySize int
	// The shared secret size, in bytes.
	SharedSecretSize int
	// 2- and 3-torsion group parameter definitions
	A, B DomainParams
	// Precomputed identity element in the Fp2 in Montgomery domain
	OneFp2 Fp2
	// Precomputed 1/2 in the Fp2 in Montgomery domain
	HalfFp2 Fp2
	// Length of SIKE secret message. Must be one of {24,32,40},
	// depending on size of prime field used (see [SIKE], 1.4 and 5.1)
	MsgLen int
	// Length of SIKE ephemeral KEM key (see [SIKE], 1.4 and 5.1)
	KemSize int
	// Byte size of ciphertext that KEM produces
	CiphertextSize int
	// Defines A,C constant for starting curve Cy^2 = x^3 + Ax^2 + x
	InitCurve ProjectiveCurveParameters
}

// Stores curve projective parameters equivalent to A/C. Meaning of the
// values depends on the context. When working with isogenies over
// subgroup that are powers of:
// * three then  (A:C) ~ (A+2C:A-2C)
// * four then   (A:C) ~ (A+2C:  4C)
// See Appendix A of SIKE for more details
type CurveCoefficientsEquiv struct {
	A Fp2
	C Fp2
}

// A point on the projective line P^1(F_{p^2}).
//
// This represents a point on the Kummer line of a Montgomery curve.  The
// curve is specified by a ProjectiveCurveParameters struct.
type ProjectivePoint struct {
	X Fp2
	Z Fp2
}

// A point on the projective line P^1(F_{p^2}).
//
// This is used to work projectively with the curve coefficients.
type ProjectiveCurveParameters struct {
	A Fp2
	C Fp2
}
