abstractj/kalium

BLAKE2b default digest length: 32 or 64?

Closed this issue · 12 comments

lvh commented

src/libsodium/include/sodium/crypto_generichash_blake2b.h, line 46:

#define crypto_generichash_blake2b_BYTES         32U

org.abstractj.kalium/NaCl line #80:

 public static final int BLAKE2B_OUTBYTES = 64;

Is that intentional?

IIRC Blake2B can produce anywhere between 16 and 64 byte outputs depending on the needs. Libsodium documentation states

The minimum recommended output size is crypto_generichash_BYTES. This size makes it practically impossible for two messages to produce the same fingerprint.

But for specific use cases, the size can be any value between crypto_generichash_BYTES_MIN (included) and crypto_generichash_BYTES_MAX (included).

With BYTES = 32, MIN = 16, and MAX = 64. I imagine the original PR that added blake2b choose the largest size to expose for Kalium. I've fixed this and made it identical to Libsodium on my branch which I'm working towards primary API completeness with Libsodium.

lvh commented

You are correct re: BLAKE2b's output sizes :) However; BLAKE2b is pretty clear that the default is 32 bytes (as you pointed out); so I don't think it's reasonable for Kalium to do something else by default. Thanks for fixing it in that other branch!

(On a related note: have you considered jnr-ffi pinning? I'm using it now when porting kalium to bind directly, and it seems to work like a charm :))

Somehow I've missed jnr-ffi's Pinned annotation, if I understand, it basically accomplishes the same as using a Direct ByteBuffer as suggested in #21. We won't be copying between java and native.

lvh commented

They're related; yes, the difference being that one only works at call time and the other changes where the object is allocated. When you say won't, does that mean "when #21 is closed", or currently?

lvh commented

(FYI, this is why I'm currently porting caesium to bind to libsodium directly. That, and that creating objects to throw them away feels a little weird. And I wanted to be able to bind new functions faster than waiting for a release. So perhaps those bindings in caesium can help you if you're trying to get pinning to work :))

Ah, yea I wasn't very clear. By using either the Pinned annotation or a Direct ByteBuffer we can avoid copying byte arrays. My reference to #21 was just regarding the first bullet point.

lvh commented

Right. The API design I'm using in caesium right now lets you use byte arrays directly or it will create them for you, so you can get actual zerocopy, instead of just zerocopy during the ffi call.

@lvh @bendoerr let me know if this change makes sense to you #56 please.

@abstractj are you concerned about backwards compatibility? Doesn't 24e9948 breaks hash checks for anyone verifying previously generated hashes using BLAKE2B_OUTBYTES?

@bendoerr indeed, but that would be manageable with semver, nope? Another alternative would be provide break backwards compatibility and provide a way for people the output size desired. Makes sense?

Indeed, just wanted to call it out.

@bendoerr @lvh thanks a lot, very appreciated.

Will do the merge.