cargo_tangle/
keys.rs

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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use clap::builder::PossibleValue;
use clap::ValueEnum;
use color_eyre::eyre::eyre;
use gadget_sdk::keystore::backend::fs::FilesystemKeystore;
use gadget_sdk::keystore::backend::mem::InMemoryKeystore;
use gadget_sdk::keystore::backend::GenericKeyStore;
use gadget_sdk::keystore::Backend;
use gadget_sdk::parking_lot::RawRwLock;
use std::path::PathBuf;
use std::str::FromStr;
use w3f_bls::serialize::SerializableToBytes;

#[derive(Clone, Debug)]
pub enum KeyType {
    Sr25519,
    Ed25519,
    Ecdsa,
    Bls381,
    BlsBn254,
}

impl ValueEnum for KeyType {
    fn value_variants<'a>() -> &'a [Self] {
        &[
            Self::Sr25519,
            Self::Ed25519,
            Self::Ecdsa,
            Self::Bls381,
            Self::BlsBn254,
        ]
    }

    fn to_possible_value(&self) -> Option<PossibleValue> {
        Some(match self {
            Self::Sr25519 => PossibleValue::new("sr25519").help("Schnorrkel/Ristretto x25519"),
            Self::Ed25519 => PossibleValue::new("ed25519").help("Edwards Curve 25519"),
            Self::Ecdsa => {
                PossibleValue::new("ecdsa").help("Elliptic Curve Digital Signature Algorithm")
            }
            Self::Bls381 => PossibleValue::new("bls381").help("Boneh-Lynn-Shacham on BLS12-381"),
            Self::BlsBn254 => PossibleValue::new("blsbn254").help("Boneh-Lynn-Shacham on BN254"),
        })
    }
}

impl FromStr for KeyType {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.to_lowercase().as_str() {
            "sr25519" => Ok(Self::Sr25519),
            "ed25519" => Ok(Self::Ed25519),
            "ecdsa" => Ok(Self::Ecdsa),
            "bls381" => Ok(Self::Bls381),
            "blsbn254" => Ok(Self::BlsBn254),
            _ => Err(format!("Unknown key type: {}", s)),
        }
    }
}

pub fn generate_key(
    key_type: KeyType,
    output: Option<PathBuf>,
    seed: Option<&[u8]>,
    show_secret: bool,
) -> color_eyre::Result<()> {
    let keystore: GenericKeyStore<RawRwLock> = match output {
        None => GenericKeyStore::Mem(InMemoryKeystore::new()),
        Some(file_path) => {
            // Filesystem Keystore
            GenericKeyStore::Fs(
                FilesystemKeystore::open(file_path).map_err(|e| eyre!(e.to_string()))?,
            )
        }
    };

    let (public, secret) = match key_type {
        KeyType::Sr25519 => {
            let public_key = keystore
                .sr25519_generate_new(seed)
                .map_err(|e| eyre!(e.to_string()))?;
            let secret = keystore
                .expose_sr25519_secret(&public_key)
                .map_err(|e| eyre!(e.to_string()))?
                .ok_or(eyre!("Failed to expose secret"))?;
            (
                hex::encode(public_key.to_bytes()),
                hex::encode(secret.to_bytes()),
            )
        }
        KeyType::Ed25519 => {
            let public_key = keystore
                .ed25519_generate_new(seed)
                .map_err(|e| eyre!(e.to_string()))?;
            let secret = keystore
                .expose_ed25519_secret(&public_key)
                .map_err(|e| eyre!(e.to_string()))?
                .ok_or(eyre!("Failed to expose secret"))?;
            (hex::encode(public_key), hex::encode(secret))
        }
        KeyType::Ecdsa => {
            let public_key = keystore
                .ecdsa_generate_new(seed)
                .map_err(|e| eyre!(e.to_string()))?;
            let secret = keystore
                .expose_ecdsa_secret(&public_key)
                .map_err(|e| eyre!(e.to_string()))?
                .ok_or(eyre!("Failed to expose secret"))?;
            (
                hex::encode(public_key.to_sec1_bytes()),
                hex::encode(secret.to_bytes()),
            )
        }
        KeyType::Bls381 => {
            let public_key = keystore
                .bls381_generate_new(seed)
                .map_err(|e| eyre!(e.to_string()))?;
            let secret = keystore
                .expose_bls381_secret(&public_key)
                .map_err(|e| eyre!(e.to_string()))?
                .ok_or(eyre!("Failed to expose secret"))?;
            (
                hex::encode(public_key.0.to_string()),
                hex::encode(secret.to_bytes()),
            )
        }
        KeyType::BlsBn254 => {
            let public_key = keystore
                .bls_bn254_generate_new(seed)
                .map_err(|e| eyre!(e.to_string()))?;
            let secret = keystore
                .expose_bls_bn254_secret(&public_key)
                .map_err(|e| eyre!(e.to_string()))?
                .ok_or(eyre!("Failed to expose secret"))?;
            (public_key.g1().to_string(), secret.0.to_string())
        }
    };

    eprintln!("Generated {:?} key:", key_type);
    eprintln!("Public key: {}", public);
    if show_secret || keystore.is_mem() {
        eprintln!("Private key: {}", secret);
    }

    Ok(())
}