fext.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. use crate::form::bpoly::*;
  2. use crate::form::poly::*;
  3. //==============================================================================
  4. // field extension methods
  5. //==============================================================================
  6. pub fn fadd(a: &Felt, b: &Felt, res: &mut Felt) {
  7. for i in 0..3 {
  8. res[i] = a[i] + b[i];
  9. }
  10. }
  11. pub fn fadd_(a: &Felt, b: &Felt) -> Felt {
  12. let mut res: Felt = Felt::zero();
  13. fadd(a, b, &mut res);
  14. res
  15. }
  16. pub fn fadd_self(a: &Felt, res: &mut Felt) {
  17. for i in 0..3 {
  18. res[i] = a[i] + res[i];
  19. }
  20. }
  21. #[inline(always)]
  22. pub fn fsub(a: &Felt, b: &Felt, res: &mut Felt) {
  23. for i in 0..3 {
  24. res[i] = a[i] - b[i];
  25. }
  26. }
  27. pub fn fsub_(a: &Felt, b: &Felt) -> Felt {
  28. let mut res: Felt = Felt::zero();
  29. fsub(a, b, &mut res);
  30. res
  31. }
  32. #[inline(always)]
  33. pub fn fneg(a: &Felt, res: &mut Felt) {
  34. for i in 0..3 {
  35. res[i] = -a[i];
  36. }
  37. }
  38. pub fn fneg_(a: &Felt) -> Felt {
  39. let mut res: Felt = Felt::zero();
  40. fneg(a, &mut res);
  41. res
  42. }
  43. #[inline(always)]
  44. pub fn felt_to_bpoly(dat: &Felt) -> BPolyVec {
  45. PolyVec(vec![dat.0[0], dat.0[1], dat.0[2]])
  46. }
  47. pub const IRD: [Belt; 4] = [Belt(1), Belt(18446744069414584320), Belt(0), Belt(1)];
  48. // See hoon comments for full explanation
  49. #[inline(always)]
  50. pub fn fmul(a: &Felt, b: &Felt, res: &mut Felt) {
  51. let poly_a: &[Belt] = &a.0;
  52. let poly_b: &[Belt] = &b.0;
  53. let a0: Belt = poly_a[0];
  54. let a1: Belt = poly_a[1];
  55. let a2: Belt = poly_a[2];
  56. let b0: Belt = poly_b[0];
  57. let b1: Belt = poly_b[1];
  58. let b2: Belt = poly_b[2];
  59. let a0b0: Belt = a0 * b0;
  60. let a1b1: Belt = a1 * b1;
  61. let a2b2: Belt = a2 * b2;
  62. let a0b1_a1b0: Belt = ((a0 + a1) * (b0 + b1) - a0b0) - a1b1;
  63. let a1b2_a2b1: Belt = ((a1 + a2) * (b1 + b2) - a1b1) - a2b2;
  64. let a0b2_a2b0: Belt = ((a0 + a2) * (b0 + b2) - a0b0) - a2b2;
  65. res.0[0] = a0b0 - a1b2_a2b1;
  66. res.0[1] = (a0b1_a1b0 + a1b2_a2b1) - a2b2;
  67. res.0[2] = a0b2_a2b0 + a1b1 + a2b2;
  68. }
  69. pub fn fmul_(a: &Felt, b: &Felt) -> Felt {
  70. let mut res = Felt::zero();
  71. fmul(a, b, &mut res);
  72. res
  73. }
  74. pub fn fscal_(a: &Belt, b: &Felt) -> Felt {
  75. Felt([b.0[0] * *a, b.0[1] * *a, b.0[2] * *a])
  76. }
  77. pub fn fscal_self(a: &Belt, b: &mut Felt) {
  78. b.0[0] = b.0[0] * *a;
  79. b.0[1] = b.0[1] * *a;
  80. b.0[2] = b.0[2] * *a;
  81. }
  82. const POLY: [Belt; 4] = [Belt(1), Belt(18446744069414584320), Belt(0), Belt(1)];
  83. pub const DUV_LEN: usize = 4;
  84. #[inline(always)]
  85. pub fn finv(a: &Felt, res: &mut Felt) {
  86. let poly_a: &[Belt] = a.into();
  87. let mut poly_d = [Belt(0); DUV_LEN];
  88. let mut poly_u = [Belt(0); DUV_LEN];
  89. let mut poly_v = [Belt(0); DUV_LEN];
  90. let poly_bpoly = POLY.as_slice();
  91. bpegcd(
  92. poly_bpoly,
  93. poly_a,
  94. poly_d.as_mut_slice(),
  95. poly_u.as_mut_slice(),
  96. poly_v.as_mut_slice(),
  97. );
  98. bpscal(poly_d[0].inv(), poly_v.as_slice(), &mut res.0);
  99. }
  100. pub fn finv_(a: &Felt) -> Felt {
  101. let mut res: Felt = Felt::zero();
  102. finv(a, &mut res);
  103. res
  104. }
  105. #[inline(always)]
  106. pub fn fpow_(term: &Felt, exponent: u64) -> Felt {
  107. let mut res: Felt = Felt::zero();
  108. fpow(term, exponent, &mut res);
  109. res
  110. }
  111. #[inline(always)]
  112. pub fn fpow(term: &Felt, exponent: u64, c: &mut Felt) {
  113. let a: &mut Felt = &mut term.clone();
  114. let mut b: u64 = exponent;
  115. *c = Felt::from([Belt(1), Belt(0), Belt(0)]);
  116. if b == 0 {
  117. return;
  118. }
  119. while b > 1 {
  120. let a_clone = *a;
  121. if b & 1 == 0 {
  122. fmul(&a_clone, &a_clone, a);
  123. b /= 2;
  124. } else {
  125. fmul(&c.clone(), a, c);
  126. fmul(&a_clone, &a_clone, a);
  127. b = (b - 1) / 2;
  128. }
  129. }
  130. fmul(&c.clone(), a, c);
  131. }
  132. #[inline(always)]
  133. pub fn fdiv(a: &Felt, b: &Felt, res: &mut Felt) {
  134. let binv = &mut Felt::zero();
  135. finv(b, binv);
  136. fmul(a, binv, res);
  137. }
  138. #[inline(always)]
  139. pub fn fdiv_(a: &Felt, b: &Felt) -> Felt {
  140. let mut res: Felt = Felt::zero();
  141. fdiv(a, b, &mut res);
  142. res
  143. }