Skip to content

Commit

Permalink
Implement ECDH on Ed25519
Browse files Browse the repository at this point in the history
  • Loading branch information
cloudhead committed Jan 26, 2023
1 parent cf1a0c0 commit 91a23d7
Showing 1 changed file with 30 additions and 4 deletions.
34 changes: 30 additions & 4 deletions src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use core::fmt;
use core::ops::{Deref, DerefMut};

use super::common::*;
#[cfg(feature = "blind-keys")]
use super::edwards25519::{ge_scalarmult, sc_invert, sc_mul};
use super::edwards25519::{
ge_scalarmult_base, is_identity, sc_muladd, sc_reduce, sc_reduce32, sc_reject_noncanonical,
GeP2, GeP3,
ge_scalarmult, ge_scalarmult_base, is_identity, sc_muladd, sc_reduce, sc_reduce32,
sc_reject_noncanonical, GeP2, GeP3,
};
#[cfg(feature = "blind-keys")]
use super::edwards25519::{sc_invert, sc_mul};
use super::error::Error;
use super::sha512;

Expand All @@ -33,6 +33,21 @@ impl PublicKey {
pk_.copy_from_slice(pk);
Ok(PublicKey::new(pk_))
}

/// Multiply the point represented by the public key by the scalar.
///
/// If all you need is ECDH, use the `x25519` module instead.
/// However, if you need signing and ECDH using the same key, you
/// may use this function.
pub fn dh(&self, sk: &SecretKey) -> Result<[u8; 32], Error> {
let (scalar, _) = {
let hash_output = sha512::Hash::hash(&sk.seed()[..]);
KeyPair::split(&hash_output, false, true)
};
let ge = GeP3::from_bytes_vartime(&self.0).ok_or(Error::InvalidPublicKey)?;

Ok(ge_scalarmult(&scalar, &ge).to_bytes())
}
}

impl Deref for PublicKey {
Expand Down Expand Up @@ -950,3 +965,14 @@ fn test_ed25519_invalid_keypair() {
assert!(kp2.sk.validate_public_key(&kp2.pk).is_ok());
assert!(kp1.validate().is_ok());
}

#[test]
fn test_e25519_dh() {
let kp_a = KeyPair::generate();
let kp_b = KeyPair::generate();

let output_a = kp_b.pk.dh(&kp_a.sk).unwrap();
let output_b = kp_a.pk.dh(&kp_b.sk).unwrap();

assert_eq!(output_a, output_b);
}

0 comments on commit 91a23d7

Please sign in to comment.