Try   HackMD

In the realm of modern cryptography, secure communication over potentially insecure channels is a crucial challenge. One of the earliest and most revolutionary breakthroughs to address this problem was the Diffie-Hellman Key Exchange.

It allowed two parties to create a shared secret key over a public channel without revealing that key to eavesdroppers.
Well, in my persepective the keys aren't actually "shared" in the traditional sense. You'll see what I mean by this.

Understanding the problem

Let us assume there are 5 people standing in a line. The first person is Alice and the last person in the line is Bob. Alice wants to share a secret with Bob and the only way to communicate in this scenario is by passing the message to the person on your right(say on a piece of paper). As you may have already guessed, this poses some serious security issues since this means, everyone else in the line will find out the secret as it travels from Aice to Bob.
Although this example doesn't fully justify the state of real world insecure communication channels, you get the idea(I hope).

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

In reality, Alice and Bob want to a shared secret key(or encryption key) which can be used to encrypt/decrypt messages between them. Diffie Hellman solves the problem of sending these keys between 2 entities in a space full of malecious parties.

Time for Math

  • Step 1: Alice and Bob must decide on public paramters - p(base prime) and G (generator).
    Let us take:
    p=23

    and:
    G=5
  • Step 2: Alice and Bob independently choose their private keys(not to shared with anyone)
    These numbers must be in the range 1 < x < p
    Lets us say Alice:
    a=6

    and Bob :
    b=15
  • Step 3: Calculation of public keys:
    For Alice:
    A=Gamodp=56mod23=8

    For Bob:
    B=Gbmodp=515mod23=19
  • Step 4: Exchange these values over untrusted space. So now Alice has Bob's public key(B) and Bob has Alice's public key(A).
    We do not care if others in the channel may have acquired these values as well.
  • Step 5: Now, both Alice and Bob can compute the shared secret by raising the other’s public key to the power of their own private key, modulo p
    For Alice,
    s=Bamodp=196mod23=2

    For Bob,
    s=Abmodp=815mod23=2

    Hence, Alice and Bob now have a shared secret key = 2 without actually having to share the key itself.

Time for Code

We will be using Lambdaworks which is a great library for building cryptographic primitives. Also we will be using Elliptic Curve Diffie Hellman which uses Elliptic Curves for the key generations.

In this example, we use TinyJubJub curve. The parameters for this curve are:

  • Base Prime: p=13
  • Generator: G= (10,3)
use lambdaworks_math::{cyclic_group::IsGroup,elliptic_curve::{montgomery::curves::tiny_jub_jub::{self,TinyJubJubMontgomery},traits::IsEllipticCurve}, field::element::FieldElement};
use lambdaworks_math::field::fields::u64_prime_field::U64PrimeField;

fn main(){
    tiny_jub_jub_math();
}

fn tiny_jub_jub_math(){

    type BaseField=U64PrimeField<13>;

    let p_x1=FieldElement::from(1);
    let p_y1=FieldElement::from(9);
    let p_x2=FieldElement::from(7);
    let p_y2=FieldElement::from(12);

    let gen=TinyJubJubMontgomery::generator();

    let priv_alice=TinyJubJubMontgomery::create_point_from_affine(p_x1, p_y1).unwrap();
    let priv_bob=TinyJubJubMontgomery::create_point_from_affine(p_x2, p_y2).unwrap();

    //public_key= Priv_key * Generator
    let pubk_alice=priv_alice.operate_with(&gen);
    let pubk_bob=priv_bob.operate_with(&gen);
    
    //secret_key_1= Priv_keyA * (Priv_keyB * Generator)
    let key_alice=priv_alice.operate_with(&pubk_bob);
    //secret_key_1= Priv_keyB * (Priv_keyA * Generator)
    let key_bob=priv_bob.operate_with(&pubk_alice);

    println!("k1:{:?}",key_alice.coordinates());
    println!("k2:{:?}",key_bob.coordinates());

    // Confirm K! == K2
    assert_eq!(key_alice.coordinates(),key_bob.coordinates());

}