1use core::{fmt, ops};
2
3use subtle::{Choice, ConstantTimeEq};
4use zeroize::Zeroize;
5
6use crate::{as_raw::AsRaw, core::ByteArray, secret, Curve};
7
8#[derive(Zeroize)]
10pub struct EncodedPoint<E: Curve>(EncodedPointInner<E>);
11
12impl<E: Curve> EncodedPoint<E> {
13 pub(crate) fn new_compressed(bytes: E::CompressedPointArray) -> Self {
14 Self(EncodedPointInner::Compressed(bytes))
15 }
16
17 pub(crate) fn new_uncompressed(bytes: E::UncompressedPointArray) -> Self {
18 Self(EncodedPointInner::Uncompressed(bytes))
19 }
20
21 pub fn as_bytes(&self) -> &[u8] {
23 match &self.0 {
24 EncodedPointInner::Compressed(bytes) => bytes.as_ref(),
25 EncodedPointInner::Uncompressed(bytes) => bytes.as_ref(),
26 }
27 }
28}
29
30impl<E: Curve> Clone for EncodedPoint<E> {
31 fn clone(&self) -> Self {
32 Self(self.0.clone())
33 }
34}
35
36impl<E: Curve> Default for EncodedPoint<E> {
37 fn default() -> Self {
38 Self(EncodedPointInner::Uncompressed(
39 E::UncompressedPointArray::zeroes(),
40 ))
41 }
42}
43
44impl<E: Curve> PartialEq for EncodedPoint<E> {
45 fn eq(&self, other: &Self) -> bool {
46 self.as_bytes() == other.as_bytes()
47 }
48}
49
50impl<E: Curve> Eq for EncodedPoint<E> {}
51
52impl<E: Curve> fmt::Debug for EncodedPoint<E> {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 let mut tuple = f.debug_tuple("EncodedPoint");
55 #[cfg(feature = "alloc")]
56 {
57 tuple.field(&hex::encode(self.as_bytes()));
58 }
59 tuple.finish()
60 }
61}
62
63impl<E: Curve> ops::Deref for EncodedPoint<E> {
64 type Target = [u8];
65 fn deref(&self) -> &[u8] {
66 self.as_bytes()
67 }
68}
69
70#[derive(Clone)]
71enum EncodedPointInner<E: Curve> {
72 Compressed(E::CompressedPointArray),
73 Uncompressed(E::UncompressedPointArray),
74}
75
76impl<E: Curve> AsRef<[u8]> for EncodedPoint<E> {
77 fn as_ref(&self) -> &[u8] {
78 self.as_bytes()
79 }
80}
81
82impl<E: Curve> AsMut<[u8]> for EncodedPoint<E> {
83 fn as_mut(&mut self) -> &mut [u8] {
84 match &mut self.0 {
85 EncodedPointInner::Compressed(a) => a.as_mut(),
86 EncodedPointInner::Uncompressed(a) => a.as_mut(),
87 }
88 }
89}
90
91impl<E: Curve> Zeroize for EncodedPointInner<E> {
92 fn zeroize(&mut self) {
93 match self {
94 EncodedPointInner::Compressed(a) => a.as_mut().zeroize(),
95 EncodedPointInner::Uncompressed(a) => a.as_mut().zeroize(),
96 }
97 }
98}
99
100#[derive(Clone)]
102pub struct EncodedScalar<E: Curve>(E::ScalarArray);
103
104impl<E: Curve> EncodedScalar<E> {
105 pub(crate) fn new(bytes: E::ScalarArray) -> Self {
106 Self(bytes)
107 }
108
109 pub fn as_bytes(&self) -> &[u8] {
111 self.0.as_ref()
112 }
113}
114
115impl<E: Curve> AsRef<[u8]> for EncodedScalar<E> {
116 fn as_ref(&self) -> &[u8] {
117 self.as_bytes()
118 }
119}
120
121impl<E: Curve> AsMut<[u8]> for EncodedScalar<E> {
122 fn as_mut(&mut self) -> &mut [u8] {
123 self.0.as_mut()
124 }
125}
126
127impl<E: Curve> ops::Deref for EncodedScalar<E> {
128 type Target = [u8];
129 fn deref(&self) -> &[u8] {
130 self.as_bytes()
131 }
132}
133
134impl<E: Curve> fmt::Debug for EncodedScalar<E> {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 let mut s = f.debug_tuple("EncodedScalar");
137 #[cfg(feature = "std")]
138 {
139 s.field(&hex::encode(self.as_bytes()));
140 }
141 s.finish()
142 }
143}
144
145impl<E: Curve> PartialEq for EncodedScalar<E> {
146 fn eq(&self, other: &Self) -> bool {
147 self.as_bytes() == other.as_bytes()
148 }
149}
150
151impl<E: Curve> Eq for EncodedScalar<E> {}
152
153impl<E: Curve> Default for EncodedScalar<E> {
154 fn default() -> Self {
155 let bytes = E::ScalarArray::zeroes();
156 Self(bytes)
157 }
158}
159
160impl<E: Curve> AsRaw for EncodedScalar<E> {
161 type Raw = E::ScalarArray;
162 fn as_raw(&self) -> &Self::Raw {
163 &self.0
164 }
165}
166
167impl<E: Curve> Zeroize for EncodedScalar<E> {
168 fn zeroize(&mut self) {
169 self.as_mut().zeroize()
170 }
171}
172
173#[derive(Clone, Default)]
182pub struct EncodedSecretPoint<E: Curve>(secret::Secret<EncodedPoint<E>>);
183
184impl<E: Curve> EncodedSecretPoint<E> {
185 #[inline(always)]
187 pub fn new(mut point: EncodedPoint<E>) -> Self {
188 Self(secret::new(&mut point))
189 }
190
191 pub fn as_nonsecret_bytes(&self) -> &[u8] {
195 self.0.as_bytes()
196 }
197
198 pub fn as_nonsecret(&self) -> &EncodedPoint<E> {
203 secret::inner_ref(&self.0)
204 }
205}
206
207impl<E: Curve> fmt::Debug for EncodedSecretPoint<E> {
208 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
209 f.write_str("SecretEncodedPoint")
210 }
211}
212
213impl<E: Curve> ConstantTimeEq for EncodedSecretPoint<E> {
214 fn ct_eq(&self, other: &Self) -> Choice {
215 self.0.ct_eq(&other.0)
216 }
217}
218
219#[derive(Clone, Default)]
228pub struct EncodedSecretScalar<E: Curve>(secret::Secret<EncodedScalar<E>>);
229
230impl<E: Curve> EncodedSecretScalar<E> {
231 pub fn new(mut scalar: EncodedScalar<E>) -> Self {
233 Self(secret::new(&mut scalar))
234 }
235
236 pub fn as_nonsecret_bytes(&self) -> &[u8] {
240 self.0.as_bytes()
241 }
242
243 pub fn as_nonsecret(&self) -> &EncodedScalar<E> {
248 secret::inner_ref(&self.0)
249 }
250}
251
252impl<E: Curve> fmt::Debug for EncodedSecretScalar<E> {
253 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254 f.write_str("SecretEncodedScalar")
255 }
256}
257
258impl<E: Curve> ConstantTimeEq for EncodedSecretScalar<E> {
259 fn ct_eq(&self, other: &Self) -> Choice {
260 self.0.ct_eq(&other.0)
261 }
262}