jchambers / java-otp

A one-time password (HOTP/TOTP) library for Java
MIT License
455 stars 122 forks source link

Avoid synchronization by cloning a prototype `Mac` and reallocating buffers #42

Closed jchambers closed 2 years ago

jchambers commented 2 years ago

I've been thinking back on the conversation in #34, and I think I've found a best-of-both-worlds approach. To recap, the suggestion in #34 was to allocate a new buffer and instantiate a new Mac on each call to generateOneTimePassword to avoid synchronization, leading to higher throughput. The problem was that instantiating a new Mac was pretty slow.

It turns out that cloning a Mac is actually pretty fast, though! We can't guarantee that cloning a Mac will be possible in all setups—some provider might have a non-cloneable HmacSHA512 implementation, for example—but it'll probably be true in most setups. This lets us make generateOneTimePassword non-synchronized while still retaining thread safety, which seems like a win.

This may come at the cost of a modest throughput decrease in the single-threaded case, but if it does, it's on the order of 1%, and I'd say that's a worthwhile price to pay.