| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- use crate::form::bpoly::*;
- use crate::form::poly::*;
- //==============================================================================
- // field extension methods
- //==============================================================================
- pub fn fadd(a: &Felt, b: &Felt, res: &mut Felt) {
- for i in 0..3 {
- res[i] = a[i] + b[i];
- }
- }
- pub fn fadd_(a: &Felt, b: &Felt) -> Felt {
- let mut res: Felt = Felt::zero();
- fadd(a, b, &mut res);
- res
- }
- pub fn fadd_self(a: &Felt, res: &mut Felt) {
- for i in 0..3 {
- res[i] = a[i] + res[i];
- }
- }
- #[inline(always)]
- pub fn fsub(a: &Felt, b: &Felt, res: &mut Felt) {
- for i in 0..3 {
- res[i] = a[i] - b[i];
- }
- }
- pub fn fsub_(a: &Felt, b: &Felt) -> Felt {
- let mut res: Felt = Felt::zero();
- fsub(a, b, &mut res);
- res
- }
- #[inline(always)]
- pub fn fneg(a: &Felt, res: &mut Felt) {
- for i in 0..3 {
- res[i] = -a[i];
- }
- }
- pub fn fneg_(a: &Felt) -> Felt {
- let mut res: Felt = Felt::zero();
- fneg(a, &mut res);
- res
- }
- #[inline(always)]
- pub fn felt_to_bpoly(dat: &Felt) -> BPolyVec {
- PolyVec(vec![dat.0[0], dat.0[1], dat.0[2]])
- }
- pub const IRD: [Belt; 4] = [Belt(1), Belt(18446744069414584320), Belt(0), Belt(1)];
- // See hoon comments for full explanation
- #[inline(always)]
- pub fn fmul(a: &Felt, b: &Felt, res: &mut Felt) {
- let poly_a: &[Belt] = &a.0;
- let poly_b: &[Belt] = &b.0;
- let a0: Belt = poly_a[0];
- let a1: Belt = poly_a[1];
- let a2: Belt = poly_a[2];
- let b0: Belt = poly_b[0];
- let b1: Belt = poly_b[1];
- let b2: Belt = poly_b[2];
- let a0b0: Belt = a0 * b0;
- let a1b1: Belt = a1 * b1;
- let a2b2: Belt = a2 * b2;
- let a0b1_a1b0: Belt = ((a0 + a1) * (b0 + b1) - a0b0) - a1b1;
- let a1b2_a2b1: Belt = ((a1 + a2) * (b1 + b2) - a1b1) - a2b2;
- let a0b2_a2b0: Belt = ((a0 + a2) * (b0 + b2) - a0b0) - a2b2;
- res.0[0] = a0b0 - a1b2_a2b1;
- res.0[1] = (a0b1_a1b0 + a1b2_a2b1) - a2b2;
- res.0[2] = a0b2_a2b0 + a1b1 + a2b2;
- }
- pub fn fmul_(a: &Felt, b: &Felt) -> Felt {
- let mut res = Felt::zero();
- fmul(a, b, &mut res);
- res
- }
- pub fn fscal_(a: &Belt, b: &Felt) -> Felt {
- Felt([b.0[0] * *a, b.0[1] * *a, b.0[2] * *a])
- }
- pub fn fscal_self(a: &Belt, b: &mut Felt) {
- b.0[0] = b.0[0] * *a;
- b.0[1] = b.0[1] * *a;
- b.0[2] = b.0[2] * *a;
- }
- const POLY: [Belt; 4] = [Belt(1), Belt(18446744069414584320), Belt(0), Belt(1)];
- pub const DUV_LEN: usize = 4;
- #[inline(always)]
- pub fn finv(a: &Felt, res: &mut Felt) {
- let poly_a: &[Belt] = a.into();
- let mut poly_d = [Belt(0); DUV_LEN];
- let mut poly_u = [Belt(0); DUV_LEN];
- let mut poly_v = [Belt(0); DUV_LEN];
- let poly_bpoly = POLY.as_slice();
- bpegcd(
- poly_bpoly,
- poly_a,
- poly_d.as_mut_slice(),
- poly_u.as_mut_slice(),
- poly_v.as_mut_slice(),
- );
- bpscal(poly_d[0].inv(), poly_v.as_slice(), &mut res.0);
- }
- pub fn finv_(a: &Felt) -> Felt {
- let mut res: Felt = Felt::zero();
- finv(a, &mut res);
- res
- }
- #[inline(always)]
- pub fn fpow_(term: &Felt, exponent: u64) -> Felt {
- let mut res: Felt = Felt::zero();
- fpow(term, exponent, &mut res);
- res
- }
- #[inline(always)]
- pub fn fpow(term: &Felt, exponent: u64, c: &mut Felt) {
- let a: &mut Felt = &mut term.clone();
- let mut b: u64 = exponent;
- *c = Felt::from([Belt(1), Belt(0), Belt(0)]);
- if b == 0 {
- return;
- }
- while b > 1 {
- let a_clone = *a;
- if b & 1 == 0 {
- fmul(&a_clone, &a_clone, a);
- b /= 2;
- } else {
- fmul(&c.clone(), a, c);
- fmul(&a_clone, &a_clone, a);
- b = (b - 1) / 2;
- }
- }
- fmul(&c.clone(), a, c);
- }
- #[inline(always)]
- pub fn fdiv(a: &Felt, b: &Felt, res: &mut Felt) {
- let binv = &mut Felt::zero();
- finv(b, binv);
- fmul(a, binv, res);
- }
- #[inline(always)]
- pub fn fdiv_(a: &Felt, b: &Felt) -> Felt {
- let mut res: Felt = Felt::zero();
- fdiv(a, b, &mut res);
- res
- }
|