Browse Source

Remove zk keygen crate (#7634)

samkim-crypto 3 tháng trước cách đây
mục cha
commit
8508753bc9
6 tập tin đã thay đổi với 7 bổ sung531 xóa
  1. 4 8
      .mergify.yml
  2. 0 19
      Cargo.lock
  3. 0 2
      Cargo.toml
  4. 0 40
      zk-keygen/Cargo.toml
  5. 3 0
      zk-keygen/README.md
  6. 0 462
      zk-keygen/src/main.rs

+ 4 - 8
.mergify.yml

@@ -217,20 +217,16 @@ pull_request_rules:
           If this PR represents a change to a native program implementation (not
           tests), please include a reviewer from the Firedancer team. And please
           keep refactors to a minimum.
-  - name: Notify about future move of zk-keygen, zk-sdk, and zk-token-sdk
+  - name: Notify about the deprecation of zk-token-sdk
     conditions:
       - or:
-        - files~=^zk-keygen/
-        - files~=^zk-sdk/
         - files~=^zk-token-sdk/
     actions:
       comment:
         message: |
-          For your information, the `zk-keygen` and `zk-sdk` directories are
-          scheduled to be relocated to `solana-program/zk-elgamal-proof` in a
-          separate repository. Additionally, the `zk-token-sdk` directory will
-          be removed. Please take these upcoming changes into account when
-          making modifications.
+          For your information, the `solana-zk-token-sdk` is deprecated, and this
+          directory will be removed in a future version. Please take this in mind
+          when making modifications.
 
 commands_restrictions:
   # The author of copied PRs is the Mergify user.

+ 0 - 19
Cargo.lock

@@ -11898,25 +11898,6 @@ dependencies = [
  "solana-zk-sdk",
 ]
 
-[[package]]
-name = "solana-zk-keygen"
-version = "3.1.0"
-dependencies = [
- "bs58",
- "clap 3.2.23",
- "dirs-next",
- "solana-clap-v3-utils",
- "solana-pubkey",
- "solana-remote-wallet",
- "solana-seed-derivable",
- "solana-signer",
- "solana-version",
- "solana-zk-sdk",
- "tempfile",
- "thiserror 2.0.16",
- "tiny-bip39",
-]
-
 [[package]]
 name = "solana-zk-sdk"
 version = "4.0.0"

+ 0 - 2
Cargo.toml

@@ -138,7 +138,6 @@ members = [
     "watchtower",
     "wen-restart",
     "xdp",
-    "zk-keygen",
     "zk-token-sdk",
 ]
 
@@ -558,7 +557,6 @@ solana-vote-interface = "3.0.0"
 solana-vote-program = { path = "programs/vote", version = "=3.1.0", default-features = false }
 solana-wen-restart = { path = "wen-restart", version = "=3.1.0" }
 solana-zk-elgamal-proof-program = { path = "programs/zk-elgamal-proof", version = "=3.1.0" }
-solana-zk-keygen = { path = "zk-keygen", version = "=3.1.0" }
 solana-zk-sdk = "4.0.0"
 solana-zk-token-proof-program = { path = "programs/zk-token-proof", version = "=3.1.0" }
 solana-zk-token-sdk = { path = "zk-token-sdk", version = "=3.1.0" }

+ 0 - 40
zk-keygen/Cargo.toml

@@ -1,40 +0,0 @@
-[package]
-name = "solana-zk-keygen"
-description = """
-Solana privacy-related key generation utility
-
-The tool currently supports two types of encryption keys that are used in the SPL Token-2022 program:
-  - ElGamal keypair that can be used for public key encryption
-  - AES128 key that can be used for an authenticated symmetric encryption (e.g. AES-GCM-SIV)
-"""
-publish = false
-version = { workspace = true }
-authors = { workspace = true }
-repository = { workspace = true }
-homepage = { workspace = true }
-license = { workspace = true }
-edition = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[[bin]]
-name = "solana-zk-keygen"
-path = "src/main.rs"
-
-[dependencies]
-bs58 = { workspace = true }
-clap = { version = "3.1.5", features = ["cargo", "derive"] }
-dirs-next = { workspace = true }
-solana-clap-v3-utils = { workspace = true, features = ["elgamal"] }
-solana-remote-wallet = { workspace = true, features = ["default"] }
-solana-seed-derivable = "=3.0.0"
-solana-signer = "=3.0.0"
-solana-version = { workspace = true }
-solana-zk-sdk = { workspace = true }
-thiserror = { workspace = true }
-tiny-bip39 = { workspace = true }
-
-[dev-dependencies]
-solana-pubkey = { workspace = true, features = ["rand"] }
-tempfile = { workspace = true }

+ 3 - 0
zk-keygen/README.md

@@ -0,0 +1,3 @@
+# PLEASE READ: This repo no longer contains the Solana ZK-KEYGEN
+
+The solana-zk-keygen is currently developed at <https://github.com/solana-program/zk-elgamal-proof>.

+ 0 - 462
zk-keygen/src/main.rs

@@ -1,462 +0,0 @@
-#![allow(deprecated)]
-use {
-    bip39::{Mnemonic, MnemonicType, Seed},
-    clap::{crate_description, crate_name, Arg, ArgMatches, Command, PossibleValue},
-    solana_clap_v3_utils::{
-        input_parsers::{signer::SignerSourceParserBuilder, STDOUT_OUTFILE_TOKEN},
-        keygen::{
-            check_for_overwrite,
-            mnemonic::{acquire_passphrase_and_message, try_get_language, try_get_word_count},
-            no_outfile_arg, KeyGenerationCommonArgs, NO_OUTFILE_ARG,
-        },
-        keypair::{
-            ae_key_from_path, ae_key_from_seed_phrase, elgamal_keypair_from_path,
-            elgamal_keypair_from_seed_phrase, SKIP_SEED_PHRASE_VALIDATION_ARG,
-        },
-        DisplayError,
-    },
-    solana_seed_derivable::SeedDerivable,
-    solana_signer::EncodableKey,
-    solana_zk_sdk::encryption::{auth_encryption::AeKey, elgamal::ElGamalKeypair},
-    std::{error, str::FromStr},
-    thiserror::Error,
-};
-
-fn output_encodable_key<K: EncodableKey>(
-    key: &K,
-    outfile: &str,
-    source: &str,
-) -> Result<(), Box<dyn error::Error>> {
-    if outfile == STDOUT_OUTFILE_TOKEN {
-        let mut stdout = std::io::stdout();
-        key.write(&mut stdout)?;
-    } else {
-        key.write_to_file(outfile)?;
-        println!("Wrote {source} to {outfile}");
-    }
-    Ok(())
-}
-
-fn app(crate_version: &str) -> Command {
-    Command::new(crate_name!())
-        .about(crate_description!())
-        .version(crate_version)
-        .subcommand_required(true)
-        .arg_required_else_help(true)
-        .subcommand(
-            Command::new("new")
-                .about("Generate a new encryption key/keypair file from a random seed phrase and optional BIP39 passphrase")
-                .disable_version_flag(true)
-                .arg(
-                    Arg::new("type")
-                        .index(1)
-                        .takes_value(true)
-                        .value_parser(clap::value_parser!(KeyType))
-                        .value_name("TYPE")
-                        .required(true)
-                        .help("The type of encryption key")
-                )
-                .arg(
-                    Arg::new("outfile")
-                        .short('o')
-                        .long("outfile")
-                        .value_name("FILEPATH")
-                        .takes_value(true)
-                        .help("Path to generated file"),
-                )
-                .arg(
-                    Arg::new("force")
-                        .long("force")
-                        .help("Overwrite the output file if it exists"),
-                )
-                .arg(
-                    Arg::new("silent")
-                        .long("silent")
-                        .help("Do not display seed phrase. Useful when piping output to other programs that prompt for user input, like gpg"),
-                )
-                .key_generation_common_args()
-                .arg(no_outfile_arg().conflicts_with_all(&["outfile", "silent"]))
-        )
-        .subcommand(
-            Command::new("pubkey")
-                .about("Display the pubkey from a keypair file")
-                .disable_version_flag(true)
-                .arg(
-                    Arg::new("type")
-                        .index(1)
-                        .takes_value(true)
-                        .value_parser([
-                            PossibleValue::new("elgamal")
-                        ])
-                        .value_name("TYPE")
-                        .required(true)
-                        .help("The type of keypair")
-                )
-                .arg(
-                    Arg::new("keypair")
-                        .index(2)
-                        .value_name("KEYPAIR")
-                        .takes_value(true)
-                        .help("Filepath or URL to a keypair"),
-                )
-                .arg(
-                    Arg::new(SKIP_SEED_PHRASE_VALIDATION_ARG.name)
-                        .long(SKIP_SEED_PHRASE_VALIDATION_ARG.long)
-                        .help(SKIP_SEED_PHRASE_VALIDATION_ARG.help),
-                )
-        )
-        .subcommand(
-            Command::new("recover")
-                .about("Recover keypair from seed phrase and optional BIP39 passphrase")
-                .disable_version_flag(true)
-                .arg(
-                    Arg::new("type")
-                        .index(1)
-                        .takes_value(true)
-                        .value_parser(clap::value_parser!(KeyType))
-                        .value_name("TYPE")
-                        .required(true)
-                        .help("The type of keypair")
-                )
-                .arg(
-                    Arg::new("prompt_signer")
-                        .index(2)
-                        .value_name("KEYPAIR")
-                        .takes_value(true)
-                        .value_parser(SignerSourceParserBuilder::default().allow_prompt().allow_legacy().build())
-                        .help("`prompt:` URI scheme or `ASK` keyword"),
-                )
-                .arg(
-                    Arg::new("outfile")
-                        .short('o')
-                        .long("outfile")
-                        .value_name("FILEPATH")
-                        .takes_value(true)
-                        .help("Path to generated file"),
-                )
-                .arg(
-                    Arg::new("force")
-                        .long("force")
-                        .help("Overwrite the output file if it exists"),
-                )
-                .arg(
-                    Arg::new(SKIP_SEED_PHRASE_VALIDATION_ARG.name)
-                        .long(SKIP_SEED_PHRASE_VALIDATION_ARG.long)
-                        .help(SKIP_SEED_PHRASE_VALIDATION_ARG.help),
-                ),
-        )
-}
-
-fn main() -> Result<(), Box<dyn error::Error>> {
-    let matches = app(solana_version::version!())
-        .try_get_matches()
-        .unwrap_or_else(|e| e.exit());
-    do_main(&matches).map_err(|err| DisplayError::new_as_boxed(err).into())
-}
-
-fn do_main(matches: &ArgMatches) -> Result<(), Box<dyn error::Error>> {
-    let subcommand = matches.subcommand().unwrap();
-    match subcommand {
-        ("new", matches) => {
-            let key_type = matches.try_get_one::<KeyType>("type")?.unwrap();
-
-            let mut path = dirs_next::home_dir().expect("home directory");
-            let outfile = if matches.try_contains_id("outfile")? {
-                matches.get_one::<String>("outfile").map(|s| s.as_str())
-            } else if matches.try_contains_id(NO_OUTFILE_ARG.name)? {
-                None
-            } else {
-                path.extend([".config", "solana", key_type.default_file_name()]);
-                Some(path.to_str().unwrap())
-            };
-
-            match outfile {
-                Some(STDOUT_OUTFILE_TOKEN) => (),
-                Some(outfile) => check_for_overwrite(outfile, matches)?,
-                None => (),
-            }
-
-            let word_count = try_get_word_count(matches)?.unwrap();
-            let mnemonic_type = MnemonicType::for_word_count(word_count)?;
-            let language = try_get_language(matches)?.unwrap();
-
-            let mnemonic = Mnemonic::new(mnemonic_type, language);
-            let (passphrase, passphrase_message) = acquire_passphrase_and_message(matches).unwrap();
-            let seed = Seed::new(&mnemonic, &passphrase);
-
-            let silent = matches.try_contains_id("silent")?;
-
-            match key_type {
-                KeyType::ElGamal => {
-                    if !silent {
-                        eprintln!("Generating a new ElGamal keypair");
-                    }
-
-                    let elgamal_keypair = ElGamalKeypair::from_seed(seed.as_bytes())?;
-                    if let Some(outfile) = outfile {
-                        output_encodable_key(&elgamal_keypair, outfile, "new ElGamal keypair")
-                            .map_err(|err| format!("Unable to write {outfile}: {err}"))?;
-                    }
-
-                    if !silent {
-                        let phrase: &str = mnemonic.phrase();
-                        let divider = String::from_utf8(vec![b'='; phrase.len()]).unwrap();
-                        println!(
-                            "{}\npubkey: {}\n{}\nSave this seed phrase{} to recover your new ElGamal keypair:\n{}\n{}",
-                            &divider, elgamal_keypair.pubkey(), &divider, passphrase_message, phrase, &divider
-                        );
-                    }
-                }
-                KeyType::Aes128 => {
-                    if !silent {
-                        eprintln!("Generating a new AES128 encryption key");
-                    }
-
-                    let aes_key = AeKey::from_seed(seed.as_bytes())?;
-                    if let Some(outfile) = outfile {
-                        output_encodable_key(&aes_key, outfile, "new AES128 key")
-                            .map_err(|err| format!("Unable to write {outfile}: {err}"))?;
-                    }
-
-                    if !silent {
-                        let phrase: &str = mnemonic.phrase();
-                        let divider = String::from_utf8(vec![b'='; phrase.len()]).unwrap();
-                        println!(
-                            "{}\nSave this seed phrase{} to recover your new AES128 key:\n{}\n{}",
-                            &divider, passphrase_message, phrase, &divider
-                        );
-                    }
-                }
-            }
-        }
-        ("pubkey", matches) => {
-            let key_type = matches.try_get_one::<String>("type")?.unwrap();
-            let key_type = if key_type == "elgamal" {
-                KeyType::ElGamal
-            } else {
-                return Err("unsupported key type".into());
-            };
-
-            let mut path = dirs_next::home_dir().expect("home directory");
-            let path = if matches.try_contains_id("keypair")? {
-                matches.get_one::<String>("keypair").unwrap()
-            } else {
-                path.extend([".config", "solana", key_type.default_file_name()]);
-                path.to_str().unwrap()
-            };
-
-            // wrap the logic inside a match statement in case more keys are supported in the
-            // future
-            match key_type {
-                KeyType::ElGamal => {
-                    let elgamal_keypair =
-                        elgamal_keypair_from_path(matches, path, "pubkey recovery", false)?;
-                    let elgamal_pubkey = elgamal_keypair.pubkey();
-                    println!("{elgamal_pubkey}");
-                }
-                _ => unreachable!(),
-            }
-        }
-        ("recover", matches) => {
-            let key_type = matches.try_get_one::<KeyType>("type")?.unwrap();
-
-            let mut path = dirs_next::home_dir().expect("home directory");
-            let outfile = if matches.try_contains_id("outfile")? {
-                matches.get_one::<String>("outfile").unwrap()
-            } else {
-                path.extend([".config", "solana", key_type.default_file_name()]);
-                path.to_str().unwrap()
-            };
-
-            if outfile != STDOUT_OUTFILE_TOKEN {
-                check_for_overwrite(outfile, matches)?;
-            }
-
-            let name = "recover";
-            match key_type {
-                KeyType::ElGamal => {
-                    let keypair = if let Some(path) =
-                        matches.try_get_one::<String>("prompt_signer")?
-                    {
-                        elgamal_keypair_from_path(matches, path, name, true)?
-                    } else {
-                        let skip_validation =
-                            matches.try_contains_id(SKIP_SEED_PHRASE_VALIDATION_ARG.name)?;
-                        elgamal_keypair_from_seed_phrase(name, skip_validation, true, None, true)?
-                    };
-                    output_encodable_key(&keypair, outfile, "recovered ElGamal keypair")?;
-                }
-                KeyType::Aes128 => {
-                    let key = if let Some(path) = matches.try_get_one::<String>("prompt_signer")? {
-                        ae_key_from_path(matches, path, name)?
-                    } else {
-                        let skip_validation =
-                            matches.try_contains_id(SKIP_SEED_PHRASE_VALIDATION_ARG.name)?;
-                        ae_key_from_seed_phrase(name, skip_validation, None, true)?
-                    };
-                    output_encodable_key(&key, outfile, "recovered AES128 key")?;
-                }
-            }
-        }
-        _ => unreachable!(),
-    }
-
-    Ok(())
-}
-
-#[derive(Clone)]
-enum KeyType {
-    ElGamal,
-    Aes128,
-}
-
-impl KeyType {
-    fn default_file_name(&self) -> &str {
-        match self {
-            KeyType::ElGamal => "elgamal.json",
-            KeyType::Aes128 => "aes128.json",
-        }
-    }
-}
-
-#[derive(Debug, Error)]
-#[error("unsupported key type: \"{0}\"")]
-pub struct KeyTypeError(pub String);
-
-impl FromStr for KeyType {
-    type Err = KeyTypeError;
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        let s = s.to_ascii_lowercase();
-        match s.as_str() {
-            "elgamal" => Ok(Self::ElGamal),
-            "aes128" => Ok(Self::Aes128),
-            _ => Err(KeyTypeError(s)),
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use {
-        super::*,
-        solana_pubkey::Pubkey,
-        tempfile::{tempdir, TempDir},
-    };
-
-    fn process_test_command(args: &[&str]) -> Result<(), Box<dyn error::Error>> {
-        let solana_version = solana_version::version!();
-        let app_matches = app(solana_version).get_matches_from(args);
-        do_main(&app_matches)
-    }
-
-    fn tmp_outfile_path(out_dir: &TempDir, name: &str) -> String {
-        let path = out_dir.path().join(name);
-        path.into_os_string().into_string().unwrap()
-    }
-
-    #[test]
-    fn test_arguments() {
-        let solana_version = solana_version::version!();
-
-        // run clap internal assert statements
-        app(solana_version).debug_assert();
-    }
-
-    #[test]
-    fn test_new_elgamal() {
-        let outfile_dir = tempdir().unwrap();
-        // use `Pubkey::new_unique()` to generate names for temporary key files
-        let outfile_path = tmp_outfile_path(&outfile_dir, &Pubkey::new_unique().to_string());
-
-        // general success case
-        process_test_command(&[
-            "solana-zk-keygen",
-            "new",
-            "elgamal",
-            "--outfile",
-            &outfile_path,
-            "--no-bip39-passphrase",
-        ])
-        .unwrap();
-
-        // refuse to overwrite file
-        let result = process_test_command(&[
-            "solana-zk-keygen",
-            "new",
-            "elgamal",
-            "--outfile",
-            &outfile_path,
-            "--no-bip39-passphrase",
-        ])
-        .unwrap_err()
-        .to_string();
-
-        let expected = format!("Refusing to overwrite {outfile_path} without --force flag");
-        assert_eq!(result, expected);
-
-        // no outfile
-        process_test_command(&[
-            "solana-keygen",
-            "new",
-            "elgamal",
-            "--no-bip39-passphrase",
-            "--no-outfile",
-        ])
-        .unwrap();
-    }
-
-    #[test]
-    fn test_new_aes128() {
-        let outfile_dir = tempdir().unwrap();
-        // use `Pubkey::new_unique()` to generate names for temporary key files
-        let outfile_path = tmp_outfile_path(&outfile_dir, &Pubkey::new_unique().to_string());
-
-        // general success case
-        process_test_command(&[
-            "solana-zk-keygen",
-            "new",
-            "aes128",
-            "--outfile",
-            &outfile_path,
-            "--no-bip39-passphrase",
-        ])
-        .unwrap();
-
-        // refuse to overwrite file
-        let result = process_test_command(&[
-            "solana-zk-keygen",
-            "new",
-            "aes128",
-            "--outfile",
-            &outfile_path,
-            "--no-bip39-passphrase",
-        ])
-        .unwrap_err()
-        .to_string();
-
-        let expected = format!("Refusing to overwrite {outfile_path} without --force flag");
-        assert_eq!(result, expected);
-
-        // no outfile
-        process_test_command(&[
-            "solana-keygen",
-            "new",
-            "aes128",
-            "--no-bip39-passphrase",
-            "--no-outfile",
-        ])
-        .unwrap();
-    }
-
-    #[test]
-    fn test_pubkey() {
-        let keypair_out_dir = tempdir().unwrap();
-        // use `Pubkey::new_unique()` to generate names for temporary key files
-        let keypair_path = tmp_outfile_path(&keypair_out_dir, &Pubkey::new_unique().to_string());
-
-        let keypair = ElGamalKeypair::new_rand();
-        keypair.write_to_file(&keypair_path).unwrap();
-
-        process_test_command(&["solana-keygen", "pubkey", "elgamal", &keypair_path]).unwrap();
-    }
-}