From 89c870577956185a7c927c8ed3f67898736c5d77 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Mon, 27 May 2019 21:42:40 -0700 Subject: [PATCH] [BROKEN] Start the process of adding examples to the top of the files, and in doing so note that DSA key generation is broken. --- cryptonum | 2 +- src/dsa/mod.rs | 32 ++++++++++++++++++++++++++++++++ src/dsa/params.rs | 13 ++++++------- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/cryptonum b/cryptonum index 83ed5bc..666378b 160000 --- a/cryptonum +++ b/cryptonum @@ -1 +1 @@ -Subproject commit 83ed5bc0baca5d1a36a62d63c8e1673a162acf49 +Subproject commit 666378b14baeaaa6b717934656f7982c347e015e diff --git a/src/dsa/mod.rs b/src/dsa/mod.rs index 0e334bf..d71f629 100644 --- a/src/dsa/mod.rs +++ b/src/dsa/mod.rs @@ -1,3 +1,35 @@ +//! If you want to use this module to generate keys, which you really +//! really shouldn't, there are two ways to do so, depending on whether +//! you've previously agreed on a set of DSA parameters for this key +//! pair. If you haven't, you can generate the parameters using a good +//! random number generator. +//! +//! ```rust +//! extern crate sha2; +//! +//! use simple_crypto::dsa::{DSAKeyPair,DSAParameters,L2048N256}; +//! use sha2::Sha224; +//! +//! // Generate a set of DSA parameters, assuming you don't have +//! // them already +//! let mut rng = rand::rngs::OsRng::new().unwrap(); +//! let params = L2048N256::generate(&mut rng); +//! +//! // Given those parameters, you can generate a key pair like so: +//! let kp = DSAKeyPair::::generate(¶ms, &mut rng); +//! // Keeping in mind that you can re-use the parameters across multiple +//! // keys, and that their secrecy isn't paramout for the security of the +//! // algorithm. +//! +//! // Now that you have this key pair, you can sign and verify messages +//! // using it. For example, to sign the vector [0,1,2,3,4] with SHA224 +//! // and then verify that signature, we would write: +//! let msg = vec![0,1,2,3,4]; +//! let sig = kp.private.sign::(&msg); +//! assert!( kp.public.verify::(&msg, &sig) ); +//! ``` + + mod errors; mod params; mod private; diff --git a/src/dsa/params.rs b/src/dsa/params.rs index 9018438..89d2772 100644 --- a/src/dsa/params.rs +++ b/src/dsa/params.rs @@ -86,7 +86,7 @@ macro_rules! generate_parameters { impl $name { - fn generate_primes(rng: &mut G) -> ($ltype,$ntype,U256,usize) + pub fn generate_primes(rng: &mut G) -> ($ltype,$ntype,U256,usize) { // This is A.1.1.2 from FIPS 186-4, with seedlen hardcoded to 256 // (since that's guaranteed to be >= N), and with the hash @@ -106,7 +106,7 @@ macro_rules! generate_parameters { // 2. If (seedlen < N), then return INVALID. // [This is always true.] // - // 3. n = L/outlen – 1. + // 3. n = L/outlen – 1. let n = ((L + 255) / 256) - 1; // 4. b = L – 1 – (n ∗ outlen). let b = L - 1 - (n * outlen); @@ -120,10 +120,9 @@ macro_rules! generate_parameters { #[allow(non_snake_case)] let U = $ntype::from_bytes(&ubytes); // 7. q = 2^(N–1) + U + 1 – (U mod 2). - let ulow = if U.is_even() { 0 } else { 1 }; - let mut q = $ntype::from(1u64) << (N - 1); - q += U; - q += $ntype::from(1u64 + ulow); + let highbit = $ntype::from(1u64) << (N - 1); + let lowbit = $ntype::from(1u64); + let q = U | highbit | lowbit; // 8. Test whether or not q is prime as specified in Appendix C.3. let q_is_prime = q.probably_prime(rng, 40); // 9. If q is not a prime, then go to step 5. @@ -141,7 +140,7 @@ macro_rules! generate_parameters { for j in 0..n { let val = &domain_parameter_seed + U256::from(offset + j); let bytes = hash(&val, 32); - assert_eq!(seedlen, bytes.len()); + assert_eq!(seedlen, bytes.len() * 8); V.push(bytes); } // 11.2 W = V_0 + ( V_1 ∗ 2^outlen) + ... + ( V_(n–1) ∗ 2^(n –1) ∗ outlen) + ((V_n mod 2^b) ∗ 2^(n ∗ outlen).