[clap-v3-utils, sdk, zk-token-sdk] Split `EncodableKey` into `EncodableKey` + `SeedDerivable` (#31668)
* add `SeedDerivable` trait * implement `SeedDerivable` for `Keypair` * implement `SeedDerivable` for `ElGamalKeypair` * update clap-v3-utils to use `EncodableKey + SeedDerivable` * implement `SeedDerivable` trait for `AeKey` * implement `EncodableKey` and `SeedDerivable` for `ElGamalSecretKey` * implement `SeedDerivable` trait for `ElGamalPubkey`
This commit is contained in:
parent
2cdb43ff1b
commit
6de581ac08
|
@ -30,7 +30,8 @@ use {
|
|||
pubkey::Pubkey,
|
||||
signature::{
|
||||
generate_seed_from_seed_phrase_and_passphrase, read_keypair, read_keypair_file,
|
||||
EncodableKey, EncodableKeypair, Keypair, NullSigner, Presigner, Signature, Signer,
|
||||
EncodableKey, EncodableKeypair, Keypair, NullSigner, Presigner, SeedDerivable,
|
||||
Signature, Signer,
|
||||
},
|
||||
},
|
||||
solana_zk_token_sdk::encryption::{auth_encryption::AeKey, elgamal::ElGamalKeypair},
|
||||
|
@ -1106,7 +1107,7 @@ pub fn ae_key_from_path(
|
|||
encodable_key_from_path(matches, path, key_name)
|
||||
}
|
||||
|
||||
fn encodable_key_from_path<K: EncodableKey>(
|
||||
fn encodable_key_from_path<K: EncodableKey + SeedDerivable>(
|
||||
matches: &ArgMatches,
|
||||
path: &str,
|
||||
keypair_name: &str,
|
||||
|
@ -1202,7 +1203,7 @@ pub fn ae_key_from_seed_phrase(
|
|||
encodable_key_from_seed_phrase(keypair_name, skip_validation, derivation_path, legacy)
|
||||
}
|
||||
|
||||
fn encodable_key_from_seed_phrase<K: EncodableKey>(
|
||||
fn encodable_key_from_seed_phrase<K: EncodableKey + SeedDerivable>(
|
||||
key_name: &str,
|
||||
skip_validation: bool,
|
||||
derivation_path: Option<DerivationPath>,
|
||||
|
|
|
@ -5,7 +5,7 @@ use {
|
|||
derivation_path::DerivationPath,
|
||||
pubkey::Pubkey,
|
||||
signature::Signature,
|
||||
signer::{EncodableKey, EncodableKeypair, Signer, SignerError},
|
||||
signer::{EncodableKey, EncodableKeypair, SeedDerivable, Signer, SignerError},
|
||||
},
|
||||
ed25519_dalek::Signer as DalekSigner,
|
||||
ed25519_dalek_bip32::Error as Bip32Error,
|
||||
|
@ -120,7 +120,9 @@ impl EncodableKey for Keypair {
|
|||
fn write<W: Write>(&self, writer: &mut W) -> Result<String, Box<dyn error::Error>> {
|
||||
write_keypair(self, writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl SeedDerivable for Keypair {
|
||||
fn from_seed(seed: &[u8]) -> Result<Self, Box<dyn error::Error>> {
|
||||
keypair_from_seed(seed)
|
||||
}
|
||||
|
|
|
@ -144,6 +144,11 @@ pub trait EncodableKey: Sized {
|
|||
|
||||
self.write(&mut f)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `SeedDerivable` trait defines the interface by which cryptographic keys/keypairs are
|
||||
/// derived from byte seeds, derivation paths, and passphrases.
|
||||
pub trait SeedDerivable: Sized {
|
||||
fn from_seed(seed: &[u8]) -> Result<Self, Box<dyn error::Error>>;
|
||||
fn from_seed_and_derivation_path(
|
||||
seed: &[u8],
|
||||
|
|
|
@ -21,8 +21,8 @@ use {
|
|||
pubkey::Pubkey,
|
||||
signature::Signature,
|
||||
signer::{
|
||||
keypair::generate_seed_from_seed_phrase_and_passphrase, EncodableKey, Signer,
|
||||
SignerError,
|
||||
keypair::generate_seed_from_seed_phrase_and_passphrase, EncodableKey, SeedDerivable,
|
||||
Signer, SignerError,
|
||||
},
|
||||
},
|
||||
std::{
|
||||
|
@ -126,7 +126,9 @@ impl EncodableKey for AeKey {
|
|||
writer.write_all(&json.clone().into_bytes())?;
|
||||
Ok(json)
|
||||
}
|
||||
}
|
||||
|
||||
impl SeedDerivable for AeKey {
|
||||
fn from_seed(seed: &[u8]) -> Result<Self, Box<dyn error::Error>> {
|
||||
const MINIMUM_SEED_LEN: usize = 16;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ use {
|
|||
signature::Signature,
|
||||
signer::{
|
||||
keypair::generate_seed_from_seed_phrase_and_passphrase, EncodableKey, EncodableKeypair,
|
||||
Signer, SignerError,
|
||||
SeedDerivable, Signer, SignerError,
|
||||
},
|
||||
},
|
||||
std::convert::TryInto,
|
||||
|
@ -248,7 +248,9 @@ impl EncodableKey for ElGamalKeypair {
|
|||
fn write<W: Write>(&self, writer: &mut W) -> Result<String, Box<dyn error::Error>> {
|
||||
self.write_json(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl SeedDerivable for ElGamalKeypair {
|
||||
fn from_seed(seed: &[u8]) -> Result<Self, Box<dyn error::Error>> {
|
||||
let secret = ElGamalSecretKey::from_seed(seed)?;
|
||||
let public = ElGamalPubkey::new(&secret);
|
||||
|
@ -336,6 +338,22 @@ impl ElGamalPubkey {
|
|||
}
|
||||
}
|
||||
|
||||
impl EncodableKey for ElGamalPubkey {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Box<dyn error::Error>> {
|
||||
let bytes: Vec<u8> = serde_json::from_reader(reader)?;
|
||||
Self::from_bytes(&bytes).ok_or_else(|| {
|
||||
std::io::Error::new(std::io::ErrorKind::Other, "Invalid ElGamalPubkey").into()
|
||||
})
|
||||
}
|
||||
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<String, Box<dyn error::Error>> {
|
||||
let bytes = self.to_bytes();
|
||||
let json = serde_json::to_string(&bytes.to_vec())?;
|
||||
writer.write_all(&json.clone().into_bytes())?;
|
||||
Ok(json)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ElGamalPubkey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", BASE64_STANDARD.encode(self.to_bytes()))
|
||||
|
@ -425,6 +443,45 @@ impl ElGamalSecretKey {
|
|||
}
|
||||
}
|
||||
|
||||
impl EncodableKey for ElGamalSecretKey {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Box<dyn error::Error>> {
|
||||
let bytes: Vec<u8> = serde_json::from_reader(reader)?;
|
||||
Self::from_bytes(&bytes).ok_or_else(|| {
|
||||
std::io::Error::new(std::io::ErrorKind::Other, "Invalid ElGamalSecretKey").into()
|
||||
})
|
||||
}
|
||||
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<String, Box<dyn error::Error>> {
|
||||
let bytes = self.to_bytes();
|
||||
let json = serde_json::to_string(&bytes.to_vec())?;
|
||||
writer.write_all(&json.clone().into_bytes())?;
|
||||
Ok(json)
|
||||
}
|
||||
}
|
||||
|
||||
impl SeedDerivable for ElGamalSecretKey {
|
||||
fn from_seed(seed: &[u8]) -> Result<Self, Box<dyn error::Error>> {
|
||||
Self::from_seed(seed)
|
||||
}
|
||||
|
||||
fn from_seed_and_derivation_path(
|
||||
_seed: &[u8],
|
||||
_derivation_path: Option<DerivationPath>,
|
||||
) -> Result<Self, Box<dyn error::Error>> {
|
||||
Err(ElGamalError::DerivationMethodNotSupported.into())
|
||||
}
|
||||
|
||||
fn from_seed_phrase_and_passphrase(
|
||||
seed_phrase: &str,
|
||||
passphrase: &str,
|
||||
) -> Result<Self, Box<dyn error::Error>> {
|
||||
Self::from_seed(&generate_seed_from_seed_phrase_and_passphrase(
|
||||
seed_phrase,
|
||||
passphrase,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Scalar> for ElGamalSecretKey {
|
||||
fn from(scalar: Scalar) -> ElGamalSecretKey {
|
||||
ElGamalSecretKey(scalar)
|
||||
|
|
Loading…
Reference in New Issue