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
//! Public-key abstraction used by [`crate::script::Script`].
//!
//! Replaces the Go `crypto.PublicKey` type-switch in `getPubKeyBytes` with a
//! small enum over the key types outscript understands.
use crate::crypto::secp256k1::SecpPublicKey;
/// A public key understood by outscript: either secp256k1 or Ed25519.
#[derive(Clone)]
pub enum PubKey {
/// A secp256k1 public key (Bitcoin, EVM, ...).
Secp256k1(SecpPublicKey),
/// A raw 32-byte Ed25519 public key (Solana, Massa).
Ed25519([u8; 32]),
}
impl PubKey {
/// Returns the public-key bytes for the requested internal format name
/// (`pubkey:comp`, `pubkey:uncomp`, `pubkey:ed25519`). Mirrors the Go
/// `Script.getPubKeyBytes`.
pub fn bytes_for(&self, typ: &str) -> Result<Vec<u8>, String> {
match (typ, self) {
("pubkey:ed25519", PubKey::Ed25519(k)) => Ok(k.to_vec()),
("pubkey:comp", PubKey::Secp256k1(k)) => Ok(k.serialize_compressed().to_vec()),
("pubkey:uncomp", PubKey::Secp256k1(k)) => Ok(k.serialize_uncompressed().to_vec()),
("pubkey:ed25519" | "pubkey:comp" | "pubkey:uncomp", _) => {
Err(format!("public key does not support {typ} export"))
}
_ => Err(format!("unknown public key format {typ}")),
}
}
}
impl From<SecpPublicKey> for PubKey {
fn from(k: SecpPublicKey) -> Self {
PubKey::Secp256k1(k)
}
}