Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/auto-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ permissions:
jobs:
auto-release:
# Only run if PR was merged to release branch (not just closed)
#for test create a pr and merge it to release branch
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest

Expand Down
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,30 @@ cargo build --release

## Usage

Generate cryptographic key pairs for hash-based signatures:
Generate validator key pairs for hash-based signatures:

```bash
cargo run --release --bin hashsig -- generate \
--num-keys 5 \
--log-num-active-epochs 12 \
--num-validators 5 \
--log-num-active-epochs 18 \
--output-dir ./generated_keys
```

**Parameters:**
- `--num-keys`: Number of key pairs to generate
- `--num-validators`: Number of validator key pairs to generate
- `--log-num-active-epochs`: Log2 of the number of active epochs (e.g., 18 for 2^18 = 262,144 active epochs)
- `--output-dir`: Directory where keys will be saved
- `--create-manifest`: Create a manifest file (optional, defaults to `true`)

**Output:**
The tool creates a directory with key pairs in JSON format:
```
generated_keys/
├── key_0_pk.json # Public key
├── key_0_sk.json # Secret key
├── key_1_pk.json
├── key_1_sk.json
├── validator-keys-manifest.yaml # Manifest file (if --create-manifest is true)
├── validator_0_pk.json # Public key for validator 0
├── validator_0_sk.json # Secret key for validator 0
├── validator_1_pk.json # Public key for validator 1
├── validator_1_sk.json # Secret key for validator 1
└── ...
```

Expand Down
50 changes: 11 additions & 39 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,8 @@ struct Args {

#[derive(Subcommand, Debug)]
enum Commands {
/// Generate key pairs (standard mode)
/// Generate validator key pairs for hash-based signatures
Generate {
/// Number of keys to generate
#[arg(long)]
num_keys: usize,

/// Log2 of the number of active epochs (e.g., 18 for 2^18 active epochs)
#[arg(long)]
log_num_active_epochs: usize,

/// Directory to save the keys to
#[arg(long)]
output_dir: PathBuf,
},
/// Generate keys for genesis validator integration
GenerateForGenesis {
/// Number of validator keys to generate
#[arg(long)]
num_validators: usize,
Expand All @@ -46,7 +32,7 @@ enum Commands {
#[arg(long)]
output_dir: PathBuf,

/// Create a manifest file for genesis integration
/// Create a manifest file for validator keys
#[arg(long, default_value = "true")]
create_manifest: bool,
},
Expand All @@ -57,19 +43,12 @@ fn main() -> std::io::Result<()> {

match args.command {
Commands::Generate {
num_keys,
log_num_active_epochs,
output_dir,
} => {
generate_keys(num_keys, log_num_active_epochs, output_dir, false)?;
}
Commands::GenerateForGenesis {
num_validators,
log_num_active_epochs,
output_dir,
create_manifest,
} => {
generate_keys(num_validators, log_num_active_epochs, output_dir.clone(), create_manifest)?;
generate_keys(num_validators, log_num_active_epochs, output_dir.clone())?;

if create_manifest {
create_validator_manifest(&output_dir, num_validators, log_num_active_epochs)?;
Expand All @@ -81,37 +60,30 @@ fn main() -> std::io::Result<()> {
}

fn generate_keys(
num_keys: usize,
num_validators: usize,
log_num_active_epochs: usize,
output_dir: PathBuf,
for_genesis: bool,
) -> std::io::Result<()> {
// Create the output directory if it doesn't exist
fs::create_dir_all(&output_dir)?;

let activation_duration = 1 << log_num_active_epochs;

println!(
"Generating {} keys with 2^{} active epochs ({} total) in directory: {}\n",
num_keys,
"Generating {} validator keys with 2^{} active epochs ({} total) in directory: {}\n",
num_validators,
log_num_active_epochs,
activation_duration,
output_dir.display()
);

if for_genesis {
println!("🔐 Genesis Mode: Keys will be formatted for validator integration");
println!("⚠️ Note: Secret keys are large files (~several MB each)\n");
}
println!("🔐 Keys will be formatted for validator integration");
println!("⚠️ Note: Secret keys are large files (~several MB each)\n");

let mut rng = rand::rng();

for i in 0..num_keys {
let key_prefix = if for_genesis {
format!("validator_{}", i)
} else {
format!("key_{}", i)
};
for i in 0..num_validators {
let key_prefix = format!("validator_{}", i);

println!("Generating {}...", key_prefix);

Expand All @@ -132,7 +104,7 @@ fn generate_keys(
println!(" ✅ {}_sk.json", key_prefix);
}

println!("\n✅ Successfully generated and saved {} key pairs.", num_keys);
println!("\n✅ Successfully generated and saved {} validator key pairs.", num_validators);

Ok(())
}
Expand Down