Open jessa0 opened 2 years ago
One thing to note about adding AsyncCipher
, AsyncDh
, and AsyncHash
traits is that, unless we add a R: CryptoResolver
generic parameter to snow
's structs instead of storing a trait object (which is required to have all associated types specified), we have to return Pin<Box<dyn Future>>
from any async trait methods, which would add an allocation and deallocation to every crypto operation.
I've been starting to think about how to add support for async crypto engines to
snow
(like crypto coprocessors, or in my case, the Web Crypto API). The Web Crypto API is particularly difficult to work with together withsnow
, as one cannot simply spawn another thread to drivesnow
synchronously since thewasm32-unknown-unknown
target doesn't support threading, and Web Workers are a pain to work with.Adding this support seems difficult to do cleanly in a DRY way, as every function in
snow
which uses cryptography (which is a lot of them) would need to be madeasync
, andawait
s added appropriately. In fact, most of whatsnow
's code does is drive crypto, so having separate copy-paste implementations for a separate async API, for example, would make maintenance pretty painful and error-prone.Another technique I've seen for supporting both sync and async APIs is using macros like in the
redis
crate, but personally heavy use of macros is something I'd want to avoid. One good takeaway from theredis
API, however, is thatsnow
could add an optional async API by havingHandshakeState
/TransportState
implement newAsyncHandshake
/AsyncTransport
traits which the user can choose touse
if desired.Another technique found in the
mongodb
crate is to write the implementation usingasync
/await
and have the sync API use some implementation of theblock_on
function from one of the async runtimes to wait on theFuture
s returned from the async implementation. Insnow
's case, assuming theCryptoResolver
trait were made to returnFuture
s,block_on
could be added to the trait as well so that, if it knows that it returns all synchronous crypto implementations, itsblock_on
implementation could be as dead simple as polling aFuture
once usingnoop_waker
.I'm still looking into more techniques for supporting parallel sync & async APIs, but I'd love to hear thoughts on whether any of this seems worthwhile / viable to support in
snow
.