Curve 25519 and Rust

The core of the security on the Web comes down to … elliptic curve cryptography (ECC). With the ECDH (Elliptic Curve Diffie Hellman)…

Photo by Daniele Levis Pelusi on Unsplash

Curve 25519 and Rust

The core of the security on the Web comes down to … elliptic curve cryptography (ECC). With the ECDH (Elliptic Curve Diffie Hellman) handshake method, we have an almost perfect way to generate a shared key between Bob and Alice, without Eve ever finding it out. And so we turn to Curve 25519, and which is one of the best elliptic curves around. It uses the Montgomery curve form of:

And where we take a base point (G), and then create a private key (n), and then determine our public key (nG). With this nG is the point G added n times (G+G+…G). Curve 25519 was created by Daniel J Bernstein, and who has contributed so much to cybersecurity. The form he chose was:

and where p=2²⁵⁵-19. It thus gave 128-bit security levels, and which is currently strong enough in most applications. The base point chosen is x=9, and which gives a point of:

P=( 9 , 14781619447589544791020593568409986887264606134616475288964881837755586237401 )

The point adding and scaling uses the method defined in RFC 7748 [here]:

In Curve 25519, we have a base point of G, and then take a secret key of sk. The public key is the sk.G. With this curve we just take the y-co-ordinate value for the The base point G is at x = 9, and the corresponding y point is 14781619447589544791020593568409986887264606134616475288964881837755586237401. In order to test, we can use test vectors: [here] and [here]:

Private= "a8abababababababababababababababababababababababababababababab6b"
Public="e3712d851a0e5d79b831c5e34ab22b41a198171de209b8b8faca23a11c624859"
Private=""c8cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd4d"
Public="b5bea823d9c9ff576091c54b7c596c0ae296884f0e150290e88455d7fba6126f"
Alice's private key, a:
77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a
Alice's public key, X25519(a, 9):
8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a
Bob's private key, b:
5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb
Bob's public key, X25519(b, 9):
de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f
Their shared secret, K:
4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742

Now, we can implement our Rust code [here]:

extern crate crypto;
extern crate hex;
use crypto::curve25519::{curve25519_base};
use rustc_serialize::hex::FromHex;
use std::env;
fn hex_to_bytes(s: &str) -> Vec<u8> {
s.from_hex().unwrap()
}
fn main() {
let mut s= "c8cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd4d";
let args: Vec<String> = env::args().collect();

if args.len() >1 { s = args[1].as_str();}
let mut out = vec![0; 32];
let sk = hex_to_bytes(s);
// [u8; 32]
let pk = curve25519_base(sk.as_ref());
println!("== Curve 25519 ===");
println!("Secret key: {}",s);
println!("Curve point: {:X?}",hex::encode(pk.as_ref()));
}

A sample run with our test vector is:

== Curve 25519 ===
Secret key: a8abababababababababababababababababababababababababababababab6b
Curve point: "e3712d851a0e5d79b831c5e34ab22b41a198171de209b8b8faca23a11c624859"

In this case, if Alice’s private key is “a8abababababababababababababababababababababababababababababab6b”, her public key will be “e3712d851a0e5d79b831c5e34ab22b41a198171de209b8b8faca23a11c624859”. A demo is here:

https://asecuritysite.com/rust/rust_curve25519