load.rs 7.8 KB

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