load.rs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. use crate::constants::{self, compute_lagrange_coeffs, H, NUM_WINDOWS, NUM_WINDOWS_SHORT};
  2. use group::ff::PrimeField;
  3. use pasta_curves::pallas;
  4. #[derive(Copy, Clone, Debug, Eq, PartialEq)]
  5. pub enum OrchardFixedBasesFull {
  6. CommitIvkR,
  7. NoteCommitR,
  8. ValueCommitR,
  9. SpendAuthG,
  10. }
  11. impl OrchardFixedBasesFull {
  12. pub fn generator(&self) -> pallas::Affine {
  13. match self {
  14. OrchardFixedBasesFull::CommitIvkR => super::commit_ivk_r::generator(),
  15. OrchardFixedBasesFull::NoteCommitR => super::note_commit_r::generator(),
  16. OrchardFixedBasesFull::ValueCommitR => super::value_commit_r::generator(),
  17. OrchardFixedBasesFull::SpendAuthG => super::spend_auth_g::generator(),
  18. }
  19. }
  20. pub fn u(&self) -> U {
  21. match self {
  22. OrchardFixedBasesFull::CommitIvkR => super::commit_ivk_r::U.into(),
  23. OrchardFixedBasesFull::NoteCommitR => super::note_commit_r::U.into(),
  24. OrchardFixedBasesFull::ValueCommitR => super::value_commit_r::U.into(),
  25. OrchardFixedBasesFull::SpendAuthG => super::spend_auth_g::U.into(),
  26. }
  27. }
  28. }
  29. /// A fixed base to be used in scalar multiplication with a full-width scalar.
  30. #[derive(Clone, Debug, Eq, PartialEq)]
  31. pub struct OrchardFixedBase {
  32. pub generator: pallas::Affine,
  33. pub lagrange_coeffs: LagrangeCoeffs,
  34. pub z: Z,
  35. pub u: U,
  36. }
  37. impl From<OrchardFixedBasesFull> for OrchardFixedBase {
  38. fn from(base: OrchardFixedBasesFull) -> Self {
  39. let (generator, z, u) = match base {
  40. OrchardFixedBasesFull::CommitIvkR => (
  41. super::commit_ivk_r::generator(),
  42. super::commit_ivk_r::Z.into(),
  43. super::commit_ivk_r::U.into(),
  44. ),
  45. OrchardFixedBasesFull::NoteCommitR => (
  46. super::note_commit_r::generator(),
  47. super::note_commit_r::Z.into(),
  48. super::note_commit_r::U.into(),
  49. ),
  50. OrchardFixedBasesFull::ValueCommitR => (
  51. super::value_commit_r::generator(),
  52. super::value_commit_r::Z.into(),
  53. super::value_commit_r::U.into(),
  54. ),
  55. OrchardFixedBasesFull::SpendAuthG => (
  56. super::spend_auth_g::generator(),
  57. super::spend_auth_g::Z.into(),
  58. super::spend_auth_g::U.into(),
  59. ),
  60. };
  61. Self {
  62. generator,
  63. lagrange_coeffs: compute_lagrange_coeffs(generator, NUM_WINDOWS).into(),
  64. z,
  65. u,
  66. }
  67. }
  68. }
  69. /// A fixed base to be used in scalar multiplication with a base field element.
  70. #[derive(Clone, Debug, Eq, PartialEq)]
  71. pub struct ValueCommitV {
  72. pub generator: pallas::Affine,
  73. pub lagrange_coeffs_short: LagrangeCoeffsShort,
  74. pub z_short: ZShort,
  75. pub u_short: UShort,
  76. }
  77. impl ValueCommitV {
  78. pub fn get() -> Self {
  79. let generator = super::value_commit_v::generator();
  80. Self {
  81. generator,
  82. lagrange_coeffs_short: compute_lagrange_coeffs(generator, NUM_WINDOWS_SHORT).into(),
  83. z_short: super::value_commit_v::Z_SHORT.into(),
  84. u_short: super::value_commit_v::U_SHORT.into(),
  85. }
  86. }
  87. }
  88. /// A fixed base to be used in scalar multiplication with a short signed exponent.
  89. #[derive(Copy, Clone, Debug, Eq, PartialEq)]
  90. pub struct NullifierK;
  91. impl From<NullifierK> for OrchardFixedBase {
  92. fn from(_nullifier_k: NullifierK) -> Self {
  93. let (generator, z, u) = (
  94. super::nullifier_k::generator(),
  95. super::nullifier_k::Z.into(),
  96. super::nullifier_k::U.into(),
  97. );
  98. Self {
  99. generator,
  100. lagrange_coeffs: compute_lagrange_coeffs(generator, NUM_WINDOWS).into(),
  101. z,
  102. u,
  103. }
  104. }
  105. }
  106. impl NullifierK {
  107. pub fn generator(&self) -> pallas::Affine {
  108. super::nullifier_k::generator()
  109. }
  110. pub fn u(&self) -> U {
  111. super::nullifier_k::U.into()
  112. }
  113. }
  114. #[derive(Clone, Debug, Eq, PartialEq)]
  115. // 8 coefficients per window
  116. pub struct WindowLagrangeCoeffs(pub Box<[pallas::Base; H]>);
  117. impl From<&[pallas::Base; H]> for WindowLagrangeCoeffs {
  118. fn from(array: &[pallas::Base; H]) -> Self {
  119. Self(Box::new(*array))
  120. }
  121. }
  122. #[derive(Clone, Debug, Eq, PartialEq)]
  123. // 85 windows per base (with the exception of ValueCommitV)
  124. pub struct LagrangeCoeffs(pub Box<[WindowLagrangeCoeffs; constants::NUM_WINDOWS]>);
  125. impl From<Vec<WindowLagrangeCoeffs>> for LagrangeCoeffs {
  126. fn from(windows: Vec<WindowLagrangeCoeffs>) -> Self {
  127. Self(windows.into_boxed_slice().try_into().unwrap())
  128. }
  129. }
  130. impl From<Vec<[pallas::Base; H]>> for LagrangeCoeffs {
  131. fn from(arrays: Vec<[pallas::Base; H]>) -> Self {
  132. let windows: Vec<WindowLagrangeCoeffs> = arrays.iter().map(|array| array.into()).collect();
  133. windows.into()
  134. }
  135. }
  136. #[derive(Clone, Debug, Eq, PartialEq)]
  137. // 22 windows for ValueCommitV
  138. pub struct LagrangeCoeffsShort(pub Box<[WindowLagrangeCoeffs; NUM_WINDOWS_SHORT]>);
  139. impl From<Vec<WindowLagrangeCoeffs>> for LagrangeCoeffsShort {
  140. fn from(windows: Vec<WindowLagrangeCoeffs>) -> Self {
  141. Self(windows.into_boxed_slice().try_into().unwrap())
  142. }
  143. }
  144. impl From<Vec<[pallas::Base; H]>> for LagrangeCoeffsShort {
  145. fn from(arrays: Vec<[pallas::Base; H]>) -> Self {
  146. let windows: Vec<WindowLagrangeCoeffs> = arrays.iter().map(|array| array.into()).collect();
  147. windows.into()
  148. }
  149. }
  150. #[derive(Clone, Debug, Eq, PartialEq)]
  151. // 85 Z's per base (with the exception of ValueCommitV)
  152. pub struct Z(pub Box<[pallas::Base; NUM_WINDOWS]>);
  153. impl From<[u64; NUM_WINDOWS]> for Z {
  154. fn from(zs: [u64; NUM_WINDOWS]) -> Self {
  155. Self(
  156. zs.iter()
  157. .map(|z| pallas::Base::from(*z))
  158. .collect::<Vec<_>>()
  159. .into_boxed_slice()
  160. .try_into()
  161. .unwrap(),
  162. )
  163. }
  164. }
  165. #[derive(Clone, Debug, Eq, PartialEq)]
  166. // 22 Z's for ValueCommitV
  167. pub struct ZShort(pub Box<[pallas::Base; NUM_WINDOWS_SHORT]>);
  168. impl From<[u64; NUM_WINDOWS_SHORT]> for ZShort {
  169. fn from(zs: [u64; NUM_WINDOWS_SHORT]) -> Self {
  170. Self(
  171. zs.iter()
  172. .map(|z| pallas::Base::from(*z))
  173. .collect::<Vec<_>>()
  174. .into_boxed_slice()
  175. .try_into()
  176. .unwrap(),
  177. )
  178. }
  179. }
  180. #[derive(Clone, Debug, Eq, PartialEq)]
  181. // 8 u's per window
  182. pub struct WindowUs(pub Box<[pallas::Base; H]>);
  183. impl From<&[[u8; 32]; H]> for WindowUs {
  184. fn from(window_us: &[[u8; 32]; H]) -> Self {
  185. Self(
  186. window_us
  187. .iter()
  188. .map(|u| pallas::Base::from_repr(*u).unwrap())
  189. .collect::<Vec<_>>()
  190. .into_boxed_slice()
  191. .try_into()
  192. .unwrap(),
  193. )
  194. }
  195. }
  196. #[derive(Clone, Debug, Eq, PartialEq)]
  197. // 85 windows per base (with the exception of ValueCommitV)
  198. pub struct U(pub Box<[WindowUs; NUM_WINDOWS]>);
  199. impl From<Vec<WindowUs>> for U {
  200. fn from(windows: Vec<WindowUs>) -> Self {
  201. Self(windows.into_boxed_slice().try_into().unwrap())
  202. }
  203. }
  204. impl From<[[[u8; 32]; H]; NUM_WINDOWS]> for U {
  205. fn from(window_us: [[[u8; 32]; H]; NUM_WINDOWS]) -> Self {
  206. let windows: Vec<WindowUs> = window_us.iter().map(|us| us.into()).collect();
  207. windows.into()
  208. }
  209. }
  210. #[derive(Clone, Debug, Eq, PartialEq)]
  211. // 22 windows for ValueCommitV
  212. pub struct UShort(pub Box<[WindowUs; NUM_WINDOWS_SHORT]>);
  213. impl From<Vec<WindowUs>> for UShort {
  214. fn from(windows: Vec<WindowUs>) -> Self {
  215. Self(windows.into_boxed_slice().try_into().unwrap())
  216. }
  217. }
  218. impl From<[[[u8; 32]; H]; NUM_WINDOWS_SHORT]> for UShort {
  219. fn from(window_us: [[[u8; 32]; H]; NUM_WINDOWS_SHORT]) -> Self {
  220. let windows: Vec<WindowUs> = window_us.iter().map(|us| us.into()).collect();
  221. windows.into()
  222. }
  223. }