Current section
Files
Jump to
Current section
Files
src/kryptos@xdh.erl
-module(kryptos@xdh).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/kryptos/xdh.gleam").
-export([key_size/1, generate_key_pair/1, compute_shared_secret/2, from_bytes/2, to_bytes/1, public_key_from_bytes/2, public_key_to_bytes/1, from_pem/1, from_der/1, to_pem/1, to_der/1, public_key_from_pem/1, public_key_from_der/1, public_key_to_pem/1, public_key_to_der/1, public_key_from_private_key/1, curve/1, public_key_curve/1]).
-export_type([private_key/0, public_key/0, curve/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" X25519 and X448 (XDH) key agreement.\n"
"\n"
" XDH provides Diffie-Hellman key agreement using Montgomery curves X25519\n"
" and X448. These curves are designed specifically for key agreement and\n"
" offer excellent performance with strong security properties.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import kryptos/xdh\n"
"\n"
" // Alice generates a key pair\n"
" let #(alice_private, alice_public) = xdh.generate_key_pair(xdh.X25519)\n"
"\n"
" // Bob generates a key pair\n"
" let #(bob_private, bob_public) = xdh.generate_key_pair(xdh.X25519)\n"
"\n"
" // Both compute the same shared secret\n"
" let assert Ok(alice_shared) = xdh.compute_shared_secret(alice_private, bob_public)\n"
" let assert Ok(bob_shared) = xdh.compute_shared_secret(bob_private, alice_public)\n"
" // alice_shared == bob_shared\n"
" ```\n"
).
-type private_key() :: any().
-type public_key() :: any().
-type curve() :: x25519 | x448.
-file("src/kryptos/xdh.gleam", 48).
?DOC(
" Returns the key size in bytes for the given curve.\n"
"\n"
" ## Parameters\n"
" - `curve`: The XDH curve\n"
"\n"
" ## Returns\n"
" The key size in bytes (32 for X25519, 56 for X448).\n"
).
-spec key_size(curve()) -> integer().
key_size(Curve) ->
case Curve of
x25519 ->
32;
x448 ->
56
end.
-file("src/kryptos/xdh.gleam", 64).
?DOC(
" Generates a new XDH key pair.\n"
"\n"
" ## Parameters\n"
" - `curve`: The curve to use for key generation (X25519 or X448)\n"
"\n"
" ## Returns\n"
" A tuple of `#(private_key, public_key)`.\n"
).
-spec generate_key_pair(curve()) -> {private_key(), public_key()}.
generate_key_pair(Curve) ->
kryptos_ffi:xdh_generate_key_pair(Curve).
-file("src/kryptos/xdh.gleam", 90).
-spec is_all_zeros(bitstring()) -> boolean().
is_all_zeros(Bytes) ->
case Bytes of
<<>> ->
true;
<<0, Rest/binary>> ->
is_all_zeros(Rest);
_ ->
false
end.
-file("src/kryptos/xdh.gleam", 76).
?DOC(
" Computes a shared secret using XDH key agreement.\n"
"\n"
" Both parties compute the same shared secret by combining their private key\n"
" with the other party's public key.\n"
"\n"
" Returns `Error(Nil)` if the keys use different curves, the result is an\n"
" all-zero shared secret (low-order point attack), or another error occurs.\n"
"\n"
" The raw shared secret should be passed through a KDF (like HKDF) before\n"
" use as a symmetric key.\n"
).
-spec compute_shared_secret(private_key(), public_key()) -> {ok, bitstring()} |
{error, nil}.
compute_shared_secret(Private_key, Peer_public_key) ->
gleam@result:'try'(
kryptos_ffi:xdh_compute_shared_secret(Private_key, Peer_public_key),
fun(Shared) -> case is_all_zeros(Shared) of
true ->
{error, nil};
false ->
{ok, Shared}
end end
).
-file("src/kryptos/xdh.gleam", 115).
?DOC(
" Imports a private key from raw bytes.\n"
"\n"
" The bytes should be the raw private key scalar:\n"
" - X25519: 32 bytes\n"
" - X448: 56 bytes\n"
"\n"
" Returns the private key and its corresponding public key, or `Error(Nil)`\n"
" if the bytes are invalid.\n"
).
-spec from_bytes(curve(), bitstring()) -> {ok, {private_key(), public_key()}} |
{error, nil}.
from_bytes(Curve, Private_bytes) ->
kryptos_ffi:xdh_private_key_from_bytes(Curve, Private_bytes).
-file("src/kryptos/xdh.gleam", 127).
?DOC(
" Exports a private key to raw bytes.\n"
"\n"
" Returns the raw private key scalar:\n"
" - X25519: 32 bytes\n"
" - X448: 56 bytes\n"
).
-spec to_bytes(private_key()) -> bitstring().
to_bytes(Key) ->
kryptos_ffi:xdh_private_key_to_bytes(Key).
-file("src/kryptos/xdh.gleam", 138).
?DOC(
" Imports a public key from raw bytes.\n"
"\n"
" The bytes should be the raw public key point:\n"
" - X25519: 32 bytes\n"
" - X448: 56 bytes\n"
"\n"
" Returns the public key or `Error(Nil)` if the bytes are invalid.\n"
).
-spec public_key_from_bytes(curve(), bitstring()) -> {ok, public_key()} |
{error, nil}.
public_key_from_bytes(Curve, Public_bytes) ->
kryptos_ffi:xdh_public_key_from_bytes(Curve, Public_bytes).
-file("src/kryptos/xdh.gleam", 150).
?DOC(
" Exports a public key to raw bytes.\n"
"\n"
" Returns the raw public key point:\n"
" - X25519: 32 bytes\n"
" - X448: 56 bytes\n"
).
-spec public_key_to_bytes(public_key()) -> bitstring().
public_key_to_bytes(Key) ->
kryptos_ffi:xdh_public_key_to_bytes(Key).
-file("src/kryptos/xdh.gleam", 163).
?DOC(
" Imports an XDH private key from PEM-encoded data.\n"
"\n"
" The key must be in PKCS#8 format.\n"
"\n"
" ## Parameters\n"
" - `pem`: PEM-encoded key string\n"
"\n"
" ## Returns\n"
" `Ok(#(private_key, public_key))` on success, `Error(Nil)` on failure.\n"
).
-spec from_pem(binary()) -> {ok, {private_key(), public_key()}} | {error, nil}.
from_pem(Pem) ->
kryptos_ffi:xdh_import_private_key_pem(Pem).
-file("src/kryptos/xdh.gleam", 176).
?DOC(
" Imports an XDH private key from DER-encoded data.\n"
"\n"
" The key must be in PKCS#8 format.\n"
"\n"
" ## Parameters\n"
" - `der`: DER-encoded key data\n"
"\n"
" ## Returns\n"
" `Ok(#(private_key, public_key))` on success, `Error(Nil)` on failure.\n"
).
-spec from_der(bitstring()) -> {ok, {private_key(), public_key()}} |
{error, nil}.
from_der(Der) ->
kryptos_ffi:xdh_import_private_key_der(Der).
-file("src/kryptos/xdh.gleam", 187).
?DOC(
" Exports an XDH private key to PEM format.\n"
"\n"
" The key is exported in PKCS#8 format.\n"
"\n"
" ## Parameters\n"
" - `key`: The private key to export\n"
"\n"
" ## Returns\n"
" `Ok(pem_string)` on success, `Error(Nil)` on failure.\n"
).
-spec to_pem(private_key()) -> {ok, binary()} | {error, nil}.
to_pem(Key) ->
_pipe = kryptos_ffi:xdh_export_private_key_pem(Key),
gleam@result:map(
_pipe,
fun(Pem) -> <<(gleam@string:trim_end(Pem))/binary, "\n"/utf8>> end
).
-file("src/kryptos/xdh.gleam", 206).
?DOC(
" Exports an XDH private key to DER format.\n"
"\n"
" The key is exported in PKCS#8 format.\n"
"\n"
" ## Parameters\n"
" - `key`: The private key to export\n"
"\n"
" ## Returns\n"
" `Ok(der_data)` on success, `Error(Nil)` on failure.\n"
).
-spec to_der(private_key()) -> {ok, bitstring()} | {error, nil}.
to_der(Key) ->
kryptos_ffi:xdh_export_private_key_der(Key).
-file("src/kryptos/xdh.gleam", 219).
?DOC(
" Imports an XDH public key from PEM-encoded data.\n"
"\n"
" The key must be in SPKI format.\n"
"\n"
" ## Parameters\n"
" - `pem`: PEM-encoded key string\n"
"\n"
" ## Returns\n"
" `Ok(public_key)` on success, `Error(Nil)` on failure.\n"
).
-spec public_key_from_pem(binary()) -> {ok, public_key()} | {error, nil}.
public_key_from_pem(Pem) ->
kryptos_ffi:xdh_import_public_key_pem(Pem).
-file("src/kryptos/xdh.gleam", 232).
?DOC(
" Imports an XDH public key from DER-encoded data.\n"
"\n"
" The key must be in SPKI format.\n"
"\n"
" ## Parameters\n"
" - `der`: DER-encoded key data\n"
"\n"
" ## Returns\n"
" `Ok(public_key)` on success, `Error(Nil)` on failure.\n"
).
-spec public_key_from_der(bitstring()) -> {ok, public_key()} | {error, nil}.
public_key_from_der(Der) ->
kryptos_ffi:xdh_import_public_key_der(Der).
-file("src/kryptos/xdh.gleam", 243).
?DOC(
" Exports an XDH public key to PEM format.\n"
"\n"
" The key is exported in SPKI format.\n"
"\n"
" ## Parameters\n"
" - `key`: The public key to export\n"
"\n"
" ## Returns\n"
" `Ok(pem_string)` on success, `Error(Nil)` on failure.\n"
).
-spec public_key_to_pem(public_key()) -> {ok, binary()} | {error, nil}.
public_key_to_pem(Key) ->
_pipe = kryptos_ffi:xdh_export_public_key_pem(Key),
gleam@result:map(
_pipe,
fun(Pem) -> <<(gleam@string:trim_end(Pem))/binary, "\n"/utf8>> end
).
-file("src/kryptos/xdh.gleam", 263).
?DOC(
" Exports an XDH public key to DER format.\n"
"\n"
" The key is exported in SPKI format.\n"
"\n"
" ## Parameters\n"
" - `key`: The public key to export\n"
"\n"
" ## Returns\n"
" `Ok(der_data)` on success, `Error(Nil)` on failure.\n"
).
-spec public_key_to_der(public_key()) -> {ok, bitstring()} | {error, nil}.
public_key_to_der(Key) ->
kryptos_ffi:xdh_export_public_key_der(Key).
-file("src/kryptos/xdh.gleam", 274).
?DOC(
" Derives the public key from an XDH private key.\n"
"\n"
" ## Parameters\n"
" - `key`: The private key\n"
"\n"
" ## Returns\n"
" The corresponding public key.\n"
).
-spec public_key_from_private_key(private_key()) -> public_key().
public_key_from_private_key(Key) ->
kryptos_ffi:xdh_public_key_from_private(Key).
-file("src/kryptos/xdh.gleam", 285).
?DOC(
" Returns the curve for an XDH private key.\n"
"\n"
" ## Parameters\n"
" - `key`: The private key\n"
"\n"
" ## Returns\n"
" The curve used by this key.\n"
).
-spec curve(private_key()) -> curve().
curve(Key) ->
kryptos_ffi:xdh_private_key_curve(Key).
-file("src/kryptos/xdh.gleam", 296).
?DOC(
" Returns the curve for an XDH public key.\n"
"\n"
" ## Parameters\n"
" - `key`: The public key\n"
"\n"
" ## Returns\n"
" The curve used by this key.\n"
).
-spec public_key_curve(public_key()) -> curve().
public_key_curve(Key) ->
kryptos_ffi:xdh_public_key_curve(Key).