fiat-crypto
fiat-crypto copied to clipboard
Can we generate genuine 64-bit code for Java?
Java has neither unsigned types nor uint128. Currently, we are generating 32-bit-targeted code for Java, but if I understand correctly, all of the operations (+
, -
, *
, <<
, >>>
, &
, |
) commute with modulo/casting, so I think we should just be able to use signed integers as if they were unsigned, and use wrap-around behavior. Presumably if we do this the pass inserting the casts for this should be verified.
cc @andres-erbsen @peterdettman @dghgit for thoughts / sanity-checking on this strategy.
I think the main question is how to get the high part of a 64-by-64 multiplication. Does Java have int128?
Ah, right, yeah, Java has neither int128 nor mulx. So I guess the alternative to using 32-bit synthesis is to do the same thing we're doing for bedrock2
Java 9 has Math.multiplyHigh
(also Math.multiplyFull
) which I assume gets JITed to the sensible thing, though it's all signed integers and (a - 2^64) * (b - 2^64) != a * b mod (2^128). (Maybe you can fix it at the cost of a couple conditional additions? Or limit it to unsaturated limbs?)
I'm not familiar enough with the Java ecosystem to know whether requiring Java 9 is a reasonable baseline these days.
what we do for bedrock2 is mulHigh.
Ooh, neat! I can hopefully use that.