1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#![cfg(any(test, feature = "testutils"))]
pub trait Sign<MSG> {
type Signature;
type Error;
fn sign(&self, m: MSG) -> Result<Self::Signature, Self::Error>;
}
pub mod ed25519 {
use xdr::WriteXdr;
use crate::xdr;
#[derive(Debug)]
pub enum Error<E: std::error::Error> {
XdrError(xdr::Error),
Ed25519SignatureError(ed25519_dalek::SignatureError),
ConversionError(E),
}
impl<E: std::error::Error> std::error::Error for Error<E> {
#[must_use]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::XdrError(e) => e.source(),
Self::Ed25519SignatureError(e) => e.source(),
Self::ConversionError(e) => e.source(),
}
}
}
impl<E: std::error::Error> std::fmt::Display for Error<E> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::XdrError(e) => write!(f, "{}", e),
Self::Ed25519SignatureError(e) => write!(f, "{}", e),
Self::ConversionError(e) => write!(f, "{}", e),
}
}
}
impl<E: std::error::Error> From<xdr::Error> for Error<E> {
fn from(e: xdr::Error) -> Self {
Error::XdrError(e)
}
}
impl<E: std::error::Error> From<ed25519_dalek::SignatureError> for Error<E> {
fn from(e: ed25519_dalek::SignatureError) -> Self {
Error::Ed25519SignatureError(e)
}
}
pub use super::Sign;
impl<S, M> Sign<M> for S
where
S: ed25519_dalek::Signer<ed25519_dalek::Signature>,
M: TryInto<xdr::ScVal>,
<M as TryInto<xdr::ScVal>>::Error: std::error::Error,
{
type Error = Error<<M as TryInto<xdr::ScVal>>::Error>;
type Signature = [u8; 64];
fn sign(&self, m: M) -> Result<Self::Signature, Self::Error> {
let mut buf = Vec::<u8>::new();
let val: xdr::ScVal = m.try_into().map_err(Self::Error::ConversionError)?;
val.write_xdr(&mut buf)?;
Ok(self.try_sign(&buf)?.to_bytes())
}
}
#[cfg(test)]
mod test {
use ed25519_dalek::{Keypair, PublicKey, SecretKey};
use super::Sign;
#[test]
fn sign() {
let sk = SecretKey::from_bytes(
&hex::decode("5acc7253295dfc356c046297925a369f3d2762d00afdf2583ecbe92180b07c37")
.unwrap(),
)
.unwrap();
let pk = PublicKey::from(&sk);
let kp = Keypair {
secret: sk,
public: pk,
};
let sig = kp.sign(128i64).unwrap();
assert_eq!(
hex::encode(sig),
"082f78fb1864f6914de4c3c4e3e0c6e7c63a6a866aa81bda8042f74155cb95e7d29958061a11568f03db137cbf17c8b7bbf6193b2901af9888bbdf150c7be00a",
);
}
}
}