-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathprivate.rs
More file actions
68 lines (58 loc) · 2.07 KB
/
private.rs
File metadata and controls
68 lines (58 loc) · 2.07 KB
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
// SPDX-License-Identifier: Apache-2.0
//
// Copyright © 2017 Trust Wallet.
use crate::ed25519::public::PublicKey;
use crate::ed25519::secret::ExpandedSecretKey;
use crate::ed25519::signature::Signature;
use crate::ed25519::Hasher512;
use crate::traits::SigningKeyTrait;
use crate::{KeyPairError, KeyPairResult};
use tw_encoding::hex;
use tw_hash::H256;
use tw_misc::traits::ToBytesZeroizing;
use zeroize::{ZeroizeOnDrop, Zeroizing};
/// Represents an `ed25519` private key.
#[derive(Clone, ZeroizeOnDrop)]
pub struct PrivateKey<H: Hasher512> {
secret: H256,
/// An expanded secret key obtained from [`PrivateKey::secret`].
/// It's used to generate a public key and sign messages.
expanded_key: ExpandedSecretKey<H>,
}
impl<H: Hasher512> PrivateKey<H> {
/// Returns an associated `ed25519` public key.
pub fn public(&self) -> PublicKey<H> {
PublicKey::with_expanded_secret(&self.expanded_key)
}
}
impl<H: Hasher512> SigningKeyTrait for PrivateKey<H> {
type SigningMessage = Vec<u8>;
type Signature = Signature;
fn sign(&self, message: Self::SigningMessage) -> KeyPairResult<Self::Signature> {
self.expanded_key
.dangerous_sign_with_pubkey(self.public().to_bytes(), &message)
}
}
impl<H: Hasher512> TryFrom<&[u8]> for PrivateKey<H> {
type Error = KeyPairError;
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
let secret = H256::try_from(data).map_err(|_| KeyPairError::InvalidSecretKey)?;
let expanded_key = ExpandedSecretKey::<H>::with_secret(secret);
Ok(PrivateKey {
secret,
expanded_key,
})
}
}
impl<'a, H: Hasher512> TryFrom<&'a str> for PrivateKey<H> {
type Error = KeyPairError;
fn try_from(hex: &'a str) -> Result<Self, Self::Error> {
let bytes = Zeroizing::new(hex::decode(hex).map_err(|_| KeyPairError::InvalidSecretKey)?);
Self::try_from(bytes.as_slice())
}
}
impl<H: Hasher512> ToBytesZeroizing for PrivateKey<H> {
fn to_zeroizing_vec(&self) -> Zeroizing<Vec<u8>> {
Zeroizing::new(self.secret.to_vec())
}
}