nym_compact_ecash/
traits.rs1use crate::common_types::{BlindedSignature, Signature};
5use crate::proofs::proof_spend::{SpendInstance, SpendProof};
6use crate::proofs::proof_withdrawal::{WithdrawalReqInstance, WithdrawalReqProof};
7use crate::scheme::withdrawal::RequestInfo;
8use crate::scheme::{Payment, WalletSignatures};
9use crate::{Attribute, CompactEcashError, PartialWallet, WithdrawalRequest};
10use group::GroupEncoding;
11use nym_bls12_381_fork::{G1Affine, G1Projective};
12
13#[macro_export]
14macro_rules! impl_byteable_bs58 {
15 ($typ:ident) => {
16 impl $crate::traits::Bytable for $typ {
17 fn to_byte_vec(&self) -> Vec<u8> {
18 self.to_bytes().to_vec()
19 }
20
21 fn try_from_byte_slice(slice: &[u8]) -> $crate::error::Result<Self> {
22 Self::from_bytes(slice)
23 }
24 }
25
26 impl $crate::traits::Base58 for $typ {}
27
28 impl TryFrom<&[u8]> for $typ {
29 type Error = CompactEcashError;
30
31 fn try_from(bytes: &[u8]) -> $crate::error::Result<Self> {
32 Self::from_bytes(bytes)
33 }
34 }
35 };
36}
37
38macro_rules! impl_complex_binary_bytable {
39 ($typ:ident) => {
40 impl $typ {
41 pub fn to_bytes(&self) -> Vec<u8> {
42 use bincode::Options;
43
44 #[allow(clippy::unwrap_used)]
46 crate::binary_serialiser().serialize(self).unwrap()
47 }
48
49 pub fn from_bytes(bytes: &[u8]) -> crate::error::Result<Self> {
50 use bincode::Options;
51 crate::binary_serialiser()
52 .deserialize(bytes)
53 .map_err(|source| CompactEcashError::BinaryDeserialisationFailure {
54 type_name: std::any::type_name::<$typ>().to_string(),
55 source,
56 })
57 }
58 }
59
60 impl_byteable_bs58!($typ);
61 };
62}
63
64pub trait Bytable
65where
66 Self: Sized,
67{
68 fn to_byte_vec(&self) -> Vec<u8>;
69
70 fn try_from_byte_slice(slice: &[u8]) -> Result<Self, CompactEcashError>;
71}
72
73pub trait Base58
74where
75 Self: Bytable,
76{
77 fn try_from_bs58<S: AsRef<str>>(x: S) -> Result<Self, CompactEcashError> {
78 Self::try_from_byte_slice(&bs58::decode(x.as_ref()).into_vec()?)
79 }
80 fn to_bs58(&self) -> String {
81 bs58::encode(self.to_byte_vec()).into_string()
82 }
83}
84
85impl Bytable for G1Projective {
86 fn to_byte_vec(&self) -> Vec<u8> {
87 self.to_bytes().as_ref().to_vec()
88 }
89
90 fn try_from_byte_slice(slice: &[u8]) -> Result<Self, CompactEcashError> {
91 let bytes = slice
92 .try_into()
93 .map_err(|_| CompactEcashError::G1ProjectiveDeserializationFailure)?;
94
95 let maybe_g1 = G1Affine::from_compressed(&bytes);
96 if maybe_g1.is_none().into() {
97 Err(CompactEcashError::G1ProjectiveDeserializationFailure)
98 } else {
99 #[allow(clippy::unwrap_used)]
101 Ok(maybe_g1.unwrap().into())
102 }
103 }
104}
105
106impl Base58 for G1Projective {}
107
108impl Bytable for Attribute {
109 fn to_byte_vec(&self) -> Vec<u8> {
110 self.to_bytes().to_vec()
111 }
112
113 fn try_from_byte_slice(slice: &[u8]) -> Result<Self, CompactEcashError> {
114 let maybe_attribute = Attribute::from_bytes(
115 slice
116 .try_into()
117 .map_err(|_| CompactEcashError::ScalarDeserializationFailure)?,
118 );
119 if maybe_attribute.is_none().into() {
120 Err(CompactEcashError::ScalarDeserializationFailure)
121 } else {
122 #[allow(clippy::unwrap_used)]
124 Ok(maybe_attribute.unwrap())
125 }
126 }
127}
128
129impl_byteable_bs58!(Signature);
130impl_byteable_bs58!(BlindedSignature);
131impl_byteable_bs58!(WalletSignatures);
132impl_byteable_bs58!(PartialWallet);
133
134impl_complex_binary_bytable!(SpendProof);
135impl_complex_binary_bytable!(SpendInstance);
136impl_complex_binary_bytable!(WithdrawalReqProof);
137impl_complex_binary_bytable!(WithdrawalReqInstance);
138impl_complex_binary_bytable!(Payment);
139impl_complex_binary_bytable!(WithdrawalRequest);
140impl_complex_binary_bytable!(RequestInfo);