You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.2 KiB

3 years ago
  1. //! This module implements the Nova traits for pallas::Point and pallas::Scalar.
  2. use crate::traits::{ChallengeTrait, CompressedGroup, Group, PrimeField};
  3. use merlin::Transcript;
  4. use pasta_curves::arithmetic::{CurveExt, FieldExt, Group as Grp};
  5. use pasta_curves::group::GroupEncoding;
  6. use pasta_curves::{self, pallas, Ep, Fq};
  7. use rand::{CryptoRng, RngCore};
  8. use std::borrow::Borrow;
  9. use std::ops::Mul;
  10. impl Group for pallas::Point {
  11. type Scalar = pallas::Scalar;
  12. type CompressedGroupElement = <pallas::Point as GroupEncoding>::Repr;
  13. fn vartime_multiscalar_mul<I, J>(scalars: I, points: J) -> Self
  14. where
  15. I: IntoIterator,
  16. I::Item: Borrow<Self::Scalar>,
  17. J: IntoIterator,
  18. J::Item: Borrow<Self>,
  19. Self: Clone,
  20. {
  21. // Unoptimized.
  22. scalars
  23. .into_iter()
  24. .zip(points)
  25. .map(|(scalar, point)| (*point.borrow()).mul(*scalar.borrow()))
  26. .fold(Ep::group_zero(), |acc, x| acc + x)
  27. }
  28. fn compress(&self) -> Self::CompressedGroupElement {
  29. self.to_bytes()
  30. }
  31. fn from_uniform_bytes(bytes: &[u8]) -> Option<Self> {
  32. if bytes.len() != 64 {
  33. None
  34. } else {
  35. let mut arr = [0; 32];
  36. arr.copy_from_slice(&bytes[0..32]);
  37. let hash = Ep::hash_to_curve("from_uniform_bytes");
  38. Some(hash(&arr))
  39. }
  40. }
  41. }
  42. impl PrimeField for pallas::Scalar {
  43. fn zero() -> Self {
  44. Fq::zero()
  45. }
  46. fn one() -> Self {
  47. Fq::one()
  48. }
  49. fn from_bytes_mod_order_wide(bytes: &[u8]) -> Option<Self> {
  50. if bytes.len() != 64 {
  51. None
  52. } else {
  53. let mut arr = [0; 64];
  54. arr.copy_from_slice(&bytes[0..64]);
  55. Some(Fq::from_bytes_wide(&arr))
  56. }
  57. }
  58. fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Self {
  59. Fq::rand()
  60. }
  61. }
  62. impl ChallengeTrait for pallas::Scalar {
  63. fn challenge(label: &'static [u8], transcript: &mut Transcript) -> Self {
  64. let mut buf = [0u8; 64];
  65. transcript.challenge_bytes(label, &mut buf);
  66. pallas::Scalar::from_bytes_mod_order_wide(&buf).unwrap()
  67. }
  68. }
  69. impl CompressedGroup for <pallas::Point as GroupEncoding>::Repr {
  70. type GroupElement = pallas::Point;
  71. fn decompress(&self) -> Option<<Self as CompressedGroup>::GroupElement> {
  72. Some(Ep::from_bytes(self).unwrap())
  73. }
  74. fn as_bytes(&self) -> &[u8] {
  75. self
  76. }
  77. }