snarkvm_utilities/serialize/
flags.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
16use crate::serialize::Flags;
17
18/// Flags to be encoded into the serialization.
19#[derive(Default, Clone, Copy, PartialEq, Eq)]
20pub struct EmptyFlags;
21
22impl Flags for EmptyFlags {
23    const BIT_SIZE: usize = 0;
24
25    #[inline]
26    fn u8_bitmask(&self) -> u8 {
27        0
28    }
29
30    #[inline]
31    fn from_u8(value: u8) -> Option<Self> {
32        if (value >> 7) == 0 { Some(EmptyFlags) } else { None }
33    }
34}
35
36/// Flags to be encoded into the serialization.
37/// The default flags (empty) should not change the binary representation.
38#[derive(Clone, Copy, Default, PartialEq, Eq)]
39pub enum SWFlags {
40    Infinity,
41    PositiveY,
42    #[default]
43    NegativeY,
44}
45
46impl SWFlags {
47    #[inline]
48    pub fn infinity() -> Self {
49        SWFlags::Infinity
50    }
51
52    #[inline]
53    pub fn from_y_sign(is_positive: bool) -> Self {
54        if is_positive { SWFlags::PositiveY } else { SWFlags::NegativeY }
55    }
56
57    #[inline]
58    pub fn is_infinity(&self) -> bool {
59        matches!(self, SWFlags::Infinity)
60    }
61
62    #[inline]
63    pub fn is_positive(&self) -> Option<bool> {
64        match self {
65            SWFlags::Infinity => None,
66            SWFlags::PositiveY => Some(true),
67            SWFlags::NegativeY => Some(false),
68        }
69    }
70}
71
72impl Flags for SWFlags {
73    const BIT_SIZE: usize = 2;
74
75    #[inline]
76    fn u8_bitmask(&self) -> u8 {
77        let mut mask = 0;
78        match self {
79            SWFlags::Infinity => mask |= 1 << 6,
80            SWFlags::PositiveY => mask |= 1 << 7,
81            _ => (),
82        }
83        mask
84    }
85
86    #[inline]
87    fn from_u8(value: u8) -> Option<Self> {
88        let x_sign = (value >> 7) & 1 == 1;
89        let is_infinity = (value >> 6) & 1 == 1;
90        match (x_sign, is_infinity) {
91            // This is invalid because we only want *one* way to serialize
92            // the point at infinity.
93            (true, true) => None,
94            (false, true) => Some(SWFlags::Infinity),
95            (true, false) => Some(SWFlags::PositiveY),
96            (false, false) => Some(SWFlags::NegativeY),
97        }
98    }
99}
100
101/// Flags to be encoded into the serialization.
102/// The default flags (empty) should not change the binary representation.
103#[derive(Clone, Copy, Default, PartialEq, Eq)]
104pub enum EdwardsFlags {
105    PositiveY,
106    #[default]
107    NegativeY,
108}
109
110impl EdwardsFlags {
111    #[inline]
112    pub fn from_y_sign(is_positive: bool) -> Self {
113        if is_positive { EdwardsFlags::PositiveY } else { EdwardsFlags::NegativeY }
114    }
115
116    #[inline]
117    pub fn is_positive(&self) -> bool {
118        match self {
119            EdwardsFlags::PositiveY => true,
120            EdwardsFlags::NegativeY => false,
121        }
122    }
123}
124
125impl Flags for EdwardsFlags {
126    const BIT_SIZE: usize = 1;
127
128    #[inline]
129    fn u8_bitmask(&self) -> u8 {
130        let mut mask = 0;
131        if let Self::PositiveY = self {
132            mask |= 1 << 7;
133        }
134        mask
135    }
136
137    #[inline]
138    fn from_u8(value: u8) -> Option<Self> {
139        let x_sign = (value >> 7) & 1 == 1;
140        if x_sign { Some(Self::PositiveY) } else { Some(Self::NegativeY) }
141    }
142}