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