felt.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. use core::ops::{Add, Div, Mul, Neg, Sub};
  2. use num_traits::{MulAdd, Pow};
  3. use crate::form::base::*;
  4. use crate::form::fext::*;
  5. use crate::form::{Belt, Felt};
  6. impl Felt {
  7. #[inline(always)]
  8. pub fn zero() -> Self {
  9. Felt(Default::default())
  10. }
  11. #[inline(always)]
  12. pub fn one() -> Self {
  13. Self::from([1, 0, 0])
  14. }
  15. #[inline(always)]
  16. pub fn constant(a: u64) -> Self {
  17. Felt([Belt(a), Belt::zero(), Belt::zero()])
  18. }
  19. #[inline(always)]
  20. pub fn lift(a: Belt) -> Self {
  21. Felt([a, Belt::zero(), Belt::zero()])
  22. }
  23. #[inline(always)]
  24. pub fn ordered_root(order: u64) -> Result<Self, FieldError> {
  25. Ok(Self::constant(Belt(order).ordered_root()?.into()))
  26. }
  27. #[inline(always)]
  28. pub fn is_zero(&self) -> bool {
  29. self.0.iter().all(|&e| e.is_zero())
  30. }
  31. #[inline(always)]
  32. pub fn degree(&self) -> u32 {
  33. match self.0.iter().rposition(|&x| x.is_zero()) {
  34. Some(i) => i as u32,
  35. // TODO: change return to an enum so this can be negative infty?
  36. None => 0,
  37. }
  38. }
  39. #[inline(always)]
  40. pub fn unpack(self) -> [u64; 3] {
  41. [self.0[0].0, self.0[1].0, self.0[2].0]
  42. }
  43. #[inline(always)]
  44. pub fn copy_from_slice(&mut self, src: &Felt) {
  45. self.0.copy_from_slice(&src.0)
  46. }
  47. // pub fn to_simd(&self) -> std::simd::Simd<[u64; 4]> {
  48. // std::simd::Simd::load_or_default(&self.0)
  49. // }
  50. }
  51. impl core::ops::Index<usize> for Felt {
  52. type Output = Belt;
  53. #[inline(always)]
  54. fn index(&self, index: usize) -> &Self::Output {
  55. &self.0[index]
  56. }
  57. }
  58. impl core::ops::IndexMut<usize> for Felt {
  59. #[inline(always)]
  60. fn index_mut(&mut self, index: usize) -> &mut Self::Output {
  61. &mut self.0[index]
  62. }
  63. }
  64. // impl AsRef<[u64]> for Felt {
  65. // fn as_ref(&self) -> &[u64] {
  66. // &self.0
  67. // }
  68. // }
  69. impl From<[Belt; 3]> for Felt {
  70. #[inline(always)]
  71. fn from(f: [Belt; 3]) -> Self {
  72. Felt(f)
  73. }
  74. }
  75. impl From<[u64; 3]> for Felt {
  76. #[inline(always)]
  77. fn from(f: [u64; 3]) -> Self {
  78. Felt(f.map(Belt::from))
  79. }
  80. }
  81. impl TryFrom<&[u64]> for Felt {
  82. type Error = ();
  83. #[inline(always)]
  84. fn try_from(f: &[u64]) -> Result<Self, Self::Error> {
  85. if f.len() != 3 {
  86. return Err(());
  87. }
  88. Ok(Felt([Belt::from(f[0]), Belt::from(f[1]), Belt::from(f[2])]))
  89. }
  90. }
  91. impl From<Felt> for [u64; 3] {
  92. #[inline(always)]
  93. fn from(f: Felt) -> Self {
  94. f.0.map(u64::from)
  95. }
  96. }
  97. impl From<Felt> for [Belt; 3] {
  98. #[inline(always)]
  99. fn from(f: Felt) -> Self {
  100. f.0
  101. }
  102. }
  103. impl<'a> From<&'a Felt> for &'a [Belt] {
  104. #[inline(always)]
  105. fn from(f: &'a Felt) -> &'a [Belt] {
  106. &f.0
  107. }
  108. }
  109. #[cfg(test)]
  110. impl quickcheck::Arbitrary for Felt {
  111. fn arbitrary(g: &mut quickcheck::Gen) -> Self {
  112. Felt([Belt::arbitrary(g), Belt::arbitrary(g), Belt::arbitrary(g)])
  113. }
  114. }
  115. impl Add for Felt {
  116. type Output = Self;
  117. #[inline(always)]
  118. fn add(self, rhs: Self) -> Self::Output {
  119. let mut res: Felt = Felt::zero();
  120. fadd(&self, &rhs, &mut res);
  121. res
  122. }
  123. }
  124. impl Sub for Felt {
  125. type Output = Self;
  126. #[inline(always)]
  127. fn sub(self, rhs: Self) -> Self::Output {
  128. let mut res: Felt = Felt::zero();
  129. fsub(&self, &rhs, &mut res);
  130. res
  131. }
  132. }
  133. impl Mul for Felt {
  134. type Output = Self;
  135. #[inline(always)]
  136. fn mul(self, rhs: Self) -> Self::Output {
  137. let mut res: Felt = Felt::zero();
  138. fmul(&self, &rhs, &mut res);
  139. res
  140. }
  141. }
  142. impl Pow<usize> for Felt {
  143. type Output = Self;
  144. #[inline(always)]
  145. fn pow(self, rhs: usize) -> Self::Output {
  146. let mut res: Felt = Felt::zero();
  147. fpow(&self, rhs as u64, &mut res);
  148. res
  149. }
  150. }
  151. impl Neg for Felt {
  152. type Output = Self;
  153. #[inline(always)]
  154. fn neg(self) -> Self::Output {
  155. let mut res: Felt = Felt::zero();
  156. fneg(&self, &mut res);
  157. res
  158. }
  159. }
  160. impl Div for Felt {
  161. type Output = Self;
  162. #[inline(always)]
  163. fn div(self, rhs: Self) -> Self::Output {
  164. let mut res: Felt = Felt::zero();
  165. fdiv(&self, &rhs, &mut res);
  166. res
  167. }
  168. }
  169. impl MulAdd for Felt {
  170. type Output = Self;
  171. #[inline(always)]
  172. fn mul_add(self, a: Self, b: Self) -> Self {
  173. let mut res: Felt = Felt::zero();
  174. fmul(&self, &a, &mut res);
  175. fadd_self(&b, &mut res);
  176. res
  177. }
  178. }