vrf_wasm/groups/
mod.rs

1// Copyright (c) 2022, Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::error::{FastCryptoError, FastCryptoResult};
5use crate::traits::AllowedRng;
6use core::ops::{Add, Div, Mul, Neg, Sub};
7use serde::de::DeserializeOwned;
8use serde::Serialize;
9use std::fmt::Debug;
10use std::ops::{AddAssign, SubAssign};
11
12pub mod ristretto255;
13// pub mod bls12381;
14// pub mod secp256r1;
15// pub mod multiplier;
16
17/// Trait impl'd by elements of an additive cyclic group.
18pub trait GroupElement:
19    Copy
20    + Clone
21    + Debug
22    + Eq
23    + Add<Output = Self>
24    + AddAssign
25    + for<'a> Add<&'a Self, Output = Self>
26    + Sub<Output = Self>
27    + SubAssign
28    + for<'a> Sub<&'a Self, Output = Self>
29    + Neg<Output = Self>
30    + Mul<Self::ScalarType, Output = Self>
31    + Div<Self::ScalarType, Output = Result<Self, FastCryptoError>>
32    + for<'a> Mul<&'a Self::ScalarType, Output = Self>
33    + Sized
34{
35    /// Type of scalars used in the [Self::mul] multiplication method.
36    type ScalarType: Scalar;
37
38    /// Return an instance of the identity element in this group.
39    fn zero() -> Self;
40
41    /// Return an instance of the generator for this group.
42    fn generator() -> Self;
43}
44
45// TODO: Move Serialize + DeserializeOwned to GroupElement.
46
47/// Trait impl'd by scalars to be used with [GroupElement].
48pub trait Scalar:
49    GroupElement<ScalarType = Self> + Copy + From<u128> + Sized + Debug + Serialize + DeserializeOwned
50{
51    fn rand<R: AllowedRng>(rng: &mut R) -> Self;
52    fn inverse(&self) -> FastCryptoResult<Self>;
53}
54
55/// Trait for group elements that has a fast doubling operation.
56pub trait Doubling: Clone {
57    /// Compute 2 * Self = Self + Self.
58    fn double(self) -> Self;
59
60    /// Compute input * 2^repetitions by repeated doubling.
61    fn repeated_doubling(self, repetitions: u64) -> Self {
62        (0..repetitions).fold(self, |acc, _| acc.double())
63    }
64}
65
66pub trait Pairing: GroupElement {
67    type Other: GroupElement<ScalarType = Self::ScalarType>;
68    type Output;
69
70    fn pairing(&self, other: &Self::Other) -> <Self as Pairing>::Output;
71
72    /// Multi-pairing operation that computes the sum of pairings of two slices of elements.
73    fn multi_pairing(
74        points_g1: &[Self],
75        points_g2: &[Self::Other],
76    ) -> FastCryptoResult<<Self as Pairing>::Output>
77    where
78        <Self as Pairing>::Output: GroupElement,
79    {
80        if points_g1.len() != points_g2.len() {
81            return Err(FastCryptoError::InvalidInput);
82        }
83        if points_g1.is_empty() {
84            return Ok(<Self as Pairing>::Output::zero());
85        }
86        Ok(points_g1
87            .iter()
88            .skip(1)
89            .zip(points_g2.iter().skip(1))
90            .map(|(g1, g2)| g1.pairing(g2))
91            .fold(
92                points_g1[0].pairing(&points_g2[0]),
93                <Self as Pairing>::Output::add,
94            ))
95    }
96}
97
98/// Trait for groups that have a reduction from a random buffer to a group element that is secure
99/// when used for Fiat-Shamir. Note that the resulting group element is not guaranteed to be
100/// uniformly distributed, but only to have enough entropy to be used for Fiat-Shamir heuristic.
101pub trait FiatShamirChallenge {
102    fn fiat_shamir_reduction_to_group_element(uniform_buffer: &[u8]) -> Self;
103}
104
105/// Trait for groups that have a standardized "hash_to_point"/"hash_to_curve" function (see
106/// [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve#section-3].
107pub trait HashToGroupElement {
108    /// Hashes the given message and maps the result to a group element.
109    fn hash_to_group_element(msg: &[u8]) -> Self;
110}
111
112/// Trait for groups that support multi-scalar multiplication.
113pub trait MultiScalarMul: GroupElement {
114    fn multi_scalar_mul(scalars: &[Self::ScalarType], points: &[Self]) -> FastCryptoResult<Self>;
115}
116
117/// Faster deserialization in case the input is trusted (otherwise it can be insecure).
118pub trait FromTrustedByteArray<const LENGTH: usize>: Sized {
119    fn from_trusted_byte_array(bytes: &[u8; LENGTH]) -> FastCryptoResult<Self>;
120}