Replies: 6 comments 16 replies
-
An idea just now was to rip out all the context switching stuff from core and leave only the Odin implementation. Then move any binding stuff to core:vendor, exposing the original API of the library as well as the API of the Odin crypto lib. That way core would be cleaned up and simplified + you could easily switch between using Odin or a lib by just changing the import. |
Beta Was this translation helpful? Give feedback.
-
For the
For the one-shot calls, I have no strong opinions, as long as they are composed on top of the incremental API, and the context used is properly sanitized. |
Beta Was this translation helpful? Give feedback.
-
If I could get some feedback regarding the MAC/AEAD/DH/stream/utility calls in my branch, I would appreciate it. |
Beta Was this translation helpful? Give feedback.
-
Ok, now that the first round of my primitives are merged, this is my tentative second round plan:
This will bring core/crypto up to feature parity with TweetNaCl, with the following caveat. There are quite a few different ways in which Ed25519 signature verification is implemented in the wild, stemming from implementations that predate standardization efforts, and the RFC leaving "cofactor multiply or not" up to the implementation. My plan is to follow modern "best practices" here, and as far as I know all of the various incompatibilities do not come into play with well-formed signatures (I can go into more detail here if required). Do we want to slim down the number of hash functions present in core/crypto, or is it sufficient to annotate the "not really recommended" ones? I marginally prefer the former just from a maintenance burden standpoint, but the nice things about primitives like these is that it tends to be "get correct once" code. |
Beta Was this translation helpful? Give feedback.
-
I've been thinking about how to best do HMAC + PBKDF2. It could be a little annoying API wise if there are multiple available. It might make sense to split it into different packages. Any thoughts? |
Beta Was this translation helpful? Give feedback.
-
With Apple and likely others to follow, post-quantum stuff is going to start to become more relevant and used. Should we add that to the list? |
Beta Was this translation helpful? Give feedback.
-
As
core:crypto
gets fleshed out, I thought it would be a good idea to come up with a cohesive design/implementation plan.As a warning, I am somewhat opinionated, and a lot of these things are subjective.
Design goals
Have core/crypto be a library that:
Has a unified/consistent API (within reason). Hash functions should expose the same API. ECDH should expose the same API, etc.
Prioritises correctness, readability + maintainability, and performance in descending order of priority.
Nudges users towards making good decisions regarding primitive selection, and ideally guides them towards using higher level constructs rather than lower level ones (eg: Prefer noise/TLS over chacha20poly1305 over chacha20 + poly1305 by hand over ROT13). Primitives that exist for backward compatibility purposes (ie: are not a good choice for new systems) should be annotated as such, or split off into a separate package.
Makes it hard to misuse APIs. For example, if the library provides PBKDF2 the output could be an opaque type, so that the user is inclined to use
compare_hashed_password(expected, digest: ^HashedPassword) -> bool
overmem.compare
. Using strong-typing does wonders here, though there is a balance/trade-off between "safe" and "annoying".Provides primitive implementations that are resistant to at least timing side-channel attacks. As a example, Golang's crypto/aes leaks the key on systems where the CPU or the standard library lacks support for hardware AES. Instead AES should be implemented correctly (bitsliced portable implementation, hardware accelerated per-target fast implementations) or call native code that does it correctly. Not "merge a Te table based implementation anyway". WASM is explicitly out of scope for this requirement due to this being impossible as currently specified.
Makes an effort to sanitize sensitive memory, including intermediaries, to mitigate the impact that bugs that disclose memory can have (
mem.zero_explicit
). How to handle registers and values that get spilled onto the stack is an open question, that I personally would feel is ok to defer for now.No "Hipster Crypto". Exotic things like VRFs, ZK proof systems, pairing friendly curves, etc belongs in external libraries.
Primitives and other functionality
This is a (non-comprehensive) list of low-level primitives that are "a reasonable choice for something new" and or "required to interoperate with something widely deployed", that the library can strive towards. Some of these primitives are implemented already.
Hash functions
eXtendable Output Functions
MAC functions
Digital signatures (hard to implement securely)
Key agreement
Stream ciphers
Block ciphers (and non-authenticated modes)
Authenticated Encryption with Associated Data
Key Derivation Functions and password hashing
Random number generation
These are things that are a "nice to have":
Maybe:
These primitives are "rather not" that might need to be implemented for interoperability:
The primitives were chosen around what is required to implement/interoperate with:
Beta Was this translation helpful? Give feedback.
All reactions