Source file dh.ml

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
type keypair = { priv : string; pub : string }

type impl = {
  dhlen : int;
  of_secret : string -> (keypair, Error.t) result;
  generate : unit -> (keypair, Error.t) result;
  dh : local:keypair -> remote:string -> (string, Error.t) result;
}

let ec_err e =
  Error (Error.DH_error (Format.asprintf "%a" Mirage_crypto_ec.pp_error e))

let x25519 =
  {
    dhlen = 32;
    of_secret =
      (fun priv_bytes ->
        match Mirage_crypto_ec.X25519.secret_of_octets priv_bytes with
        | Ok (_, pub) -> Ok { priv = priv_bytes; pub }
        | Error e -> ec_err e);
    generate =
      (fun () ->
        let secret, pub = Mirage_crypto_ec.X25519.gen_key () in
        let priv = Mirage_crypto_ec.X25519.secret_to_octets secret in
        Ok { priv; pub });
    dh =
      (fun ~local ~remote ->
        match Mirage_crypto_ec.X25519.secret_of_octets local.priv with
        | Error e -> ec_err e
        | Ok (secret, _) -> (
            match Mirage_crypto_ec.X25519.key_exchange secret remote with
            | Ok shared -> Ok shared
            | Error e -> ec_err e));
  }

let of_name = function
  | "25519" -> Ok x25519
  | other -> Error (Error.Unsupported_primitive ("DH: " ^ other))