2021-04-21 22:31:45 +02:00
|
|
|
use std::fmt::{Debug, Display};
|
2021-04-04 11:35:58 -07:00
|
|
|
use std::hash::Hash;
|
2021-04-23 10:26:57 -07:00
|
|
|
use std::iter::{Product, Sum};
|
2021-04-21 22:31:45 +02:00
|
|
|
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-04-25 18:09:43 -07:00
|
|
|
use num::Integer;
|
2021-04-23 10:26:57 -07:00
|
|
|
use rand::Rng;
|
2021-04-25 18:09:43 -07:00
|
|
|
use rand::rngs::OsRng;
|
2021-04-23 10:26:57 -07:00
|
|
|
|
|
|
|
|
use crate::util::bits_u64;
|
|
|
|
|
|
2021-02-09 21:25:21 -08:00
|
|
|
/// A finite field with prime order less than 2^64.
|
2021-04-21 22:31:45 +02:00
|
|
|
pub trait Field:
|
|
|
|
|
'static
|
|
|
|
|
+ Copy
|
|
|
|
|
+ Eq
|
|
|
|
|
+ Hash
|
|
|
|
|
+ Neg<Output = Self>
|
|
|
|
|
+ Add<Self, Output = Self>
|
|
|
|
|
+ AddAssign<Self>
|
2021-04-23 10:26:57 -07:00
|
|
|
+ Sum
|
2021-04-21 22:31:45 +02:00
|
|
|
+ Sub<Self, Output = Self>
|
|
|
|
|
+ SubAssign<Self>
|
|
|
|
|
+ Mul<Self, Output = Self>
|
|
|
|
|
+ MulAssign<Self>
|
2021-04-23 10:26:57 -07:00
|
|
|
+ Product
|
2021-04-21 22:31:45 +02:00
|
|
|
+ Div<Self, Output = Self>
|
|
|
|
|
+ DivAssign<Self>
|
|
|
|
|
+ Debug
|
|
|
|
|
+ Display
|
|
|
|
|
+ Send
|
|
|
|
|
+ Sync
|
|
|
|
|
{
|
2021-02-09 21:25:21 -08:00
|
|
|
const ZERO: Self;
|
|
|
|
|
const ONE: Self;
|
2021-02-26 13:18:41 -08:00
|
|
|
const TWO: Self;
|
2021-02-09 21:25:21 -08:00
|
|
|
const NEG_ONE: Self;
|
|
|
|
|
|
2021-03-30 23:12:47 -07:00
|
|
|
const ORDER: u64;
|
2021-04-02 19:04:26 -07:00
|
|
|
const TWO_ADICITY: usize;
|
|
|
|
|
|
|
|
|
|
/// Generator of the entire multiplicative group, i.e. all non-zero elements.
|
|
|
|
|
const MULTIPLICATIVE_GROUP_GENERATOR: Self;
|
|
|
|
|
/// Generator of a multiplicative subgroup of order `2^TWO_ADICITY`.
|
|
|
|
|
const POWER_OF_TWO_GENERATOR: Self;
|
2021-03-30 13:30:31 -07:00
|
|
|
|
2021-03-30 23:12:47 -07:00
|
|
|
fn is_zero(&self) -> bool {
|
|
|
|
|
*self == Self::ZERO
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-23 10:26:57 -07:00
|
|
|
fn is_nonzero(&self) -> bool {
|
|
|
|
|
*self != Self::ZERO
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-30 23:12:47 -07:00
|
|
|
fn is_one(&self) -> bool {
|
|
|
|
|
*self == Self::ONE
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-02 17:49:51 -07:00
|
|
|
fn square(&self) -> Self {
|
2021-03-30 23:12:47 -07:00
|
|
|
*self * *self
|
|
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-03-30 23:12:47 -07:00
|
|
|
fn cube(&self) -> Self {
|
|
|
|
|
*self * *self * *self
|
|
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
|
|
|
|
|
/// Compute the multiplicative inverse of this field element.
|
2021-02-17 22:19:18 -08:00
|
|
|
fn try_inverse(&self) -> Option<Self>;
|
|
|
|
|
|
|
|
|
|
fn inverse(&self) -> Self {
|
|
|
|
|
self.try_inverse().expect("Tried to invert zero")
|
|
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-03-30 13:30:31 -07:00
|
|
|
fn batch_multiplicative_inverse(x: &[Self]) -> Vec<Self> {
|
|
|
|
|
// This is Montgomery's trick. At a high level, we invert the product of the given field
|
|
|
|
|
// elements, then derive the individual inverses from that via multiplication.
|
|
|
|
|
|
|
|
|
|
let n = x.len();
|
|
|
|
|
if n == 0 {
|
|
|
|
|
return Vec::new();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut a = Vec::with_capacity(n);
|
|
|
|
|
a.push(x[0]);
|
|
|
|
|
for i in 1..n {
|
|
|
|
|
a.push(a[i - 1] * x[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut a_inv = vec![Self::ZERO; n];
|
|
|
|
|
a_inv[n - 1] = a[n - 1].try_inverse().expect("No inverse");
|
|
|
|
|
for i in (0..n - 1).rev() {
|
|
|
|
|
a_inv[i] = x[i + 1] * a_inv[i + 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut x_inv = Vec::with_capacity(n);
|
|
|
|
|
x_inv.push(a_inv[0]);
|
|
|
|
|
for i in 1..n {
|
|
|
|
|
x_inv.push(a[i - 1] * a_inv[i]);
|
|
|
|
|
}
|
|
|
|
|
x_inv
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-23 10:26:57 -07:00
|
|
|
fn primitive_root_of_unity(n_log: usize) -> Self {
|
|
|
|
|
assert!(n_log <= Self::TWO_ADICITY);
|
2021-04-25 18:09:43 -07:00
|
|
|
let mut base = Self::POWER_OF_TWO_GENERATOR;
|
|
|
|
|
for _ in n_log..Self::TWO_ADICITY {
|
|
|
|
|
base = base.square();
|
|
|
|
|
}
|
|
|
|
|
base
|
2021-04-02 19:04:26 -07:00
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-04-04 11:35:58 -07:00
|
|
|
/// Computes a multiplicative subgroup whose order is known in advance.
|
2021-04-02 19:04:26 -07:00
|
|
|
fn cyclic_subgroup_known_order(generator: Self, order: usize) -> Vec<Self> {
|
2021-04-04 11:35:58 -07:00
|
|
|
let mut subgroup = Vec::with_capacity(order);
|
2021-04-02 19:04:26 -07:00
|
|
|
let mut current = Self::ONE;
|
|
|
|
|
for _i in 0..order {
|
|
|
|
|
subgroup.push(current);
|
2021-04-23 12:35:19 -07:00
|
|
|
current *= generator;
|
2021-04-02 19:04:26 -07:00
|
|
|
}
|
|
|
|
|
subgroup
|
|
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
|
2021-04-22 21:12:34 -07:00
|
|
|
fn cyclic_subgroup_unknown_order(generator: Self) -> Vec<Self> {
|
|
|
|
|
let mut subgroup = Vec::new();
|
|
|
|
|
for power in generator.powers() {
|
|
|
|
|
if power.is_one() && !subgroup.is_empty() {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
subgroup.push(power);
|
|
|
|
|
}
|
|
|
|
|
subgroup
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn generator_order(generator: Self) -> usize {
|
2021-04-22 23:59:37 -07:00
|
|
|
generator.powers().skip(1).position(|y| y.is_one()).unwrap() + 1
|
2021-04-22 21:12:34 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-04 11:35:58 -07:00
|
|
|
/// Computes a coset of a multiplicative subgroup whose order is known in advance.
|
|
|
|
|
fn cyclic_subgroup_coset_known_order(generator: Self, shift: Self, order: usize) -> Vec<Self> {
|
|
|
|
|
let subgroup = Self::cyclic_subgroup_known_order(generator, order);
|
2021-04-21 22:31:45 +02:00
|
|
|
subgroup.into_iter().map(|x| x * shift).collect()
|
2021-04-04 11:35:58 -07:00
|
|
|
}
|
|
|
|
|
|
2021-02-09 21:25:21 -08:00
|
|
|
fn to_canonical_u64(&self) -> u64;
|
|
|
|
|
|
|
|
|
|
fn from_canonical_u64(n: u64) -> Self;
|
|
|
|
|
|
2021-04-25 18:09:43 -07:00
|
|
|
fn from_canonical_u32(n: u32) -> Self {
|
|
|
|
|
Self::from_canonical_u64(n as u64)
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-09 21:25:21 -08:00
|
|
|
fn from_canonical_usize(n: usize) -> Self {
|
|
|
|
|
Self::from_canonical_u64(n as u64)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn bits(&self) -> usize {
|
2021-04-02 17:49:51 -07:00
|
|
|
bits_u64(self.to_canonical_u64())
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn exp(&self, power: Self) -> Self {
|
|
|
|
|
let mut current = *self;
|
|
|
|
|
let mut product = Self::ONE;
|
|
|
|
|
|
|
|
|
|
for j in 0..power.bits() {
|
|
|
|
|
if (power.to_canonical_u64() >> j & 1) != 0 {
|
2021-04-23 12:35:19 -07:00
|
|
|
product *= current;
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
2021-04-02 17:49:51 -07:00
|
|
|
current = current.square();
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
|
|
|
|
product
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-25 18:09:43 -07:00
|
|
|
fn exp_u32(&self, power: u32) -> Self {
|
|
|
|
|
self.exp(Self::from_canonical_u32(power))
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-09 21:25:21 -08:00
|
|
|
fn exp_usize(&self, power: usize) -> Self {
|
|
|
|
|
self.exp(Self::from_canonical_usize(power))
|
|
|
|
|
}
|
2021-03-30 23:12:47 -07:00
|
|
|
|
2021-04-25 18:09:43 -07:00
|
|
|
/// Returns whether `x^power` is a permutation of this field.
|
|
|
|
|
fn is_monomial_permutation(power: Self) -> bool {
|
|
|
|
|
if power.is_zero() {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if power.is_one() {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
(Self::ORDER - 1).gcd(&power.to_canonical_u64()) == 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn kth_root(&self, k: Self) -> Self {
|
|
|
|
|
let p = Self::ORDER;
|
|
|
|
|
let p_minus_1 = p - 1;
|
|
|
|
|
debug_assert!(
|
|
|
|
|
Self::is_monomial_permutation(k),
|
|
|
|
|
"Not a permutation of this field"
|
|
|
|
|
);
|
|
|
|
|
let k = k.to_canonical_u64();
|
|
|
|
|
|
|
|
|
|
// By Fermat's little theorem, x^p = x and x^(p - 1) = 1, so x^(p + n(p - 1)) = x for any n.
|
|
|
|
|
// Our assumption that the k'th root operation is a permutation implies gcd(p - 1, k) = 1,
|
|
|
|
|
// so there exists some n such that p + n(p - 1) is a multiple of k. Once we find such an n,
|
|
|
|
|
// we can rewrite the above as
|
|
|
|
|
// x^((p + n(p - 1))/k)^k = x,
|
|
|
|
|
// implying that x^((p + n(p - 1))/k) is a k'th root of x.
|
|
|
|
|
for n in 0..k {
|
|
|
|
|
let numerator = p as u128 + n as u128 * p_minus_1 as u128;
|
|
|
|
|
if numerator % k as u128 == 0 {
|
|
|
|
|
let power = (numerator / k as u128) as u64 % p_minus_1;
|
|
|
|
|
return self.exp(Self::from_canonical_u64(power));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
panic!(
|
|
|
|
|
"x^{} and x^(1/{}) are not permutations of this field, or we have a bug!",
|
|
|
|
|
k, k
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn kth_root_u32(&self, k: u32) -> Self {
|
|
|
|
|
self.kth_root(Self::from_canonical_u32(k))
|
2021-04-10 14:52:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cube_root(&self) -> Self {
|
2021-04-25 18:09:43 -07:00
|
|
|
self.kth_root_u32(3)
|
2021-04-10 14:52:34 -07:00
|
|
|
}
|
|
|
|
|
|
2021-04-05 11:39:16 -07:00
|
|
|
fn powers(&self) -> Powers<Self> {
|
2021-04-21 22:31:45 +02:00
|
|
|
Powers {
|
|
|
|
|
base: *self,
|
|
|
|
|
current: Self::ONE,
|
|
|
|
|
}
|
2021-04-05 11:39:16 -07:00
|
|
|
}
|
|
|
|
|
|
2021-03-30 23:12:47 -07:00
|
|
|
fn rand_from_rng<R: Rng>(rng: &mut R) -> Self {
|
|
|
|
|
Self::from_canonical_u64(rng.gen_range(0, Self::ORDER))
|
|
|
|
|
}
|
2021-04-02 14:00:26 -07:00
|
|
|
|
|
|
|
|
fn rand() -> Self {
|
|
|
|
|
Self::rand_from_rng(&mut OsRng)
|
|
|
|
|
}
|
2021-02-09 21:25:21 -08:00
|
|
|
}
|
2021-04-05 11:39:16 -07:00
|
|
|
|
|
|
|
|
/// An iterator over the powers of a certain base element `b`: `b^0, b^1, b^2, ...`.
|
|
|
|
|
pub struct Powers<F: Field> {
|
|
|
|
|
base: F,
|
|
|
|
|
current: F,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<F: Field> Iterator for Powers<F> {
|
|
|
|
|
type Item = F;
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<F> {
|
|
|
|
|
let result = self.current;
|
|
|
|
|
self.current *= self.base;
|
|
|
|
|
Some(result)
|
|
|
|
|
}
|
|
|
|
|
}
|