ecvrf_rs/
traits.rs

1use core::fmt;
2
3use schemars::{
4    gen::SchemaGenerator,
5    schema::{InstanceType, Schema, SchemaObject},
6    JsonSchema,
7};
8use serde::{
9    de::{Error, IgnoredAny, MapAccess, SeqAccess, Visitor},
10    ser::SerializeStruct,
11    Deserialize, Deserializer, Serialize, Serializer,
12};
13
14use crate::{Proof, PublicKey, SecretKey};
15use std::{
16    fmt::{Formatter, Write},
17    num::ParseIntError,
18};
19
20impl AsRef<[u8]> for SecretKey {
21    fn as_ref(&self) -> &[u8] {
22        &self.bytes
23    }
24}
25
26/// Decodes a hex-encoded string into a byte array.
27///
28/// # Errors
29///
30/// This function will return an error if the string is not hex-encoded.
31pub fn decode_hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
32    (0..s.len())
33        .step_by(2)
34        .map(|i| u8::from_str_radix(&s[i..i + 2], 16))
35        .collect()
36}
37
38/// Encodes a byte array into a hex-encoded string.
39///
40/// # Panics
41///
42/// Panics if the call to [`write!`] returns an error.
43#[must_use]
44pub fn encode_hex(bytes: &[u8]) -> String {
45    let mut s = String::with_capacity(bytes.len() * 2);
46    for &b in bytes {
47        write!(&mut s, "{:02x}", b).unwrap();
48    }
49    s
50}
51
52impl fmt::Display for SecretKey {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        write!(f, "{}", encode_hex(&self.bytes))?;
55        Ok(())
56    }
57}
58
59impl fmt::Display for PublicKey {
60    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61        write!(f, "{}", encode_hex(self.point.as_bytes()))?;
62        Ok(())
63    }
64}
65
66impl Serialize for PublicKey {
67    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68    where
69        S: Serializer,
70    {
71        serializer.serialize_str(&encode_hex(self.point.as_bytes()))
72    }
73}
74
75impl Serialize for SecretKey {
76    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
77    where
78        S: Serializer,
79    {
80        serializer.serialize_str(&encode_hex(self.as_bytes()))
81    }
82}
83
84impl Serialize for Proof {
85    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86    where
87        S: Serializer,
88    {
89        let mut state = serializer.serialize_struct("Proof", 3)?;
90        state.serialize_field("signer", &self.signer)?;
91        state.serialize_field("message", &encode_hex(&self.message_bytes))?;
92        state.serialize_field("proof", &encode_hex(&self.proof_bytes))?;
93        state.end()
94    }
95}
96
97impl<'de> Deserialize<'de> for PublicKey {
98    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
99    where
100        D: Deserializer<'de>,
101    {
102        struct PublicKeyVisitor;
103
104        impl<'de> Visitor<'de> for PublicKeyVisitor {
105            type Value = PublicKey;
106
107            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
108                formatter.write_str("PublicKey bytes")
109            }
110
111            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
112            where
113                E: Error,
114            {
115                Ok(PublicKey::from_bytes(
116                    decode_hex(v)
117                        .map_err(|_| E::custom("Error decoding PublicKey bytes"))?
118                        .as_slice(),
119                ))
120            }
121        }
122
123        deserializer.deserialize_str(PublicKeyVisitor)
124    }
125}
126
127impl<'de> Deserialize<'de> for SecretKey {
128    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
129    where
130        D: Deserializer<'de>,
131    {
132        struct SecretKeyVisitor;
133
134        impl<'de> Visitor<'de> for SecretKeyVisitor {
135            type Value = SecretKey;
136
137            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
138                formatter.write_str("SecretKey bytes")
139            }
140
141            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
142            where
143                E: Error,
144            {
145                Ok(SecretKey::from_slice(
146                    decode_hex(v)
147                        .map_err(|_| E::custom("Error decoding Secretkey bytes"))?
148                        .as_slice(),
149                ))
150            }
151        }
152
153        deserializer.deserialize_str(SecretKeyVisitor)
154    }
155}
156
157impl<'de> Deserialize<'de> for Proof {
158    #[allow(clippy::too_many_lines)]
159    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
160    where
161        D: Deserializer<'de>,
162    {
163        enum Field {
164            Signer,
165            Message,
166            Proof,
167            Ignore,
168        }
169
170        struct FieldVisitor;
171
172        impl<'de> Visitor<'de> for FieldVisitor {
173            type Value = Field;
174
175            fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
176                formatter.write_str("field identifier")
177            }
178
179            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
180            where
181                E: Error,
182            {
183                match v {
184                    0u64 => Ok(Field::Signer),
185                    1u64 => Ok(Field::Message),
186                    2u64 => Ok(Field::Proof),
187                    _ => Ok(Field::Ignore),
188                }
189            }
190
191            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
192            where
193                E: Error,
194            {
195                match v {
196                    "signer" => Ok(Field::Signer),
197                    "message" => Ok(Field::Message),
198                    "proof" => Ok(Field::Proof),
199                    _ => Ok(Field::Ignore),
200                }
201            }
202
203            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
204            where
205                E: Error,
206            {
207                match v {
208                    b"signer" => Ok(Field::Signer),
209                    b"message" => Ok(Field::Message),
210                    b"proof" => Ok(Field::Proof),
211                    _ => Ok(Field::Ignore),
212                }
213            }
214        }
215
216        impl<'de> Deserialize<'de> for Field {
217            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
218            where
219                D: Deserializer<'de>,
220            {
221                deserializer.deserialize_identifier(FieldVisitor)
222            }
223        }
224
225        struct ProofVisitor;
226
227        impl<'de> Visitor<'de> for ProofVisitor {
228            type Value = Proof;
229
230            fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
231                formatter.write_str("struct Proof")
232            }
233
234            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
235            where
236                A: SeqAccess<'de>,
237            {
238                let signer = seq
239                    .next_element::<PublicKey>()?
240                    .ok_or_else(|| A::Error::invalid_length(0, &"struct Proof with 3 elements"))?;
241                let message = seq
242                    .next_element::<String>()?
243                    .ok_or_else(|| A::Error::invalid_length(1, &"struct Proof with 3 elements"))?;
244                let proof = seq
245                    .next_element::<String>()?
246                    .ok_or_else(|| A::Error::invalid_length(2, &"struct Proof with 3 elements"))?;
247                Ok(Proof {
248                    signer,
249                    message_bytes: decode_hex(message.as_str())
250                        .map_err(|_| A::Error::custom("Error decoding message"))?,
251                    proof_bytes: decode_hex(proof.as_str())
252                        .map_err(|_| A::Error::custom("Error decoding proof"))?,
253                })
254            }
255
256            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
257            where
258                A: MapAccess<'de>,
259            {
260                let mut signer = None;
261                let mut message = None;
262                let mut proof = None;
263                while let Some(key) = map.next_key::<Field>()? {
264                    match key {
265                        Field::Signer => {
266                            if signer.is_some() {
267                                return Err(A::Error::duplicate_field("signer"));
268                            }
269                            signer = Some(map.next_value::<PublicKey>()?);
270                        }
271                        Field::Message => {
272                            if message.is_some() {
273                                return Err(A::Error::duplicate_field("message"));
274                            }
275                            message = Some(map.next_value::<String>()?);
276                        }
277                        Field::Proof => {
278                            if proof.is_some() {
279                                return Err(A::Error::duplicate_field("proof"));
280                            }
281                            proof = Some(map.next_value::<String>()?);
282                        }
283                        Field::Ignore => {
284                            let _ = map.next_value::<IgnoredAny>()?;
285                        }
286                    }
287                }
288                let signer = signer.ok_or_else(|| A::Error::missing_field("signer"))?;
289                let message = message.ok_or_else(|| A::Error::missing_field("message"))?;
290                let proof = proof.ok_or_else(|| A::Error::missing_field("proof"))?;
291                Ok(Proof {
292                    signer,
293                    message_bytes: decode_hex(message.as_str())
294                        .map_err(|_| A::Error::custom("Error decoding message"))?,
295                    proof_bytes: decode_hex(proof.as_str())
296                        .map_err(|_| A::Error::custom("Error decoding proof"))?,
297                })
298            }
299        }
300
301        const FIELDS: &[&str] = &["signer", "message", "proof"];
302        deserializer.deserialize_struct("Proof", FIELDS, ProofVisitor)
303    }
304}
305
306impl JsonSchema for SecretKey {
307    fn schema_name() -> String {
308        "SecretKey".to_owned()
309    }
310    fn json_schema(_: &mut SchemaGenerator) -> Schema {
311        let mut schema_object = SchemaObject {
312            instance_type: Some(InstanceType::String.into()),
313            ..Default::default()
314        };
315        let string_validation = schema_object.string();
316        string_validation.min_length = Some(64u32);
317        string_validation.max_length = Some(64u32);
318        Schema::Object(schema_object)
319    }
320}
321
322impl JsonSchema for PublicKey {
323    fn schema_name() -> String {
324        "PublicKey".to_owned()
325    }
326    fn json_schema(_: &mut SchemaGenerator) -> Schema {
327        let mut schema_object = SchemaObject {
328            instance_type: Some(InstanceType::String.into()),
329            ..Default::default()
330        };
331        let string_validation = schema_object.string();
332        string_validation.min_length = Some(64u32);
333        string_validation.max_length = Some(64u32);
334        Schema::Object(schema_object)
335    }
336}
337
338impl JsonSchema for Proof {
339    fn schema_name() -> String {
340        "Proof".to_owned()
341    }
342
343    fn json_schema(gen: &mut SchemaGenerator) -> Schema {
344        let mut schema_object = SchemaObject {
345            instance_type: Some(InstanceType::Object.into()),
346            ..Default::default()
347        };
348        let object_validation = schema_object.object();
349        {
350            // signer
351            object_validation
352                .properties
353                .insert("signer".to_owned(), gen.subschema_for::<PublicKey>());
354            object_validation.required.insert("signer".to_owned());
355        }
356        {
357            // message
358            object_validation
359                .properties
360                .insert("message".to_owned(), gen.subschema_for::<String>());
361            object_validation.required.insert("message".to_owned());
362        }
363
364        {
365            // proof
366            object_validation
367                .properties
368                .insert("proof".to_owned(), gen.subschema_for::<String>());
369            object_validation.required.insert("proof".to_owned());
370        }
371        Schema::Object(schema_object)
372    }
373}