Packages

Cryptography library for Gleam targeting Erlang and JavaScript

Current section

Files

Jump to
kryptos src kryptos@ec.erl
Raw

src/kryptos@ec.erl

-module(kryptos@ec).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/kryptos/ec.gleam").
-export([coordinate_size/1, generate_key_pair/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_from_raw_point/2, public_key_to_raw_point/1, public_key_to_pem/1, public_key_to_der/1, public_key_from_private_key/1, curve/1, public_key_curve/1, to_bytes/1, from_bytes/2]).
-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(
" Elliptic Curve Cryptography key generation and management.\n"
"\n"
" Key pair generation and management for elliptic curve cryptography,\n"
" supporting standard NIST curves and secp256k1. EC keys can be used for\n"
" both ECDSA signatures and ECDH key agreement.\n"
"\n"
" ## Key Generation\n"
"\n"
" ```gleam\n"
" import kryptos/ec\n"
"\n"
" let #(private_key, public_key) = ec.generate_key_pair(ec.P256)\n"
" ```\n"
"\n"
" ## Import/Export\n"
"\n"
" ```gleam\n"
" import kryptos/ec\n"
"\n"
" let #(private_key, _public_key) = ec.generate_key_pair(ec.P256)\n"
" let assert Ok(pem) = ec.to_pem(private_key)\n"
" let assert Ok(#(imported_private, _)) = ec.from_pem(pem)\n"
" ```\n"
).
-type private_key() :: any().
-type public_key() :: any().
-type curve() :: p256 | p384 | p521 | secp256k1.
-file("src/kryptos/ec.gleam", 49).
?DOC(
" Returns the coordinate size in bytes for the given curve.\n"
"\n"
" This is the size of each coordinate (x or y) in an EC point.\n"
).
-spec coordinate_size(curve()) -> integer().
coordinate_size(Curve) ->
case Curve of
p256 ->
32;
secp256k1 ->
32;
p384 ->
48;
p521 ->
66
end.
-file("src/kryptos/ec.gleam", 60).
?DOC(" Generates a new elliptic curve key pair.\n").
-spec generate_key_pair(curve()) -> {private_key(), public_key()}.
generate_key_pair(Curve) ->
kryptos_ffi:ec_generate_key_pair(Curve).
-file("src/kryptos/ec.gleam", 67).
?DOC(
" Imports an EC private key from PEM-encoded data.\n"
"\n"
" The key must be in PKCS#8 format.\n"
).
-spec from_pem(binary()) -> {ok, {private_key(), public_key()}} | {error, nil}.
from_pem(Pem) ->
kryptos_ffi:ec_import_private_key_pem(Pem).
-file("src/kryptos/ec.gleam", 74).
?DOC(
" Imports an EC private key from DER-encoded data.\n"
"\n"
" The key must be in PKCS#8 format.\n"
).
-spec from_der(bitstring()) -> {ok, {private_key(), public_key()}} |
{error, nil}.
from_der(Der) ->
kryptos_ffi:ec_import_private_key_der(Der).
-file("src/kryptos/ec.gleam", 79).
?DOC(
" Exports an EC private key to PEM format.\n"
"\n"
" The key is exported in PKCS#8 format.\n"
).
-spec to_pem(private_key()) -> {ok, binary()} | {error, nil}.
to_pem(Key) ->
_pipe = kryptos_ffi:ec_export_private_key_pem(Key),
gleam@result:map(
_pipe,
fun(Pem) -> <<(gleam@string:trim_end(Pem))/binary, "\n"/utf8>> end
).
-file("src/kryptos/ec.gleam", 92).
?DOC(
" Exports an EC private key to DER format.\n"
"\n"
" The key is exported in PKCS#8 format.\n"
).
-spec to_der(private_key()) -> {ok, bitstring()} | {error, nil}.
to_der(Key) ->
kryptos_ffi:ec_export_private_key_der(Key).
-file("src/kryptos/ec.gleam", 99).
?DOC(
" Imports an EC public key from PEM-encoded data.\n"
"\n"
" The key must be in SPKI format.\n"
).
-spec public_key_from_pem(binary()) -> {ok, public_key()} | {error, nil}.
public_key_from_pem(Pem) ->
kryptos_ffi:ec_import_public_key_pem(Pem).
-file("src/kryptos/ec.gleam", 106).
?DOC(
" Imports an EC public key from DER-encoded data.\n"
"\n"
" The key must be in SPKI format.\n"
).
-spec public_key_from_der(bitstring()) -> {ok, public_key()} | {error, nil}.
public_key_from_der(Der) ->
kryptos_ffi:ec_import_public_key_der(Der).
-file("src/kryptos/ec.gleam", 124).
?DOC(
" Imports an EC public key from an uncompressed SEC1 point.\n"
"\n"
" The point must be in uncompressed format: `0x04 || x || y`\n"
" where x and y are the coordinates padded to the curve's coordinate size.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import kryptos/ec\n"
"\n"
" let #(_private_key, public_key) = ec.generate_key_pair(ec.P256)\n"
" let point = ec.public_key_to_raw_point(public_key)\n"
" let assert Ok(imported) = ec.public_key_from_raw_point(ec.P256, point)\n"
" ```\n"
).
-spec public_key_from_raw_point(curve(), bitstring()) -> {ok, public_key()} |
{error, nil}.
public_key_from_raw_point(Curve, Point) ->
kryptos_ffi:ec_public_key_from_raw_point(Curve, Point).
-file("src/kryptos/ec.gleam", 141).
?DOC(
" Exports a public key to uncompressed SEC1 point format.\n"
"\n"
" Returns a BitArray in the format: `0x04 || X || Y` where X and Y are\n"
" the coordinates of the public key point, each padded to the curve's\n"
" coordinate size.\n"
"\n"
" If the key was imported with a compressed point format, it will be\n"
" automatically decompressed.\n"
"\n"
" This is the inverse of `public_key_from_raw_point`.\n"
).
-spec public_key_to_raw_point(public_key()) -> bitstring().
public_key_to_raw_point(Key) ->
kryptos_ffi:ec_public_key_to_raw_point(Key).
-file("src/kryptos/ec.gleam", 146).
?DOC(
" Exports an EC public key to PEM format.\n"
"\n"
" The key is exported in SPKI format.\n"
).
-spec public_key_to_pem(public_key()) -> {ok, binary()} | {error, nil}.
public_key_to_pem(Key) ->
_pipe = kryptos_ffi:ec_export_public_key_pem(Key),
gleam@result:map(
_pipe,
fun(Pem) -> <<(gleam@string:trim_end(Pem))/binary, "\n"/utf8>> end
).
-file("src/kryptos/ec.gleam", 160).
?DOC(
" Exports an EC public key to DER format.\n"
"\n"
" The key is exported in SPKI format.\n"
).
-spec public_key_to_der(public_key()) -> {ok, bitstring()} | {error, nil}.
public_key_to_der(Key) ->
kryptos_ffi:ec_export_public_key_der(Key).
-file("src/kryptos/ec.gleam", 165).
?DOC(" Derives the public key from an EC private key.\n").
-spec public_key_from_private_key(private_key()) -> public_key().
public_key_from_private_key(Key) ->
kryptos_ffi:ec_public_key_from_private(Key).
-file("src/kryptos/ec.gleam", 170).
?DOC(" Returns the curve for an EC private key.\n").
-spec curve(private_key()) -> curve().
curve(Key) ->
kryptos_ffi:ec_private_key_curve(Key).
-file("src/kryptos/ec.gleam", 175).
?DOC(" Returns the curve for an EC public key.\n").
-spec public_key_curve(public_key()) -> curve().
public_key_curve(Key) ->
kryptos_ffi:ec_public_key_curve(Key).
-file("src/kryptos/ec.gleam", 192).
?DOC(
" Exports an EC private key to raw scalar bytes.\n"
"\n"
" Returns the private scalar (the \"d\" value in JWK terminology) as\n"
" big-endian bytes. The size matches the curve's coordinate size.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import kryptos/ec\n"
"\n"
" let #(private_key, _public_key) = ec.generate_key_pair(ec.P256)\n"
" let scalar = ec.to_bytes(private_key)\n"
" ```\n"
).
-spec to_bytes(private_key()) -> bitstring().
to_bytes(Key) ->
kryptos_ffi:ec_private_key_to_bytes(Key).
-file("src/kryptos/ec.gleam", 211).
?DOC(
" Imports an EC private key from raw scalar bytes.\n"
"\n"
" The scalar should be in big-endian format with size matching the\n"
" curve's coordinate size (32 bytes for P256/Secp256k1, 48 for P384,\n"
" 66 for P521).\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" import kryptos/ec\n"
"\n"
" let #(private_key, _public_key) = ec.generate_key_pair(ec.P256)\n"
" let scalar = ec.to_bytes(private_key)\n"
" let assert Ok(#(imported, _pub)) = ec.from_bytes(ec.P256, scalar)\n"
" ```\n"
).
-spec from_bytes(curve(), bitstring()) -> {ok, {private_key(), public_key()}} |
{error, nil}.
from_bytes(Curve, Private_bytes) ->
kryptos_ffi:ec_private_key_from_bytes(Curve, Private_bytes).