snarkvm_console_types_group/
lib.rs

1// Copyright 2024 Aleo Network Foundation
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#![cfg_attr(test, allow(clippy::assertions_on_result_states))]
17#![warn(clippy::cast_possible_truncation)]
18
19mod arithmetic;
20mod bitwise;
21mod bytes;
22mod from_bits;
23mod from_field;
24mod from_fields;
25mod from_x_coordinate;
26mod from_xy_coordinates;
27mod parse;
28mod random;
29mod serialize;
30mod size_in_bits;
31mod size_in_bytes;
32mod to_bits;
33mod to_field;
34mod to_fields;
35mod to_x_coordinate;
36mod to_xy_coordinates;
37mod to_y_coordinate;
38mod zero;
39
40pub use snarkvm_console_network_environment::prelude::*;
41pub use snarkvm_console_types_boolean::Boolean;
42pub use snarkvm_console_types_field::Field;
43pub use snarkvm_console_types_scalar::Scalar;
44
45#[derive(Copy, Clone, PartialEq, Eq, Hash)]
46pub struct Group<E: Environment> {
47    /// The underlying group element.
48    group: E::Projective,
49}
50
51impl<E: Environment> GroupTrait<Scalar<E>> for Group<E> {}
52
53impl<E: Environment> Visibility for Group<E> {
54    type Boolean = Boolean<E>;
55
56    /// Returns the number of field elements to encode `self`.
57    fn size_in_fields(&self) -> Result<u16> {
58        Ok(1)
59    }
60}
61
62impl<E: Environment> Group<E> {
63    /// The coefficient A for the twisted Edwards curve equation.
64    pub const EDWARDS_A: Field<E> = Field::<E>::new(E::EDWARDS_A);
65    /// The coefficient D for the twisted Edwards curve equation.
66    pub const EDWARDS_D: Field<E> = Field::<E>::new(E::EDWARDS_D);
67    /// The coefficient A for the Montgomery curve equation.
68    pub const MONTGOMERY_A: Field<E> = Field::<E>::new(E::MONTGOMERY_A);
69    /// The coefficient B for the Montgomery curve equation.
70    pub const MONTGOMERY_B: Field<E> = Field::<E>::new(E::MONTGOMERY_B);
71
72    /// Initializes a new group.
73    pub fn new(group: E::Affine) -> Self {
74        Self { group: group.into() }
75    }
76
77    /// Returns the prime subgroup generator.
78    pub fn generator() -> Self {
79        Self { group: E::Affine::prime_subgroup_generator().to_projective() }
80    }
81
82    /// Returns `self * COFACTOR`.
83    pub fn mul_by_cofactor(&self) -> Self {
84        // (For advanced users) The cofactor for this curve is `4`. Thus doubling is used to be performant.
85        // See unit tests below, which sanity check that this condition holds.
86        debug_assert!(E::Affine::cofactor().len() == 1 && E::Affine::cofactor()[0] == 4);
87
88        Self { group: self.group.double().double() }
89    }
90
91    /// Returns `self / COFACTOR`.
92    pub fn div_by_cofactor(&self) -> Self {
93        Self { group: self.group.to_affine().mul_by_cofactor_inv().into() }
94    }
95}
96
97impl<E: Environment> Group<E> {
98    /// This internal function initializes a group element from projective coordinates.
99    const fn from_projective(group: E::Projective) -> Self {
100        Self { group }
101    }
102}
103
104impl<E: Environment> TypeName for Group<E> {
105    /// Returns the type name as a string.
106    #[inline]
107    fn type_name() -> &'static str {
108        "group"
109    }
110}
111
112impl<E: Environment> Deref for Group<E> {
113    type Target = E::Projective;
114
115    #[inline]
116    fn deref(&self) -> &Self::Target {
117        &self.group
118    }
119}