use cryptix_field::field::montgomery::MontgomeryOps;
use super::fp12::Fp12Element;
#[derive(Debug, Clone, Copy)]
pub struct Fp12Clotomic(Fp12Element);
impl From<Fp12Clotomic> for Fp12Element {
fn from(value: Fp12Clotomic) -> Self {
value.0
}
}
impl Fp12Clotomic {
pub const unsafe fn new_unchecked(value: Fp12Element) -> Self {
Self(value)
}
pub fn clotomic_inv(self) -> Self {
let mut tmp = self.0;
tmp.0.1 = -tmp.0.1;
tmp.1.0 = -tmp.1.0;
tmp.2.1 = -tmp.2.1;
Self(tmp)
}
pub fn clotomic_sqr(self) -> Self {
let a = self.0;
let t1 = a.0.mont_sqr();
let c0 = t1 + t1 + t1;
let t1 = a.0.conjugate();
let c0 = c0 - (t1 + t1);
let t1 = a.1.conjugate();
let c1 = t1 + t1;
let t1 = a.2.mont_sqr().mul_s();
let t2 = t1 + t1 + t1;
let c1 = c1 + t2;
let t1 = a.1.mont_sqr();
let c2 = t1 + t1 + t1;
let t1 = a.2.conjugate();
let c2 = c2 - (t1 + t1);
Self(Fp12Element(c0, c1, c2))
}
pub fn mont_mul(self, rhs: Self) -> Self {
Fp12Clotomic(self.0.mont_mul(rhs.0))
}
pub fn mont_form(self) -> Self {
Fp12Clotomic(self.0.mont_form())
}
pub fn map_frob(self) -> Self {
Self(self.0.map_frob())
}
pub fn map2_frob(self) -> Self {
Self(self.0.map2_frob())
}
pub fn exp_const(self) -> Self {
let mut r = self.clotomic_sqr().clotomic_sqr(); let a8 = r.clotomic_sqr(); for _ in 0..8 {
r = r.clotomic_sqr()
} r = r.mont_mul(a8);
for _ in 0..52 {
r = r.clotomic_sqr()
}
r.mont_mul(self)
}
}