gleam-lang / crypto

⛓️ Crypto functionality for Gleam applications
https://hexdocs.pm/gleam_crypto/
Apache License 2.0
35 stars 11 forks source link

Decouple hash algorithms from sign algorithms #12

Open NorbertSzydlik opened 1 week ago

NorbertSzydlik commented 1 week ago

Functions hash, new_hasher, hmac and sign_message all use HashAlgorithm to define which algorithm to use.

I tried adding new hash algorithms supported by Erlang and Node.js. I stumbled on problem with sign_message. It seems that this function implements creation of JSON Web Token (RFC-7519, https://datatracker.ietf.org/doc/html/rfc7519). It uses "alg" field to define which Message Authentication Code algorithm was used to sign the message. I could not find definition for SHA3-X algorithm family in docs (RFC-7518, https://datatracker.ietf.org/doc/html/rfc7518). Additionally, if someone wanted to implement non hash-based message authentication codes (HMAC) it would be impossible to do so with current state. It is because MAC algorithms like ES256 (ECDSA using P-256 and SHA-256) are not hash based, so algorithm definition for it would make no sense for functions like hash.

My proposal is to move hash functions, hmac functions and sign_message to separate submodules: hash, mac and jwt respectively. By doing so you will have nice separation of concerns. It will also prevent collisions between algorithm names. Sha256 can mean something different for the hash, module, as it refers to a cryptographic hash function, whereas in the mac module, it may represent the hashing algorithm used to generate a Message Authentication Code (MAC). By doing so you could also work on different domains of cryptography without affecting other ones.

My other, less involved proposal is to define separate types for MAC and JWT algorithms. It will also allow to work separately on different types of algorithms. However it will not provide separation of concerns found in Erlang and in Node.

Both my proposals will introduce breaking changes, so I wanted to first discuss them here.

lpil commented 1 week ago

There is no desire to support JWT with this package. I actually want to discourage their use wherever possible so it would be counter-productive to have any support for them in core libraries.

NorbertSzydlik commented 4 days ago

That's great and I agree with the direction. I wanted to add SHA3 to hash function and I don't know how can I proceed with current implementation. It would be great to share the implementation, how can I do it?

lpil commented 4 days ago

Sorry, I'm getting confused and not understanding the issue. Why wouldn't you implement SHA3 for both hash and hmac?