hopr_crypto_types/
utils.rs1use cipher::zeroize;
2use generic_array::{ArrayLength, GenericArray};
3use hopr_crypto_random::{Randomizable, random_array};
4use k256::{
5 AffinePoint, Secp256k1,
6 elliptic_curve::{
7 PrimeField,
8 hash2curve::{ExpandMsgXmd, GroupDigest},
9 point::NonIdentity,
10 },
11};
12use sha3::Sha3_256;
13use subtle::{Choice, ConstantTimeEq};
14use typenum::Unsigned;
15
16use crate::{
17 errors::{
18 CryptoError,
19 CryptoError::{CalculationError, InvalidInputValue, InvalidParameterSize},
20 },
21 prelude::{HalfKey, SecretKey},
22 types::PublicKey,
23};
24
25pub(crate) fn random_group_element() -> ([u8; 32], NonIdentity<AffinePoint>) {
28 let scalar = k256::NonZeroScalar::random(&mut hopr_crypto_random::rng());
30 let point =
31 PublicKey::from_privkey(&scalar.to_bytes()).expect("non-zero scalar cannot represent an invalid public key");
32 (scalar.to_bytes().into(), point.into())
33}
34
35pub fn x25519_scalar_from_bytes(bytes: &[u8]) -> crate::errors::Result<curve25519_dalek::scalar::Scalar> {
39 if bytes.len() == 32 {
40 let mut clamped = [0u8; 32];
42 clamped.copy_from_slice(&bytes[..32]);
43 clamped[00] &= 0b1111_1000; clamped[31] &= 0b0111_1111; clamped[31] |= 0b0100_0000; Ok(curve25519_dalek::scalar::Scalar::from_bytes_mod_order(clamped))
48 } else {
49 Err(InvalidInputValue("bytes"))
50 }
51}
52
53pub fn k256_scalar_from_bytes(bytes: &[u8]) -> crate::errors::Result<k256::Scalar> {
56 if bytes.len() == k256::elliptic_curve::FieldBytesSize::<Secp256k1>::to_usize() {
57 Option::from(k256::Scalar::from_repr(*k256::FieldBytes::from_slice(bytes))).ok_or(InvalidInputValue("bytes"))
58 } else {
59 Err(InvalidInputValue("bytes"))
60 }
61}
62
63pub fn sample_secp256k1_field_element(secret: &[u8], tag: &str) -> crate::errors::Result<HalfKey> {
70 if secret.len() >= SecretKey::LENGTH {
71 let scalar = Secp256k1::hash_to_scalar::<ExpandMsgXmd<Sha3_256>>(
72 &[secret],
73 &[b"secp256k1_XMD:SHA3-256_SSWU_RO_", tag.as_bytes()],
74 )
75 .map_err(|_| CalculationError)?;
76 Ok(HalfKey::try_from(scalar.to_bytes().as_ref())?)
77 } else {
78 Err(InvalidParameterSize {
79 name: "secret",
80 expected: SecretKey::LENGTH,
81 })
82 }
83}
84
85#[derive(Clone, zeroize::ZeroizeOnDrop)]
89pub struct SecretValue<L: ArrayLength>(GenericArray<u8, L>);
90
91impl<L: ArrayLength> ConstantTimeEq for SecretValue<L> {
92 fn ct_eq(&self, other: &Self) -> Choice {
93 self.0.ct_eq(&other.0)
94 }
95}
96
97impl<L: ArrayLength> AsRef<[u8]> for SecretValue<L> {
98 fn as_ref(&self) -> &[u8] {
99 self.0.as_ref()
100 }
101}
102
103impl<L: ArrayLength> From<GenericArray<u8, L>> for SecretValue<L> {
104 fn from(value: GenericArray<u8, L>) -> Self {
105 Self(value)
106 }
107}
108
109impl<'a, L: ArrayLength> From<&'a SecretValue<L>> for &'a GenericArray<u8, L> {
110 fn from(value: &'a SecretValue<L>) -> Self {
111 &value.0
112 }
113}
114
115impl<L: ArrayLength> TryFrom<&[u8]> for SecretValue<L> {
116 type Error = CryptoError;
117
118 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
119 if value.len() == Self::LENGTH {
120 Ok(Self(GenericArray::from_slice(value).clone()))
121 } else {
122 Err(InvalidInputValue("value"))
123 }
124 }
125}
126
127impl<L: ArrayLength> Default for SecretValue<L> {
128 fn default() -> Self {
129 Self(GenericArray::default())
130 }
131}
132
133impl<L: ArrayLength> AsMut<[u8]> for SecretValue<L> {
134 fn as_mut(&mut self) -> &mut [u8] {
135 self.0.as_mut()
136 }
137}
138
139impl<L: ArrayLength> From<SecretValue<L>> for Box<[u8]> {
140 fn from(value: SecretValue<L>) -> Self {
141 value.as_ref().into()
142 }
143}
144
145impl From<SecretValue<typenum::U32>> for [u8; 32] {
146 fn from(value: SecretValue<typenum::U32>) -> Self {
147 value.0.into_array()
148 }
149}
150
151#[cfg(feature = "serde")]
152impl<L: ArrayLength> serde::Serialize for SecretValue<L> {
153 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
154 where
155 S: serde::Serializer,
156 {
157 self.0.serialize(serializer)
158 }
159}
160
161#[cfg(feature = "serde")]
162impl<'de, L: ArrayLength> serde::Deserialize<'de> for SecretValue<L> {
163 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
164 where
165 D: serde::Deserializer<'de>,
166 {
167 Ok(Self(GenericArray::deserialize(deserializer)?))
168 }
169}
170
171impl<L: ArrayLength> SecretValue<L> {
172 pub const LENGTH: usize = L::USIZE;
174}
175
176impl<L: ArrayLength> Randomizable for SecretValue<L> {
177 fn random() -> Self {
179 Self(random_array())
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186
187 #[test]
188 fn test_sample_field_element() {
189 let secret = [1u8; SecretKey::LENGTH];
190 assert!(sample_secp256k1_field_element(&secret, "TEST_TAG").is_ok());
191 }
192}