darkfi_serial/types/
pasta.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2026 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19//! Implementations for pasta curves
20use std::io::{Error, Read, Result, Write};
21
22#[cfg(feature = "async")]
23use crate::{
24    async_lib::{AsyncReadExt, AsyncWriteExt},
25    AsyncDecodable, AsyncEncodable,
26};
27#[cfg(feature = "async")]
28use async_trait::async_trait;
29#[cfg(feature = "async")]
30use futures_lite::{AsyncRead, AsyncWrite};
31
32use pasta_curves::{
33    group::{ff::PrimeField, GroupEncoding},
34    Ep, Eq, Fp, Fq,
35};
36
37use crate::{Decodable, Encodable, ReadExt, WriteExt};
38
39impl Encodable for Fp {
40    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
41        s.write_slice(&self.to_repr())?;
42        Ok(32)
43    }
44}
45
46#[cfg(feature = "async")]
47#[async_trait]
48impl AsyncEncodable for Fp {
49    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
50        s.write_slice_async(&self.to_repr()).await?;
51        Ok(32)
52    }
53}
54
55impl Decodable for Fp {
56    fn decode<D: Read>(d: &mut D) -> Result<Self> {
57        let mut bytes = [0u8; 32];
58        d.read_slice(&mut bytes)?;
59        match Self::from_repr(bytes).into() {
60            Some(v) => Ok(v),
61            None => Err(Error::other("Noncanonical bytes for pallas::Base")),
62        }
63    }
64}
65#[cfg(feature = "async")]
66#[async_trait]
67impl AsyncDecodable for Fp {
68    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
69        let mut bytes = [0u8; 32];
70        d.read_slice_async(&mut bytes).await?;
71        match Self::from_repr(bytes).into() {
72            Some(v) => Ok(v),
73            None => Err(Error::other("Noncanonical bytes for pallas::Base")),
74        }
75    }
76}
77
78impl Encodable for Fq {
79    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
80        s.write_slice(&self.to_repr())?;
81        Ok(32)
82    }
83}
84
85#[cfg(feature = "async")]
86#[async_trait]
87impl AsyncEncodable for Fq {
88    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
89        s.write_slice_async(&self.to_repr()).await?;
90        Ok(32)
91    }
92}
93
94impl Decodable for Fq {
95    fn decode<D: Read>(d: &mut D) -> Result<Self> {
96        let mut bytes = [0u8; 32];
97        d.read_slice(&mut bytes)?;
98        match Self::from_repr(bytes).into() {
99            Some(v) => Ok(v),
100            None => Err(Error::other("Noncanonical bytes for pallas::Scalar")),
101        }
102    }
103}
104
105#[cfg(feature = "async")]
106#[async_trait]
107impl AsyncDecodable for Fq {
108    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
109        let mut bytes = [0u8; 32];
110        d.read_slice_async(&mut bytes).await?;
111        match Self::from_repr(bytes).into() {
112            Some(v) => Ok(v),
113            None => Err(Error::other("Noncanonical bytes for pallas::Scalar")),
114        }
115    }
116}
117
118impl Encodable for Ep {
119    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
120        s.write_slice(&self.to_bytes())?;
121        Ok(32)
122    }
123}
124
125#[cfg(feature = "async")]
126#[async_trait]
127impl AsyncEncodable for Ep {
128    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
129        s.write_slice_async(&self.to_bytes()).await?;
130        Ok(32)
131    }
132}
133
134impl Decodable for Ep {
135    fn decode<D: Read>(d: &mut D) -> Result<Self> {
136        let mut bytes = [0u8; 32];
137        d.read_slice(&mut bytes)?;
138        match Self::from_bytes(&bytes).into() {
139            Some(v) => Ok(v),
140            None => Err(Error::other("Noncanonical bytes for pallas::Point")),
141        }
142    }
143}
144
145#[cfg(feature = "async")]
146#[async_trait]
147impl AsyncDecodable for Ep {
148    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
149        let mut bytes = [0u8; 32];
150        d.read_slice_async(&mut bytes).await?;
151        match Self::from_bytes(&bytes).into() {
152            Some(v) => Ok(v),
153            None => Err(Error::other("Noncanonical bytes for pallas::Point")),
154        }
155    }
156}
157
158impl Encodable for Eq {
159    fn encode<S: Write>(&self, s: &mut S) -> Result<usize> {
160        s.write_slice(&self.to_bytes())?;
161        Ok(32)
162    }
163}
164
165#[cfg(feature = "async")]
166#[async_trait]
167impl AsyncEncodable for Eq {
168    async fn encode_async<S: AsyncWrite + Unpin + Send>(&self, s: &mut S) -> Result<usize> {
169        s.write_slice_async(&self.to_bytes()).await?;
170        Ok(32)
171    }
172}
173
174impl Decodable for Eq {
175    fn decode<D: Read>(d: &mut D) -> Result<Self> {
176        let mut bytes = [0u8; 32];
177        d.read_slice(&mut bytes)?;
178        match Self::from_bytes(&bytes).into() {
179            Some(v) => Ok(v),
180            None => Err(Error::other("Noncanonical bytes for vesta::Point")),
181        }
182    }
183}
184
185#[cfg(feature = "async")]
186#[async_trait]
187impl AsyncDecodable for Eq {
188    async fn decode_async<D: AsyncRead + Unpin + Send>(d: &mut D) -> Result<Self> {
189        let mut bytes = [0u8; 32];
190        d.read_slice_async(&mut bytes).await?;
191        match Self::from_bytes(&bytes).into() {
192            Some(v) => Ok(v),
193            None => Err(Error::other("Noncanonical bytes for vesta::Point")),
194        }
195    }
196}