From dfd2b7ded8fcdb598a01319bb28b5621b869b567 Mon Sep 17 00:00:00 2001 From: redshiftzero Date: Wed, 30 Aug 2023 13:31:46 -0400 Subject: [PATCH] crypto: in `SeedPhrase::from_randomness`, infer word length --- .../component/dex/src/swap_claim/proof.rs | 4 +- .../governance/src/delegator_vote/proof.rs | 6 +-- .../shielded-pool/src/nullifier_derivation.rs | 4 +- .../shielded-pool/src/output/proof.rs | 6 +-- .../shielded-pool/src/spend/proof.rs | 22 +++++------ crates/core/keys/src/keys/seed_phrase.rs | 37 ++++++++----------- 6 files changed, 37 insertions(+), 42 deletions(-) diff --git a/crates/core/component/dex/src/swap_claim/proof.rs b/crates/core/component/dex/src/swap_claim/proof.rs index 975ddb4e66..f084625328 100644 --- a/crates/core/component/dex/src/swap_claim/proof.rs +++ b/crates/core/component/dex/src/swap_claim/proof.rs @@ -217,7 +217,7 @@ impl ParameterSetup for SwapClaimCircuit { .id(), }; - let seed_phrase = SeedPhrase::from_randomness([b'f'; 32]); + let seed_phrase = SeedPhrase::from_randomness(&[b'f'; 32]); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -416,7 +416,7 @@ mod tests { let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_recipient = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_recipient = sk_recipient.full_viewing_key(); let ivk_recipient = fvk_recipient.incoming(); diff --git a/crates/core/component/governance/src/delegator_vote/proof.rs b/crates/core/component/governance/src/delegator_vote/proof.rs index a12972b257..199a095103 100644 --- a/crates/core/component/governance/src/delegator_vote/proof.rs +++ b/crates/core/component/governance/src/delegator_vote/proof.rs @@ -186,7 +186,7 @@ impl ConstraintSynthesizer for DelegatorVoteCircuit { impl ParameterSetup for DelegatorVoteCircuit { fn generate_test_parameters() -> (ProvingKey, VerifyingKey) { - let seed_phrase = SeedPhrase::from_randomness([b'f'; 32]); + let seed_phrase = SeedPhrase::from_randomness(&[b'f'; 32]); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -367,7 +367,7 @@ mod tests { let (pk, vk) = DelegatorVoteCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -438,7 +438,7 @@ mod tests { let (pk, vk) = DelegatorVoteCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); diff --git a/crates/core/component/shielded-pool/src/nullifier_derivation.rs b/crates/core/component/shielded-pool/src/nullifier_derivation.rs index 3c9c5051cb..bc4f93d2be 100644 --- a/crates/core/component/shielded-pool/src/nullifier_derivation.rs +++ b/crates/core/component/shielded-pool/src/nullifier_derivation.rs @@ -75,7 +75,7 @@ impl ConstraintSynthesizer for NullifierDerivationCircuit { impl ParameterSetup for NullifierDerivationCircuit { fn generate_test_parameters() -> (ProvingKey, VerifyingKey) { - let seed_phrase = SeedPhrase::from_randomness([b'f'; 32]); + let seed_phrase = SeedPhrase::from_randomness(&[b'f'; 32]); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -211,7 +211,7 @@ mod tests { let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); diff --git a/crates/core/component/shielded-pool/src/output/proof.rs b/crates/core/component/shielded-pool/src/output/proof.rs index 797955086a..9e27b9e3ab 100644 --- a/crates/core/component/shielded-pool/src/output/proof.rs +++ b/crates/core/component/shielded-pool/src/output/proof.rs @@ -253,7 +253,7 @@ mod tests { let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_recipient = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_recipient = sk_recipient.full_viewing_key(); let ivk_recipient = fvk_recipient.incoming(); @@ -296,7 +296,7 @@ mod tests { let (pk, vk) = OutputCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_recipient = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_recipient = sk_recipient.full_viewing_key(); let ivk_recipient = fvk_recipient.incoming(); @@ -345,7 +345,7 @@ mod tests { let (pk, vk) = OutputCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_recipient = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_recipient = sk_recipient.full_viewing_key(); let ivk_recipient = fvk_recipient.incoming(); diff --git a/crates/core/component/shielded-pool/src/spend/proof.rs b/crates/core/component/shielded-pool/src/spend/proof.rs index 969664518b..7d440b6b1d 100644 --- a/crates/core/component/shielded-pool/src/spend/proof.rs +++ b/crates/core/component/shielded-pool/src/spend/proof.rs @@ -171,7 +171,7 @@ impl ConstraintSynthesizer for SpendCircuit { impl ParameterSetup for SpendCircuit { fn generate_test_parameters() -> (ProvingKey, VerifyingKey) { - let seed_phrase = SeedPhrase::from_randomness([b'f'; 32]); + let seed_phrase = SeedPhrase::from_randomness(&[b'f'; 32]); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -358,7 +358,7 @@ mod tests { let (pk, vk) = SpendCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -423,7 +423,7 @@ mod tests { let (pk, vk) = SpendCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -481,10 +481,10 @@ mod tests { let (pk, vk) = SpendCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); - let wrong_seed_phrase = SeedPhrase::from_randomness(incorrect_seed_phrase_randomness); + let wrong_seed_phrase = SeedPhrase::from_randomness(&incorrect_seed_phrase_randomness); let wrong_sk_sender = SpendKey::from_seed_phrase(wrong_seed_phrase, 0); let wrong_fvk_sender = wrong_sk_sender.full_viewing_key(); let wrong_ivk_sender = wrong_fvk_sender.incoming(); @@ -543,7 +543,7 @@ mod tests { let (pk, vk) = SpendCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -602,7 +602,7 @@ mod tests { let (pk, vk) = SpendCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -660,7 +660,7 @@ mod tests { let (pk, vk) = SpendCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -721,7 +721,7 @@ mod tests { let (pk, vk) = SpendCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness(seed_phrase_randomness); + let seed_phrase = SeedPhrase::from_randomness(&seed_phrase_randomness); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -825,7 +825,7 @@ mod tests { impl ParameterSetup for MerkleProofCircuit { fn generate_test_parameters() -> (ProvingKey, VerifyingKey) { - let seed_phrase = SeedPhrase::from_randomness([b'f'; 32]); + let seed_phrase = SeedPhrase::from_randomness(&[b'f'; 32]); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); @@ -876,7 +876,7 @@ mod tests { let (pk, vk) = MerkleProofCircuit::generate_prepared_test_parameters(); let mut rng = OsRng; - let seed_phrase = SeedPhrase::from_randomness([b'f'; 32]); + let seed_phrase = SeedPhrase::from_randomness(&[b'f'; 32]); let sk_sender = SpendKey::from_seed_phrase(seed_phrase, 0); let fvk_sender = sk_sender.full_viewing_key(); let ivk_sender = fvk_sender.incoming(); diff --git a/crates/core/keys/src/keys/seed_phrase.rs b/crates/core/keys/src/keys/seed_phrase.rs index 424cded15a..2dfe9bbfbd 100644 --- a/crates/core/keys/src/keys/seed_phrase.rs +++ b/crates/core/keys/src/keys/seed_phrase.rs @@ -33,6 +33,14 @@ impl SeedPhraseType { } } + pub fn from_randomness_length(len: usize) -> anyhow::Result { + match len * NUM_BITS_PER_BYTE { + NUM_ENTROPY_BITS_SHORT => Ok(SeedPhraseType::MinimumLength), + NUM_ENTROPY_BITS_LONG => Ok(SeedPhraseType::MaximumLength), + _ => Err(anyhow::anyhow!("invalid randomness length")), + } + } + pub fn num_words(&self) -> usize { match self { SeedPhraseType::MinimumLength => NUM_WORDS_SHORT, @@ -54,13 +62,6 @@ impl SeedPhraseType { } } - pub fn num_entropy_bytes(&self) -> usize { - match self { - SeedPhraseType::MinimumLength => NUM_ENTROPY_BITS_SHORT / NUM_BITS_PER_BYTE, - SeedPhraseType::MaximumLength => NUM_ENTROPY_BITS_LONG / NUM_BITS_PER_BYTE, - } - } - pub fn num_total_bits(&self) -> usize { self.num_entropy_bits() + self.num_checksum_bits() } @@ -74,27 +75,22 @@ impl SeedPhrase { pub fn generate(mut rng: R) -> Self { let mut randomness = [0u8; NUM_ENTROPY_BITS_LONG / NUM_BITS_PER_BYTE]; rng.fill_bytes(&mut randomness); - Self::from_randomness(&randomness, NUM_WORDS_LONG) + Self::from_randomness(&randomness) } /// Randomly generates a 12 word BIP39 [`SeedPhrase`]. pub fn short_generate(mut rng: R) -> Self { let mut randomness = [0u8; NUM_ENTROPY_BITS_SHORT / NUM_BITS_PER_BYTE]; rng.fill_bytes(&mut randomness); - Self::from_randomness(&randomness, NUM_WORDS_SHORT) + Self::from_randomness(&randomness) } /// Given bytes of randomness, generate a [`SeedPhrase`]. - pub fn from_randomness(randomness: &[u8], length: usize) -> Self { - let seed_phrase_type = - SeedPhraseType::from_length(length).expect("can get seed phrase type"); - if seed_phrase_type.num_entropy_bytes() != randomness.len() { - panic!( - "invalid length of randomness: expected {}, got {}", - seed_phrase_type.num_entropy_bytes(), - randomness.len() - ); - } + pub fn from_randomness(randomness: &[u8]) -> Self { + // We infer if the seed phrase will be a valid length based on the number of + // random bytes generated. + let seed_phrase_type = SeedPhraseType::from_randomness_length(randomness.len()) + .expect("can get seed phrase type from randomness length"); let num_entropy_bits = seed_phrase_type.num_entropy_bits(); let mut bits = vec![false; seed_phrase_type.num_total_bits()]; @@ -268,9 +264,8 @@ mod tests { for (hex_randomness, expected_phrase) in randomness_arr.iter().zip(expected_phrase_arr.iter()) { - let length = expected_phrase.split_whitespace().count(); let randomness = hex::decode(hex_randomness).expect("can decode test vector"); - let actual_phrase = SeedPhrase::from_randomness(&randomness[..], length); + let actual_phrase = SeedPhrase::from_randomness(&randomness[..]); assert_eq!(actual_phrase.to_string(), *expected_phrase); actual_phrase .verify_checksum()