Skip to content

Commit

Permalink
improve keygen algo
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdaybird committed Dec 30, 2024
1 parent 2078b6f commit 98a29b3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
22 changes: 17 additions & 5 deletions src/dsa/eddsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! 1. [RFC8032] "Edwards-Curve Digital Signature Algorithm (EdDSA)".
use crypto_bigint::{Encoding, U256, U512};
use curve::{Coordinate, ScalarField, ScalarField64, GENERATOR, ORDER};
use rand::Rng;
use sha2::{Digest, Sha512};

pub mod curve;
Expand Down Expand Up @@ -46,18 +47,29 @@ fn reduce_by_order(x: [u8; 64]) -> [u8; 32] {
pub struct Ed25519;

impl Ed25519 {
/// Generates the `public_key` given the `private_key`.
/// Generates the `public_key` using the `private_key`, if given, otherwise randomly generates
/// one.
///
/// The `private_key` should be a randomly generated 32-byte array.
/// Returns both the keys as a (private_key, public_key) tuple.
pub fn keygen(private_key: [u8; 32]) -> ([u8; 32], [u8; 32]) {
let keyhash = sha512_hash(&private_key);
pub fn keygen(private_key: Option<[u8; 32]>) -> ([u8; 32], [u8; 32]) {
let pk = match private_key {
Some(pk) => pk,
None => {
let mut rng = rand::thread_rng();
let v: Vec<_> = (0..32).map(|_| rng.gen_range(0..=255)).collect();
let mut a = [0u8; 32];
a.copy_from_slice(&v);
a
},
};

let keyhash = sha512_hash(&pk);
let mut h = [0u8; 32];
h.copy_from_slice(&keyhash[..32]);

let a = ScalarField::new(&U256::from_le_bytes(clamp(h)));
let public_key = GENERATOR * a;
(private_key, public_key.encode())
(pk, public_key.encode())
}

/// Sign the `message` using the `public_key` and `private_key`.
Expand Down
19 changes: 14 additions & 5 deletions src/dsa/eddsa/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ use test::Bencher;

use super::*;

#[test]
fn test_simple() {
let (sk, pk) = Ed25519::keygen(None);
let msg = b"Hello World";

let signature = Ed25519::sign(sk, pk, msg);
assert!(Ed25519::verify(pk, msg, signature));
}

/// Test the `Ed25519` digital signature scheme using the test vectors given in Section 7.1 of RFC
/// 8032.
#[rstest]
Expand Down Expand Up @@ -49,7 +58,7 @@ fn test_small(
#[case] msg: &[u8],
#[case] expected_signature: [u8; 64],
) {
let (_, public_key) = Ed25519::keygen(secret_key);
let (_, public_key) = Ed25519::keygen(Some(secret_key));
assert_eq!(public_key, expected_public_key);

let signature = Ed25519::sign(secret_key, public_key, msg);
Expand Down Expand Up @@ -82,7 +91,7 @@ fn test_large() {

let msg = decode_hex(&v[2]).unwrap();

let (_, public_key) = Ed25519::keygen(secret_key);
let (_, public_key) = Ed25519::keygen(Some(secret_key));
assert_eq!(public_key, expected_public_key);

let signature = Ed25519::sign(secret_key, public_key, &msg);
Expand All @@ -101,7 +110,7 @@ fn bench_keygen(b: &mut Bencher) {

b.iter(|| {
let sk = test::black_box(sk_b);
Ed25519::keygen(sk)
Ed25519::keygen(Some(sk))
});
}

Expand All @@ -113,7 +122,7 @@ macro_rules! bench_sign {
let sk_v: Vec<_> = (0..32).map(|_| rng.gen_range(0..=255)).collect();
let mut sk_b = [0u8; 32];
sk_b.copy_from_slice(&sk_v);
let (_, pk_b) = Ed25519::keygen(sk_b);
let (_, pk_b) = Ed25519::keygen(Some(sk_b));

let msg_v: Vec<_> = (0..$n).map(|_| rng.gen_range(0..=255)).collect();
let mut msg_b = [0u8; $n];
Expand Down Expand Up @@ -147,7 +156,7 @@ macro_rules! bench_verify {
let sk_v: Vec<_> = (0..32).map(|_| rng.gen_range(0..=255)).collect();
let mut sk_b = [0u8; 32];
sk_b.copy_from_slice(&sk_v);
let (_, pk_b) = Ed25519::keygen(sk_b);
let (_, pk_b) = Ed25519::keygen(Some(sk_b));

let msg_v: Vec<_> = (0..$n).map(|_| rng.gen_range(0..=255)).collect();
let mut msg_b = [0u8; $n];
Expand Down

0 comments on commit 98a29b3

Please sign in to comment.