use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use std::fmt::Display;
pub trait Fq:
Copy
+ Neg<Output = Self>
+ Add<Output = Self>
+ AddAssign
+ Sub<Output = Self>
+ SubAssign
+ Mul<Output = Self>
+ MulAssign
+ Div<Output = Self>
+ DivAssign
+ Display
+ From<u32>
+ From<u64>
+ From<i32>
+ From<i64>
{
const ENCODED_LENGTH: usize;
const N: usize;
const ZERO: Self;
const ONE: Self;
const TWO: Self;
const THREE: Self;
const FOUR: Self;
const MINUS_ONE: Self;
fn is_zero(self) -> u32;
fn equals(self, rhs: &Self) -> u32;
fn set_neg(&mut self);
fn set_half(&mut self);
fn set_mul2(&mut self);
fn set_mul3(&mut self);
fn set_mul4(&mut self);
fn set_mul8(&mut self);
fn set_mul_small(&mut self, k: i32);
fn set_square(&mut self);
fn set_n_square(&mut self, n: u32);
fn set_invert(&mut self);
fn set_sqrt(&mut self) -> u32;
fn half(self) -> Self;
fn mul2(self) -> Self;
fn mul3(self) -> Self;
fn mul4(self) -> Self;
fn mul8(self) -> Self;
fn mul_small(self, k: i32) -> Self;
fn square(self) -> Self;
fn n_square(self, n: u32) -> Self;
fn invert(self) -> Self;
fn sqrt(self) -> (Self, u32);
fn legendre(self) -> i32;
fn is_square(self) -> u32;
fn batch_invert(xx: &mut [Self]);
fn set_select(&mut self, a: &Self, b: &Self, ctl: u32);
fn set_cond(&mut self, rhs: &Self, ctl: u32);
fn set_cond_neg(&mut self, ctl: u32);
fn select(a: &Self, b: &Self, ctl: u32) -> Self;
fn cond_swap(a: &mut Self, b: &mut Self, ctl: u32);
fn encode(self) -> [u8; Self::ENCODED_LENGTH];
fn decode(buf: &[u8]) -> (Self, u32);
fn decode_reduce(buf: &[u8]) -> Self;
fn hashcode(self) -> u64;
}
pub trait FqRoots: Fq {
fn set_fourth_root(&mut self) -> u32;
fn fourth_root(self) -> (Self, u32);
}
pub trait FqExp: Fq {
fn set_pow(&mut self, e: &[u8], ebitlen: usize);
fn set_pow_ext(&mut self, e: &[u8], eoff: usize, ebitlen: usize);
fn set_pow_u64(&mut self, e: u64, ebitlen: usize);
fn set_pow_pubexp(&mut self, e: &[u64; Self::N]);
fn set_pow_u64_vartime(&mut self, e: u64);
fn pow(self, e: &[u8], ebitlen: usize) -> Self;
fn pow_ext(self, e: &[u8], eoff: usize, ebitlen: usize) -> Self;
fn pow_u64(self, e: u64, ebitlen: usize) -> Self;
fn pow_u64_vartime(self, e: u64) -> Self;
fn pow_pubexp(self, e: &[u64; Self::N]) -> Self;
}
pub trait FqRnd: Fq {
fn set_rand<R: ::rand_core::CryptoRng + ::rand_core::RngCore>(&mut self, rng: &mut R);
fn rand<R: ::rand_core::CryptoRng + ::rand_core::RngCore>(rng: &mut R) -> Self;
}
pub trait Fp2: Fq + FqExp + FqRoots + FqRnd {
type BaseField: Fq;
const ZETA: Self;
const MINUS_ZETA: Self;
fn set_x0_small(&mut self, x: i32);
fn set_x1_small(&mut self, x: i32);
fn from_i32_pair(x0: i32, x1: i32) -> Self;
fn from_u32_pair(x0: u32, x1: u32) -> Self;
fn from_i64_pair(x0: i64, x1: i64) -> Self;
fn from_u64_pair(x0: u64, x1: u64) -> Self;
fn x0(self) -> Self::BaseField;
fn x1(self) -> Self::BaseField;
fn xi(self) -> (Self::BaseField, Self::BaseField);
fn set_conjugate(&mut self);
fn conjugate(self) -> Self;
fn is_square_base_field(self) -> u32;
fn precompute_dlp_tables(self, n: usize) -> (Vec<usize>, Vec<Self>, u32);
fn solve_dlp_2e(
self,
x: &Self,
e: usize,
precomputed_tables: Option<(&Vec<usize>, &Vec<Self>)>,
) -> (Vec<u8>, u32);
}