[clap-v3-utils] Add `EncodableKeypair` trait and make `confirm_keypair_pubkey` generic (#31642)
* add `EncodableKeypair` trait * implement `EncodableKeypair` for `Keypair` * implement `EncodableKeypair` for `ElGamalKeypair * make confirm pubkey functions generic * fix a typo * Update sdk/src/signer/keypair.rs Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com> * Update clap-v3-utils/src/keypair.rs Co-authored-by: Tyera <teulberg@gmail.com> * fix a typo --------- Co-authored-by: Trent Nelson <trent.a.b.nelson@gmail.com> Co-authored-by: Tyera <teulberg@gmail.com>
This commit is contained in:
parent
ad67fd5be5
commit
e14384d8ff
|
@ -30,7 +30,7 @@ use {
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
signature::{
|
signature::{
|
||||||
generate_seed_from_seed_phrase_and_passphrase, read_keypair, read_keypair_file,
|
generate_seed_from_seed_phrase_and_passphrase, read_keypair, read_keypair_file,
|
||||||
EncodableKey, Keypair, NullSigner, Presigner, Signature, Signer,
|
EncodableKey, EncodableKeypair, Keypair, NullSigner, Presigner, Signature, Signer,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
solana_zk_token_sdk::encryption::{auth_encryption::AeKey, elgamal::ElGamalKeypair},
|
solana_zk_token_sdk::encryption::{auth_encryption::AeKey, elgamal::ElGamalKeypair},
|
||||||
|
@ -1004,23 +1004,11 @@ pub fn keypair_from_path(
|
||||||
) -> Result<Keypair, Box<dyn error::Error>> {
|
) -> Result<Keypair, Box<dyn error::Error>> {
|
||||||
let keypair = encodable_key_from_path(matches, path, keypair_name)?;
|
let keypair = encodable_key_from_path(matches, path, keypair_name)?;
|
||||||
if confirm_pubkey {
|
if confirm_pubkey {
|
||||||
confirm_keypair_pubkey(&keypair);
|
confirm_encodable_keypair_pubkey(&keypair, "pubkey");
|
||||||
}
|
}
|
||||||
Ok(keypair)
|
Ok(keypair)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_keypair_pubkey(keypair: &Keypair) {
|
|
||||||
let pubkey = keypair.pubkey();
|
|
||||||
print!("Recovered pubkey `{pubkey:?}`. Continue? (y/n): ");
|
|
||||||
let _ignored = stdout().flush();
|
|
||||||
let mut input = String::new();
|
|
||||||
stdin().read_line(&mut input).expect("Unexpected input");
|
|
||||||
if input.to_lowercase().trim() != "y" {
|
|
||||||
println!("Exiting");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads an [ElGamalKeypair] from one of several possible sources.
|
/// Loads an [ElGamalKeypair] from one of several possible sources.
|
||||||
///
|
///
|
||||||
/// If `confirm_pubkey` is `true` then after deriving the keypair, the user will
|
/// If `confirm_pubkey` is `true` then after deriving the keypair, the user will
|
||||||
|
@ -1063,14 +1051,14 @@ pub fn elgamal_keypair_from_path(
|
||||||
) -> Result<ElGamalKeypair, Box<dyn error::Error>> {
|
) -> Result<ElGamalKeypair, Box<dyn error::Error>> {
|
||||||
let elgamal_keypair = encodable_key_from_path(matches, path, elgamal_keypair_name)?;
|
let elgamal_keypair = encodable_key_from_path(matches, path, elgamal_keypair_name)?;
|
||||||
if confirm_pubkey {
|
if confirm_pubkey {
|
||||||
confirm_elgamal_keypair_pubkey(&elgamal_keypair);
|
confirm_encodable_keypair_pubkey(&elgamal_keypair, "ElGamal pubkey");
|
||||||
}
|
}
|
||||||
Ok(elgamal_keypair)
|
Ok(elgamal_keypair)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_elgamal_keypair_pubkey(keypair: &ElGamalKeypair) {
|
fn confirm_encodable_keypair_pubkey<K: EncodableKeypair>(keypair: &K, pubkey_label: &str) {
|
||||||
let elgamal_pubkey = keypair.public;
|
let pubkey = keypair.encodable_pubkey().to_string();
|
||||||
print!("Recovered ElGamal pubkey `{elgamal_pubkey:?}`. Continue? (y/n): ");
|
println!("Recovered {pubkey_label} `{pubkey:?}`. Continue? (y/n): ");
|
||||||
let _ignored = stdout().flush();
|
let _ignored = stdout().flush();
|
||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
stdin().read_line(&mut input).expect("Unexpected input");
|
stdin().read_line(&mut input).expect("Unexpected input");
|
||||||
|
@ -1175,7 +1163,7 @@ pub fn keypair_from_seed_phrase(
|
||||||
let keypair: Keypair =
|
let keypair: Keypair =
|
||||||
encodable_key_from_seed_phrase(keypair_name, skip_validation, derivation_path, legacy)?;
|
encodable_key_from_seed_phrase(keypair_name, skip_validation, derivation_path, legacy)?;
|
||||||
if confirm_pubkey {
|
if confirm_pubkey {
|
||||||
confirm_keypair_pubkey(&keypair);
|
confirm_encodable_keypair_pubkey(&keypair, "pubkey");
|
||||||
}
|
}
|
||||||
Ok(keypair)
|
Ok(keypair)
|
||||||
}
|
}
|
||||||
|
@ -1198,7 +1186,7 @@ pub fn elgamal_keypair_from_seed_phrase(
|
||||||
legacy,
|
legacy,
|
||||||
)?;
|
)?;
|
||||||
if confirm_pubkey {
|
if confirm_pubkey {
|
||||||
confirm_elgamal_keypair_pubkey(&elgamal_keypair);
|
confirm_encodable_keypair_pubkey(&elgamal_keypair, "ElGamal pubkey");
|
||||||
}
|
}
|
||||||
Ok(elgamal_keypair)
|
Ok(elgamal_keypair)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use {
|
||||||
derivation_path::DerivationPath,
|
derivation_path::DerivationPath,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
signature::Signature,
|
signature::Signature,
|
||||||
signer::{EncodableKey, Signer, SignerError},
|
signer::{EncodableKey, EncodableKeypair, Signer, SignerError},
|
||||||
},
|
},
|
||||||
ed25519_dalek::Signer as DalekSigner,
|
ed25519_dalek::Signer as DalekSigner,
|
||||||
ed25519_dalek_bip32::Error as Bip32Error,
|
ed25519_dalek_bip32::Error as Bip32Error,
|
||||||
|
@ -140,6 +140,16 @@ impl EncodableKey for Keypair {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EncodableKeypair for Keypair {
|
||||||
|
type Pubkey = Pubkey;
|
||||||
|
|
||||||
|
/// Returns the associated pubkey. Use this function specifically for settings that involve
|
||||||
|
/// reading or writing pubkeys. For other settings, use `Signer::pubkey()` instead.
|
||||||
|
fn encodable_pubkey(&self) -> Self::Pubkey {
|
||||||
|
self.pubkey()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads a JSON-encoded `Keypair` from a `Reader` implementor
|
/// Reads a JSON-encoded `Keypair` from a `Reader` implementor
|
||||||
pub fn read_keypair<R: Read>(reader: &mut R) -> Result<Keypair, Box<dyn error::Error>> {
|
pub fn read_keypair<R: Read>(reader: &mut R) -> Result<Keypair, Box<dyn error::Error>> {
|
||||||
let bytes: Vec<u8> = serde_json::from_reader(reader)?;
|
let bytes: Vec<u8> = serde_json::from_reader(reader)?;
|
||||||
|
|
|
@ -155,6 +155,15 @@ pub trait EncodableKey: Sized {
|
||||||
) -> Result<Self, Box<dyn error::Error>>;
|
) -> Result<Self, Box<dyn error::Error>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The `EncodableKeypair` trait extends `EncodableKey` for asymmetric keypairs, i.e. have
|
||||||
|
/// associated public keys.
|
||||||
|
pub trait EncodableKeypair: EncodableKey {
|
||||||
|
type Pubkey: ToString;
|
||||||
|
|
||||||
|
/// Returns an encodable representation of the associated public key.
|
||||||
|
fn encodable_pubkey(&self) -> Self::Pubkey;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use {super::*, crate::signer::keypair::Keypair};
|
use {super::*, crate::signer::keypair::Keypair};
|
||||||
|
|
|
@ -33,8 +33,8 @@ use {
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
signature::Signature,
|
signature::Signature,
|
||||||
signer::{
|
signer::{
|
||||||
keypair::generate_seed_from_seed_phrase_and_passphrase, EncodableKey, Signer,
|
keypair::generate_seed_from_seed_phrase_and_passphrase, EncodableKey, EncodableKeypair,
|
||||||
SignerError,
|
Signer, SignerError,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
std::convert::TryInto,
|
std::convert::TryInto,
|
||||||
|
@ -273,6 +273,14 @@ impl EncodableKey for ElGamalKeypair {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EncodableKeypair for ElGamalKeypair {
|
||||||
|
type Pubkey = ElGamalPubkey;
|
||||||
|
|
||||||
|
fn encodable_pubkey(&self) -> Self::Pubkey {
|
||||||
|
self.public
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Public key for the ElGamal encryption scheme.
|
/// Public key for the ElGamal encryption scheme.
|
||||||
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize, Zeroize)]
|
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize, Zeroize)]
|
||||||
pub struct ElGamalPubkey(RistrettoPoint);
|
pub struct ElGamalPubkey(RistrettoPoint);
|
||||||
|
|
Loading…
Reference in New Issue