Skip to content

x.crypto.curve25519 #

curve25519


This module implement Diffie-Hellman key exchange mechanism (ECDHA) based on elliptic curve known as Curve25519 in pure V.

About curve25519

From wikipedia, Curve25519 is an elliptic curve used in elliptic-curve cryptography (ECC) offering 128 bits of security (256-bit key size) and designed for use with the elliptic curve Diffie–Hellman (ECDH) key agreement scheme. It is one of the fastest curves in ECC, and is not covered by any known patents. The reference implementation is public domain software. The original Curve25519 paper defined it as a Diffie–Hellman (DH) function. Daniel J. Bernstein has since proposed that the name "Curve25519" be used for the underlying curve, and the name "X25519" for the DH function Curve25519 is an elliptic curve that offers 128 security bits and is designed for use in the Elliptic Curve Diffie-Hellman (ECDH) key agreement key design scheme.

Examples

import x.crypto.curve25519

fn main() {
    // For example, two peers, Alice and Bob, want to create a shared secret together
    //
    // Alice generates a private key
    mut alice_pvkey := curve25519.PrivateKey.new()!
    // Alice's PublicKey to be shared with Bob
    alice_pbkey := alice_pvkey.public_key()!

    // The other peer, Bob, has a different private key
    mut bob_pvkey := curve25519.PrivateKey.new()!
    // Bob's public key to be shared with Alice
    bob_pbkey := bob_pvkey.public_key()!

    // Let the two peers exchange their respective public keys
    //
    // Alice derives the shared secret, using her own private key, and the public key that Bob shared
    alice_shared_sec := curve25519.derive_shared_secret(mut alice_pvkey, bob_pbkey)!

    // Bob derives the shared secret, using his own private key, and the public key that Alice shared
    bob_shared_sec := curve25519.derive_shared_secret(mut bob_pvkey, alice_pbkey)!

    // the two shared secrets (derived by Alice, and derived by Bob), should be the same
    //
    println(alice_shared_sec.hex()) // 49fd4a4d0637d2413cd501b20111fc50a592dc21460e45f451c03d1fd3cef900
    println(bob_shared_sec.hex()) // 49fd4a4d0637d2413cd501b20111fc50a592dc21460e45f451c03d1fd3cef900
    dump(alice_shared_sec == bob_shared_sec) // alice_shared_sec == bob_shared_sec: true

    assert alice_shared_sec == bob_shared_sec
}

fn derive_shared_secret #

fn derive_shared_secret(mut local PrivateKey, remote PublicKey, opt SharedOpts) ![]u8

derive_shared_secret derives a shared secret between two peer's between first private key's peer and the second PublicKey's peer. Its accepts SharedOpts options to advance supports for other key derivation mechanism.

  1. Diffie-Hellman with Curve25519See https://datatracker.ietf.org/doc/html/rfc7748#section-6

fn x25519 #

fn x25519(mut scalar []u8, point []u8) ![]u8

x25519 returns the result of the scalar multiplication (scalar * point), according to RFC 7748, Section 5. scalar, point and the return value are slices of 32 bytes. The functions take a scalar and a u-coordinate as inputs and produce a u-coordinate as output. Although the functions work internally with integers, the inputs and outputs are 32-bytes length (for X25519). scalar can be generated at random, for example with crypto.rand and point should be either base_point or the output of another x25519 call.

fn PrivateKey.new #

fn PrivateKey.new() !&PrivateKey

new creates a new Curve25519 key using randomly generated bytes from crypto.rand.

fn PrivateKey.new_from_seed #

fn PrivateKey.new_from_seed(seed []u8) !&PrivateKey

new_from_seed creates a new Curve25519 key from provided seed bytes.

fn PublicKey.new_from_bytes #

fn PublicKey.new_from_bytes(bytes []u8) !&PublicKey

new_from_bytes creates a new Curve25519 public key from provided bytes.

interface Derivator #

interface Derivator {
	// derive transforms bytes in sec into another form of bytes.
	derive(sec []u8, opt DeriveOpts) ![]u8
}

Derivator represent key derivation function

struct DeriveOpts #

@[params]
struct DeriveOpts {}

DeriveOpts is config to drive the Derivator's derive operation.

struct PrivateKey #

@[noinit]
struct PrivateKey {
mut:
	// boolean flag that tells this key should not be
	// used again when its true. its set after .free call
	done bool
	// clamped key, 32 bytes length
	key []u8
}

PrivateKey represents Curve25519 private key

fn (PrivateKey) public_key #

fn (mut pv PrivateKey) public_key() !&PublicKey

public_key returns the associated public key part of the PrivateKey.

fn (PrivateKey) equal #

fn (pv PrivateKey) equal(oth PrivateKey) bool

equal returns whether two private keys are equal.

fn (PrivateKey) x25519 #

fn (mut pv PrivateKey) x25519(point []u8) ![]u8

x25519 performs scalar multiplication between key and point and return another bytes (point).

fn (PrivateKey) bytes #

fn (pv PrivateKey) bytes() ![]u8

bytes return a clone of the bytes of the underlying PrivateKey

fn (PrivateKey) free #

unsafe
fn (mut pv PrivateKey) free()

free releases underlying key. Dont use the key after calling .free

struct PublicKey #

@[noinit]
struct PublicKey {
mut:
	// 32 bytes length of scalar * point
	key []u8
}

PublicKey represent Curve25519 key.

fn (PublicKey) equal #

fn (pb PublicKey) equal(other PublicKey) bool

equal tells whether two public keys are equal

fn (PublicKey) bytes #

fn (pb PublicKey) bytes() ![]u8

bytes return the clone of the bytes of the underlying PublicKey

struct SharedOpts #

@[params]
struct SharedOpts {
pub mut:
	should_derive bool
	derivator     Derivator = RawDerivator{}
	drv_opts      DeriveOpts
}

SharedOpts is the configuration options to derive_shared_secret routine