open Syntax type priv = Mirage_crypto_ec.Ed25519.priv type pub = Mirage_crypto_ec.Ed25519.pub (* transmitted as 64-bytes base32 binary-encoded objects with just the R and S values *) type sig_ = Sig of string let generate = Mirage_crypto_ec.Ed25519.generate let pub_of_priv = Mirage_crypto_ec.Ed25519.pub_of_priv let priv_to_octets t = Mirage_crypto_ec.Ed25519.priv_to_octets t let priv_of_octets t = Mirage_crypto_ec.Ed25519.priv_of_octets t |> function | Error err -> let err = Fmt.str "%a" Mirage_crypto_ec.pp_error err in Error err | Ok v -> Ok v let priv_bin = let priv_of_octets_exn t = priv_of_octets t |> Result.get_ok in Bin.map (Bin.bytes 32) priv_of_octets_exn priv_to_octets let priv_jsont = let of_b32 s = let* octets = B32.decode s in priv_of_octets octets in let to_b32 t = B32.encode (priv_to_octets t) in Jsont.of_of_string ~kind:"EddsaPrivateKey" of_b32 ~enc:to_b32 let pub_to_octets t = Mirage_crypto_ec.Ed25519.pub_to_octets t let pub_of_octets t = Mirage_crypto_ec.Ed25519.pub_of_octets t |> function | Error e -> Fmt.error "%a" Mirage_crypto_ec.pp_error e | Ok v -> Ok v let pub_bin = let pub_of_octets_exn t = pub_of_octets t |> Result.get_ok in Bin.map (Bin.bytes 32) pub_of_octets_exn pub_to_octets let pub_of_b32 s = let* octets = B32.decode s in pub_of_octets octets let pub_to_b32 t = B32.encode (pub_to_octets t) let pub_jsont = Jsont.of_of_string ~kind:"EddsaPublicKey" pub_of_b32 ~enc:pub_to_b32 let pub_caqti = Caqti_type.custom ~encode:(fun v -> Ok (pub_to_octets v)) ~decode:(fun v -> pub_of_octets v) Caqti_type.octets let sign ~key s = let sig_ = Mirage_crypto_ec.Ed25519.sign ~key s in Sig sig_ let verify ~key (Sig s) ~msg = let b = Mirage_crypto_ec.Ed25519.verify ~key s ~msg in match b with | false -> Error "EddsaSignature verification: invalid signature" | true -> Ok () let sig_to_octets (Sig s) = s let check_size s = match String.length s = 64 with | false -> Error "EddsaSignature of_octets: data is not 64 bytes." | true -> Ok () let sig_of_octets s = let+ () = check_size s in Sig s let sig_bin = let sig_of_octets_exn t = sig_of_octets t |> Result.get_ok in Bin.map (Bin.bytes 64) sig_of_octets_exn sig_to_octets let sig_jsont = let sig_of_b32 s = let* s = B32.decode s in sig_of_octets s in let sig_to_b32 (Sig s) = B32.encode s in Jsont.of_of_string ~kind:"EddsaSignature" sig_of_b32 ~enc:sig_to_b32 let sig_caqti = Caqti_type.custom ~encode:(fun v -> Ok (sig_to_octets v)) ~decode:(fun s -> sig_of_octets s) Caqti_type.octets