rust_eigenda_v2_client/
utils.rs

1use std::str::FromStr;
2
3use crate::{
4    core::BYTES_PER_SYMBOL,
5    errors::{ConversionError, EigenClientError},
6};
7use ark_bn254::Fr;
8use ark_ff::fields::PrimeField;
9use secrecy::{ExposeSecret, Secret};
10use url::Url;
11
12#[derive(Debug, Clone)]
13/// A URL stored securely using the `Secret` type from the secrecy crate
14pub struct SecretUrl {
15    // We keep the URL as a String because Secret<T> enforces T: DefaultIsZeroes
16    // which is not the case for the type Url
17    inner: Secret<String>,
18}
19
20impl SecretUrl {
21    /// Create a new `SecretUrl` from a `Url`
22    pub fn new(url: Url) -> Self {
23        Self {
24            inner: Secret::new(url.to_string()),
25        }
26    }
27}
28
29impl TryFrom<SecretUrl> for String {
30    type Error = ConversionError;
31
32    fn try_from(secret_url: SecretUrl) -> Result<Self, Self::Error> {
33        Ok(secret_url.inner.expose_secret().clone())
34    }
35}
36
37impl From<SecretUrl> for Url {
38    fn from(secret_url: SecretUrl) -> Url {
39        Url::from_str(secret_url.inner.expose_secret()).unwrap() // Safe unwrap, as we know inner is a valid URL
40    }
41}
42
43impl PartialEq for SecretUrl {
44    fn eq(&self, other: &Self) -> bool {
45        self.inner.expose_secret().eq(other.inner.expose_secret())
46    }
47}
48
49/// Secretly enclosed Private Key
50#[derive(Debug, Clone)]
51pub struct PrivateKey(pub Secret<String>);
52
53impl PartialEq for PrivateKey {
54    fn eq(&self, other: &Self) -> bool {
55        self.0.expose_secret().eq(other.0.expose_secret())
56    }
57}
58
59impl FromStr for PrivateKey {
60    type Err = EigenClientError;
61
62    fn from_str(s: &str) -> Result<Self, Self::Err> {
63        Ok(PrivateKey(
64            s.parse().map_err(|_| ConversionError::PrivateKey)?,
65        ))
66    }
67}
68
69pub(crate) fn pad_to_bytes_per_symbol(input_bytes: &[u8]) -> Vec<u8> {
70    let remainder = input_bytes.len() % BYTES_PER_SYMBOL;
71    match remainder == 0 {
72        true => {
73            // no padding necessary, since bytes are already a multiple of BYTES_PER_SYMBOL
74            input_bytes.to_vec()
75        }
76        false => {
77            let necessary_padding = BYTES_PER_SYMBOL - remainder;
78            let mut padded_bytes = input_bytes.to_vec();
79            padded_bytes.extend(vec![0; necessary_padding]);
80            padded_bytes
81        }
82    }
83}
84
85/// fr_array_from_bytes accept a byte array as an input, and converts it to an array of field elements
86pub(crate) fn fr_array_from_bytes(input_data: &[u8]) -> Vec<Fr> {
87    let bytes = pad_to_bytes_per_symbol(input_data);
88
89    let element_count = bytes.len() / BYTES_PER_SYMBOL;
90    let mut output_elements = Vec::new();
91    for i in 0..element_count {
92        let start_idx = i * BYTES_PER_SYMBOL;
93        let end_idx = start_idx + BYTES_PER_SYMBOL;
94        output_elements.push(Fr::from_be_bytes_mod_order(&bytes[start_idx..end_idx]))
95    }
96    output_elements
97}