-module(gose@cose@algorithm). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/gose/cose/algorithm.gleam"). -export([signature_alg_to_int/1, signature_alg_from_int/1, mac_alg_to_int/1, mac_alg_from_int/1, signing_alg_to_int/1, signing_alg_from_int/1, key_encryption_alg_to_int/1, key_encryption_alg_from_int/1, content_alg_to_int/1, content_alg_from_int/1]). -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( " COSE algorithm integer ID mapping ([RFC 9053](https://www.rfc-editor.org/rfc/rfc9053.html)).\n" "\n" " Maps between `gose/algorithm` types and COSE integer identifiers.\n" ). -file("src/gose/cose/algorithm.gleam", 11). ?DOC(" Convert a signature algorithm to its COSE integer identifier.\n"). -spec signature_alg_to_int(gose@algorithm:digital_signature_alg()) -> integer(). signature_alg_to_int(Alg) -> case Alg of {ecdsa, ecdsa_p256} -> -7; {ecdsa, ecdsa_p384} -> -35; {ecdsa, ecdsa_p521} -> -36; {ecdsa, ecdsa_secp256k1} -> -47; eddsa -> -8; {rsa_pkcs1, rsa_pkcs1_sha256} -> -257; {rsa_pkcs1, rsa_pkcs1_sha384} -> -258; {rsa_pkcs1, rsa_pkcs1_sha512} -> -259; {rsa_pss, rsa_pss_sha256} -> -37; {rsa_pss, rsa_pss_sha384} -> -38; {rsa_pss, rsa_pss_sha512} -> -39 end. -file("src/gose/cose/algorithm.gleam", 28). ?DOC(" Parse a signature algorithm from its COSE integer identifier.\n"). -spec signature_alg_from_int(integer()) -> {ok, gose@algorithm:digital_signature_alg()} | {error, gose:gose_error()}. signature_alg_from_int(Id) -> case Id of -257 -> {ok, {rsa_pkcs1, rsa_pkcs1_sha256}}; -258 -> {ok, {rsa_pkcs1, rsa_pkcs1_sha384}}; -259 -> {ok, {rsa_pkcs1, rsa_pkcs1_sha512}}; -35 -> {ok, {ecdsa, ecdsa_p384}}; -36 -> {ok, {ecdsa, ecdsa_p521}}; -37 -> {ok, {rsa_pss, rsa_pss_sha256}}; -38 -> {ok, {rsa_pss, rsa_pss_sha384}}; -39 -> {ok, {rsa_pss, rsa_pss_sha512}}; -47 -> {ok, {ecdsa, ecdsa_secp256k1}}; -7 -> {ok, {ecdsa, ecdsa_p256}}; -8 -> {ok, eddsa}; _ -> {error, {parse_error, <<"unknown COSE signature algorithm: "/utf8, (erlang:integer_to_binary(Id))/binary>>}} end. -file("src/gose/cose/algorithm.gleam", 51). ?DOC(" Convert a MAC algorithm to its COSE integer identifier.\n"). -spec mac_alg_to_int(gose@algorithm:mac_alg()) -> integer(). mac_alg_to_int(Alg) -> case Alg of {hmac, hmac_sha256} -> 5; {hmac, hmac_sha384} -> 6; {hmac, hmac_sha512} -> 7 end. -file("src/gose/cose/algorithm.gleam", 60). ?DOC(" Parse a MAC algorithm from its COSE integer identifier.\n"). -spec mac_alg_from_int(integer()) -> {ok, gose@algorithm:mac_alg()} | {error, gose:gose_error()}. mac_alg_from_int(Id) -> case Id of 5 -> {ok, {hmac, hmac_sha256}}; 6 -> {ok, {hmac, hmac_sha384}}; 7 -> {ok, {hmac, hmac_sha512}}; _ -> {error, {parse_error, <<"unknown COSE MAC algorithm: "/utf8, (erlang:integer_to_binary(Id))/binary>>}} end. -file("src/gose/cose/algorithm.gleam", 71). ?DOC(" Convert a signing algorithm to its COSE integer identifier.\n"). -spec signing_alg_to_int(gose@algorithm:signing_alg()) -> integer(). signing_alg_to_int(Alg) -> case Alg of {digital_signature, Sig_alg} -> signature_alg_to_int(Sig_alg); {mac, Mac_alg} -> mac_alg_to_int(Mac_alg) end. -file("src/gose/cose/algorithm.gleam", 79). ?DOC(" Parse a signing algorithm from its COSE integer identifier.\n"). -spec signing_alg_from_int(integer()) -> {ok, gose@algorithm:signing_alg()} | {error, gose:gose_error()}. signing_alg_from_int(Id) -> case signature_alg_from_int(Id) of {ok, Alg} -> {ok, {digital_signature, Alg}}; {error, _} -> case mac_alg_from_int(Id) of {ok, Alg@1} -> {ok, {mac, Alg@1}}; {error, _} -> {error, {parse_error, <<"unknown COSE signing algorithm: "/utf8, (erlang:integer_to_binary(Id))/binary>>}} end end. -file("src/gose/cose/algorithm.gleam", 99). ?DOC( " Convert a key encryption algorithm to its COSE integer identifier.\n" "\n" " Some key encryption algorithms are JOSE-only and have no COSE\n" " identifier, in which case this returns an error.\n" ). -spec key_encryption_alg_to_int(gose@algorithm:key_encryption_alg()) -> {ok, integer()} | {error, gose:gose_error()}. key_encryption_alg_to_int(Alg) -> case Alg of direct -> {ok, -6}; {aes_key_wrap, aes_kw, aes128} -> {ok, -3}; {aes_key_wrap, aes_kw, aes192} -> {ok, -4}; {aes_key_wrap, aes_kw, aes256} -> {ok, -5}; {ecdh_es, ecdh_es_direct} -> {ok, -25}; {ecdh_es, {ecdh_es_aes_kw, aes128}} -> {ok, -29}; {ecdh_es, {ecdh_es_aes_kw, aes192}} -> {ok, -30}; {ecdh_es, {ecdh_es_aes_kw, aes256}} -> {ok, -31}; {rsa_encryption, rsa_oaep_sha1} -> {ok, -40}; {rsa_encryption, rsa_oaep_sha256} -> {ok, -41}; {aes_key_wrap, aes_gcm_kw, _} -> {error, {invalid_state, <<"no COSE identifier for algorithm: "/utf8, (gleam@string:inspect(Alg))/binary>>}}; {cha_cha20_key_wrap, _} -> {error, {invalid_state, <<"no COSE identifier for algorithm: "/utf8, (gleam@string:inspect(Alg))/binary>>}}; {rsa_encryption, rsa_pkcs1v15} -> {error, {invalid_state, <<"no COSE identifier for algorithm: "/utf8, (gleam@string:inspect(Alg))/binary>>}}; {ecdh_es, {ecdh_es_cha_cha20_kw, _}} -> {error, {invalid_state, <<"no COSE identifier for algorithm: "/utf8, (gleam@string:inspect(Alg))/binary>>}}; {pbes2, _} -> {error, {invalid_state, <<"no COSE identifier for algorithm: "/utf8, (gleam@string:inspect(Alg))/binary>>}} end. -file("src/gose/cose/algorithm.gleam", 132). ?DOC( " Parse a key encryption algorithm from its COSE integer identifier.\n" "\n" " Both ECDH-ES+HKDF-256 (-25) and ECDH-ES+HKDF-512 (-26) map to\n" " `EcdhEs(EcdhEsDirect)` because the shared algorithm type does not\n" " distinguish the HKDF variant. The HKDF variant is preserved at the\n" " `cose/encrypt` layer via `EcdhEsDirectVariant`. Use\n" " `new_ecdh_es_direct_recipient` and `ecdh_es_direct_decryptor` for\n" " HKDF-512 support.\n" ). -spec key_encryption_alg_from_int(integer()) -> {ok, gose@algorithm:key_encryption_alg()} | {error, gose:gose_error()}. key_encryption_alg_from_int(Id) -> case Id of -25 -> {ok, {ecdh_es, ecdh_es_direct}}; -26 -> {ok, {ecdh_es, ecdh_es_direct}}; -29 -> {ok, {ecdh_es, {ecdh_es_aes_kw, aes128}}}; -3 -> {ok, {aes_key_wrap, aes_kw, aes128}}; -30 -> {ok, {ecdh_es, {ecdh_es_aes_kw, aes192}}}; -31 -> {ok, {ecdh_es, {ecdh_es_aes_kw, aes256}}}; -4 -> {ok, {aes_key_wrap, aes_kw, aes192}}; -5 -> {ok, {aes_key_wrap, aes_kw, aes256}}; -6 -> {ok, direct}; -40 -> {ok, {rsa_encryption, rsa_oaep_sha1}}; -41 -> {ok, {rsa_encryption, rsa_oaep_sha256}}; _ -> {error, {parse_error, <<"unknown COSE key encryption algorithm: "/utf8, (erlang:integer_to_binary(Id))/binary>>}} end. -file("src/gose/cose/algorithm.gleam", 157). ?DOC( " Convert a content encryption algorithm to its COSE integer identifier.\n" "\n" " Some content encryption algorithms are JOSE-only and have no COSE\n" " identifier, in which case this returns an error.\n" ). -spec content_alg_to_int(gose@algorithm:content_alg()) -> {ok, integer()} | {error, gose:gose_error()}. content_alg_to_int(Alg) -> case Alg of {aes_gcm, aes128} -> {ok, 1}; {aes_gcm, aes192} -> {ok, 2}; {aes_gcm, aes256} -> {ok, 3}; cha_cha20_poly1305 -> {ok, 24}; {aes_cbc_hmac, _} -> {error, {invalid_state, <<"no COSE identifier for algorithm: "/utf8, (gleam@string:inspect(Alg))/binary>>}}; x_cha_cha20_poly1305 -> {error, {invalid_state, <<"no COSE identifier for algorithm: "/utf8, (gleam@string:inspect(Alg))/binary>>}} end. -file("src/gose/cose/algorithm.gleam", 173). ?DOC(" Parse a content encryption algorithm from its COSE integer identifier.\n"). -spec content_alg_from_int(integer()) -> {ok, gose@algorithm:content_alg()} | {error, gose:gose_error()}. content_alg_from_int(Id) -> case Id of 1 -> {ok, {aes_gcm, aes128}}; 2 -> {ok, {aes_gcm, aes192}}; 3 -> {ok, {aes_gcm, aes256}}; 24 -> {ok, cha_cha20_poly1305}; _ -> {error, {parse_error, <<"unknown COSE content encryption algorithm: "/utf8, (erlang:integer_to_binary(Id))/binary>>}} end.