1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
//! X25519 - diffie hellman using curve25519
//!
//! Curve25519 elliptic curve from [Specification][1], and extra information also on [Wikipedia][2]
//!
//! # Example
//!
//! Creating a curve25519 point from a secret:
//!
//! ```
//! use cryptoxide::x25519;
//!
//! let secret = x25519::SecretKey::from([0,1,2,3,4,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
//! let public = x25519::base(&secret);
//! ```
//!
//! Doing a ECDH on curve25519 using a curve point 'other_point' and a specific secret:
//!
//! ```
//! use cryptoxide::x25519;
//!
//! # let other_public = x25519::base(&x25519::SecretKey::from([3u8; 32]));
//! let secret = x25519::SecretKey::from([0,1,2,3,4,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
//! let shared_secret = x25519::dh(&secret, &other_public);
//! ```
//!
//! [1]: <https://cr.yp.to/ecdh/curve25519-20060209.pdf>
//! [2]: <https://en.wikipedia.org/wiki/Curve25519>
use crate::curve25519::{curve25519, curve25519_base};
macro_rules! bytes_impl {
($t:ident, $n:literal) => {
impl From<[u8; $n]> for $t {
fn from(v: [u8; $n]) -> Self {
$t(v)
}
}
impl core::convert::TryFrom<&[u8]> for $t {
type Error = ();
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
if value.len() == $n {
Ok($t(<[u8; $n]>::try_from(value).unwrap()))
} else {
Err(())
}
}
}
impl AsRef<[u8]> for $t {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
};
}
/// Secret Key
pub struct SecretKey([u8; 32]);
bytes_impl!(SecretKey, 32);
/// Public Key
pub struct PublicKey([u8; 32]);
bytes_impl!(PublicKey, 32);
pub struct SharedSecret([u8; 32]);
bytes_impl!(SharedSecret, 32);
/// Computes a shared secret from the curve25519 private key (n) and public
/// key (p)
pub fn dh(n: &SecretKey, p: &PublicKey) -> SharedSecret {
SharedSecret(curve25519(&n.0, &p.0))
}
/// Derives a public key from a private key
pub fn base(x: &SecretKey) -> PublicKey {
PublicKey(curve25519_base(&x.0))
}