briansmith / ring

Safe, fast, small crypto using Rust
Other
3.75k stars 708 forks source link

Expose common crypto primitives API #359

Closed kcchu closed 7 years ago

kcchu commented 7 years ago

The current API of Ring is opinionated that it makes design choices for users about how the cryptographic primitives should be used. It is not a bad thing for a crypto API to be opinionated. After all, the subtleties of cryptography bit us too many times. It is great for an utility API to be secure-by-default. However, the current API is quite limiting when it is used as a building block for a larger cryptographic protocol that need to be interoperate with other implementations. Say, the ECDH functions can't be used with static key (#331). It may make sense to expose common primitives like BN, prime-field and elliptic curve operations, constant-time comparison, etc as an API to allow developers maximum flexibility. These subtle API can be grouped into a module that is labeled clearly as low level primitives, and perhaps disabled with a feature flag.

briansmith commented 7 years ago

Say, the ECDH functions can't be used with static key (#331).

This is just a matter of implementing the missing functionality, right? Anybody can submit a PR to fix #331 and then static keys will work.

It may make sense to expose common primitives like BN, prime-field and elliptic curve operations, constant-time comparison, etc as an API to allow developers maximum flexibility. These subtle API can be grouped into a module that is labeled clearly as low level primitives, and perhaps disabled with a feature flag.

We have such APIs and will have more such APIs, but they will stay internal to ring for the foreseeable future.

The ring API is designed based on use cases from real-world applications. If you have an application that needs functionality that is missing in ring then please file issues for the missing functionality and we'll figure out if/how to accommodate the application.

kcchu commented 7 years ago

I want to argue that many applications of cryptography are too uncommon to be included in a high-level crypto API, yet they could benefit from a good crypto primitives library. Examples that came to mind include Bitcoin's HD Wallets and blind signature schemes. They are definitely not everyday crypto usages but they exist in "real-world" software. It is of course possible to abstract and include them as an API in ring, but doing so would easily become feature creep and defeat the goal of writing a safe and small crypto library. These kind of applications need a secure, well-tested and fast implementation of various primitives. I think ring could fill this void in Rust.

NaCl is a good example of being a foolproof crypto library (the box/secretbox functions), and at the same time provides low-level functions like curve25519 scalar multiplication for people who need to shoot their feet. I think these two goals are not contradicting and a thoughtfully designed crypto library should achieve both.

briansmith commented 7 years ago

Examples that came to mind include Bitcoin's HD Wallets and blind signature schemes.

For the time-being I've decided not to punt on cryptocurrency stuff. Bitcoin is probably the most conservative and it still uses the secp256k1 curve, for which we don't have any implementation.

It is of course possible to abstract and include them as an API in ring, but doing so would easily become feature creep and defeat the goal of writing a safe and small crypto library.

So far, I've avoided feature creep by asking people who ask for features to commit to using ring for a specific application or library that needs the feature, before I commit to adding the feature. This way, we get assurance that there will be at least one serious user of every feature. So far this has been a good filter as it has not excluded any ring users but it has avoided the adding of any unused features.

As far as “safe” goes, I agree that that there is some tension between breadth and safety since the more features there are, the more work it is to ensure they are all safe. However, I worry that it will be hard for us to maintain a low-level API at the same level of safety as the rest of ring, and so I'm speculating that it might be easier to maintain a wider breadth of high-level features.

As far as “small” goes, “small” in the description of ring refers to its (intended) impact on the size of the application using it, not on the breadth of the ring API. However, adding a low-level API like you are requesting would also increase the breadth of ring. Therefore, I don't think that adding a low-level API is a clear net benefit over the current approach as far as the “small” goal is concerned.

Also, we (I) want to encourage people using ring to work together, and I think a good way of ensuring that is to encourage people to add extensions to ring to ring itself, rather than bolting extensions onto the top of ring. Again, this is conjecture on my part, but it is a social experiment that's in progress.

NaCl is a good example of being a foolproof crypto library (the box/secretbox functions), and at the same time provides low-level functions like curve25519 scalar multiplication for people who need to shoot their feet.

We are aiming much higher than NaCl as far as usability and foolproofing is concerned. NaCl has pioneered many great features in API and algorithm design, but it also left much room for improvement.

briansmith commented 7 years ago

OK, I'm going to close this. I appreciate the feature request. It just happens to be contrary to what we're doing now. Let's revisit this some time next year.