commonware_stream/public_key/
x25519.rs1use bytes::{Buf, BufMut};
4use commonware_codec::{Error as CodecError, FixedSize, Read, ReadExt, Write};
5use rand::{CryptoRng, Rng};
6use x25519_dalek::{EphemeralSecret, PublicKey as X25519PublicKey};
7
8#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
10pub struct PublicKey {
11 inner: X25519PublicKey,
12}
13
14impl PublicKey {
15 pub fn from_secret(secret: &EphemeralSecret) -> Self {
17 PublicKey {
18 inner: X25519PublicKey::from(secret),
19 }
20 }
21
22 pub fn from_bytes(array: [u8; 32]) -> Self {
24 PublicKey {
25 inner: X25519PublicKey::from(array),
26 }
27 }
28}
29
30impl AsRef<x25519_dalek::PublicKey> for PublicKey {
31 fn as_ref(&self) -> &x25519_dalek::PublicKey {
32 &self.inner
33 }
34}
35
36impl Write for PublicKey {
37 fn write(&self, buf: &mut impl BufMut) {
38 self.inner.as_bytes().write(buf);
39 }
40}
41
42impl Read for PublicKey {
43 type Cfg = ();
44
45 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, CodecError> {
46 let public_key = <[u8; Self::SIZE]>::read(buf)?;
47 Ok(PublicKey {
48 inner: X25519PublicKey::from(public_key),
49 })
50 }
51}
52
53impl FixedSize for PublicKey {
54 const SIZE: usize = 32;
55}
56
57pub fn new<R: Rng + CryptoRng>(rng: &mut R) -> EphemeralSecret {
62 EphemeralSecret::random_from_rng(rng)
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use bytes::Bytes;
69 use commonware_codec::{DecodeExt, Encode as _};
70 use commonware_runtime::{deterministic, Runner};
71
72 #[test]
73 fn test_codec() {
74 let executor = deterministic::Runner::default();
75 executor.start(|mut context| async move {
76 let mut buf = [0u8; PublicKey::SIZE];
78 context.fill(&mut buf);
79 let original = PublicKey {
80 inner: X25519PublicKey::from(buf),
81 };
82 let encoded = original.encode();
84 assert_eq!(encoded.len(), PublicKey::SIZE);
85 let decoded = PublicKey::decode(encoded).unwrap();
86 assert_eq!(original, decoded);
87 });
88 }
89
90 #[test]
91 fn test_decode_invalid() {
92 let invalid_bytes = Bytes::from(vec![1, 2, 3]); let result = PublicKey::decode(invalid_bytes);
95 assert!(result.is_err());
96
97 let too_long_bytes = Bytes::from(vec![0u8; 33]); let result = PublicKey::decode(too_long_bytes);
100 assert!(result.is_err());
101 }
102}