Skip to content

Commit 60d28a9

Browse files
committed
feat(p2p/identity): signing
1 parent 6d8f1d9 commit 60d28a9

File tree

4 files changed

+149
-15
lines changed

4 files changed

+149
-15
lines changed

node/common/src/service/p2p.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,28 +123,23 @@ impl P2pCryptoService for NodeService {
123123
fn sign_key(&mut self, key: &[u8; 32]) -> Vec<u8> {
124124
// TODO: make deterministic
125125
let msg = [b"noise-libp2p-static-key:", key.as_slice()].concat();
126-
let sig = self
127-
.p2p
128-
.mio
129-
.keypair()
130-
.sign(&msg)
131-
.expect("unable to create signature");
126+
let sig = self.p2p.sec_key.sign(&msg);
127+
let libp2p_sec_key = libp2p_identity::Keypair::try_from(self.p2p.sec_key.clone()).unwrap();
132128

133129
let mut payload = vec![];
134130
payload.extend_from_slice(b"\x0a\x24");
135-
payload.extend_from_slice(&self.p2p.mio.keypair().public().encode_protobuf());
131+
payload.extend_from_slice(&libp2p_sec_key.public().encode_protobuf());
136132
payload.extend_from_slice(b"\x12\x40");
137-
payload.extend_from_slice(&sig);
133+
payload.extend_from_slice(&sig.to_bytes());
138134
payload
139135
}
140136

141137
fn sign_publication(&mut self, publication: &[u8]) -> Vec<u8> {
142-
let msg = [b"libp2p-pubsub:", publication].concat();
143138
self.p2p
144-
.mio
145-
.keypair()
146-
.sign(&msg)
147-
.expect("unable to create signature")
139+
.sec_key
140+
.libp2p_pubsub_sign(publication)
141+
.to_bytes()
142+
.to_vec()
148143
}
149144

150145
fn verify_publication(

p2p/src/identity/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ pub use public_key::PublicKey;
66

77
mod secret_key;
88
pub use secret_key::{EncryptableType, SecretKey};
9+
10+
mod signature;
11+
pub use signature::Signature;

p2p/src/identity/secret_key.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::{fmt, path::Path, str::FromStr};
22

33
use base64::Engine;
4-
use ed25519_dalek::SigningKey as Ed25519SecretKey;
4+
use ed25519_dalek::{ed25519::signature::SignerMut, SigningKey as Ed25519SecretKey};
55
use openmina_core::{EncryptedSecretKey, EncryptedSecretKeyFile, EncryptionError};
66
use rand::{CryptoRng, Rng};
77
use serde::{Deserialize, Serialize};
88

9-
use crate::identity::PublicKey;
9+
use super::{PublicKey, Signature};
1010

1111
#[derive(Clone)]
1212
pub struct SecretKey(Ed25519SecretKey);
@@ -170,6 +170,14 @@ impl SecretKey {
170170
let data: Vec<u8> = self.decrypt_raw(other_pk, ciphertext.as_ref())?;
171171
serde_json::from_slice(&data).map_err(Box::<dyn std::error::Error>::from)
172172
}
173+
174+
pub fn sign(&mut self, data: &[u8]) -> Signature {
175+
Signature(self.0.sign(data))
176+
}
177+
178+
pub fn libp2p_pubsub_sign(&mut self, msg: &[u8]) -> Signature {
179+
self.sign(&[b"libp2p-pubsub:", msg].concat())
180+
}
173181
}
174182

175183
pub trait EncryptableType: Serialize + for<'a> Deserialize<'a> {

p2p/src/identity/signature.rs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
use std::{
2+
fmt,
3+
io::{Read, Write},
4+
str::FromStr,
5+
};
6+
7+
use binprot::{BinProtRead, BinProtWrite};
8+
use ed25519_dalek::Signature as Ed25519Signature;
9+
use serde::{
10+
de::{SeqAccess, Visitor},
11+
Deserialize, Serialize,
12+
};
13+
14+
#[derive(Eq, PartialEq, Clone)]
15+
pub struct Signature(pub(super) Ed25519Signature);
16+
17+
impl Signature {
18+
const BYTE_SIZE: usize = Ed25519Signature::BYTE_SIZE;
19+
20+
pub fn from_bytes(bytes: [u8; Self::BYTE_SIZE]) -> Self {
21+
Self(Ed25519Signature::from_bytes(&bytes))
22+
}
23+
24+
pub fn to_bytes(&self) -> [u8; Self::BYTE_SIZE] {
25+
self.0.to_bytes()
26+
}
27+
}
28+
29+
impl FromStr for Signature {
30+
type Err = hex::FromHexError;
31+
32+
fn from_str(s: &str) -> Result<Self, Self::Err> {
33+
hex::decode(s)?
34+
.try_into()
35+
.map(Self::from_bytes)
36+
.or(Err(hex::FromHexError::InvalidStringLength))
37+
}
38+
}
39+
40+
impl fmt::Display for Signature {
41+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42+
write!(f, "{}", hex::encode(self.to_bytes()))
43+
}
44+
}
45+
46+
impl fmt::Debug for Signature {
47+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48+
write!(f, "Signature({self})")
49+
}
50+
}
51+
52+
impl From<Signature> for [u8; Signature::BYTE_SIZE] {
53+
fn from(value: Signature) -> Self {
54+
value.to_bytes()
55+
}
56+
}
57+
58+
impl Serialize for Signature {
59+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
60+
where
61+
S: serde::Serializer,
62+
{
63+
if serializer.is_human_readable() {
64+
serializer.serialize_str(&self.to_string())
65+
} else {
66+
self.to_bytes().serialize(serializer)
67+
}
68+
}
69+
}
70+
71+
impl<'de> serde::Deserialize<'de> for Signature {
72+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
73+
where
74+
D: serde::Deserializer<'de>,
75+
{
76+
if deserializer.is_human_readable() {
77+
let s: String = Deserialize::deserialize(deserializer)?;
78+
Ok(s.parse().map_err(serde::de::Error::custom)?)
79+
} else {
80+
struct ArrayVisitor;
81+
82+
impl<'de> Visitor<'de> for ArrayVisitor {
83+
type Value = [u8; Signature::BYTE_SIZE];
84+
85+
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
86+
write!(f, "signature bytes({})", Signature::BYTE_SIZE)
87+
}
88+
89+
#[inline]
90+
fn visit_seq<A>(self, mut a: A) -> Result<Self::Value, A::Error>
91+
where
92+
A: SeqAccess<'de>,
93+
{
94+
let mut bytes: Self::Value = [0; Signature::BYTE_SIZE];
95+
96+
for (i, byte) in bytes.iter_mut().enumerate() {
97+
*byte = a
98+
.next_element()?
99+
.ok_or(serde::de::Error::invalid_length(i + 1, &self))?;
100+
}
101+
102+
Ok(bytes)
103+
}
104+
}
105+
106+
deserializer
107+
.deserialize_tuple(Self::BYTE_SIZE, ArrayVisitor)
108+
.map(Self::from_bytes)
109+
}
110+
}
111+
}
112+
113+
impl BinProtWrite for Signature {
114+
fn binprot_write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
115+
w.write_all(&self.to_bytes())
116+
}
117+
}
118+
119+
impl BinProtRead for Signature {
120+
fn binprot_read<R: Read + ?Sized>(r: &mut R) -> Result<Self, binprot::Error>
121+
where
122+
Self: Sized,
123+
{
124+
let mut buf = [0; Ed25519Signature::BYTE_SIZE];
125+
r.read_exact(&mut buf)?;
126+
Ok(Self::from_bytes(buf))
127+
}
128+
}

0 commit comments

Comments
 (0)