Skip to content

Conversation

kayabaNerve
Copy link
Contributor

wasm is a 64-bit architecture with a 32-bit address space. We should be able to use 64-bit words for it without issue. I have not reviewed the u128 codegen to confirm it's non-branching on wasm, yet we already assume u128 codegen is non-branching for 64-bit platforms.

https://users.rust-lang.org/t/are-there-any-negative-implications-of-using-u64-in-wasm32/57419 seems to casually discuss the premise of 64-bit integers within WASM decently.

wasm is a 64-bit architecture with a 32-bit address space. We should be able to
use 64-bit words for it without issue. I have not reviewed the u128 codegen to
confirm it's non-branching on wasm, yet we already assume u128 codegen is
non-branching for 64-bit platforms.
@kayabaNerve
Copy link
Contributor Author

https://godbolt.org/z/bT86GeKnj appears to confirm I used target_family correctly and u128 won't generate wasm which branches.


#[inline]
#[cfg(target_pointer_width = "32")]
#[cfg(all(target_pointer_width = "32", not(target_family = "wasm")))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there's some way to make an alias for that so that we could only spell out this condition once.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also considered it, but I believe it'd require adding a build script to set a cfg for the desired word size. I didn't want to take that step when we have this single exception at this time.

Copy link
Member

@tarcieri tarcieri Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was intending to solve this with the vaporwarecpubits crate (which as it were uses a build script to set a cfg attribute)

RustCrypto/utils#826

Copy link
Member

@tarcieri tarcieri Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to take that step when we have this single exception at this time.

IMO this isn’t worth doing in a way that can’t be applied easily and in a DRY manner for multiple targets.

As noted in RustCrypto/utils#824 this same sort of 64-bit promotion should be applied to ARMv7 targets

@kayabaNerve
Copy link
Contributor Author

Hm. godbolt claims this generates __multi3, which is a LLVM thing, but I don't have the WAT in front of me to confirm LLVM's __multi3 is non-branching on WASM... I'll pull that up.

@kayabaNerve
Copy link
Contributor Author

kayabaNerve commented Oct 6, 2025

For wasm32-unknown-unknown, wasmv1-none, the __multi3 codegen includes i64.lt_u (comparisons) yet no branches. I don't believe the memory access pattern is dependent on the values, but I'm not experienced enough with WAT to confirm this definitely isn't using a value as an index when loading from the stack.

@tarcieri
Copy link
Member

tarcieri commented Oct 6, 2025

This property applies to many targets, not just WASM, and trying to solve it this way is neither DRY nor scalable to many targets.

As I just noted, I had intended to solve this problem with the cpubits crate: RustCrypto/utils#826

@tarcieri
Copy link
Member

tarcieri commented Oct 6, 2025

See also: RustCrypto/utils#824

@tarcieri
Copy link
Member

tarcieri commented Oct 6, 2025

I’ll also note we have downstream crates that consume crypto-bigint and need to gate everything for 32-bit vs 64-bit in an identical manner to crypto-bigint

So really a PR like this also needs a companion PR to e.g. https://github.com/RustCrypto/elliptic-curves which will make clear this already un-DRY approach is impractical.

That’s why I wanted to have one crate in charge of the selection that every other crate can easily consume.

@kayabaNerve
Copy link
Contributor Author

kayabaNerve commented Oct 6, 2025

Ah, apologies. I was unaware of the prior art in those regards. I've just known this is an inefficiency for a while and wanted to finally improve it.

A unified crate to yield this value would definitely be better. Re: elliptic-curves, wouldn't the better solution be to always use crypto_bigint::Word as the primitive type, deferring it to select the optimal candidate? Or is part of the commentary due to how not all curves there premise their backends on crypto-bigint?

Feel free to close this PR if it's unhelpful though.

@tarcieri
Copy link
Member

tarcieri commented Oct 6, 2025

@kayabaNerve in elliptic-curves we need to interact with fiat-crypto synthesized backends which are stored in separate files for the 32-bit vs 64-bit backends, with one file selected to be the backend at compile time.

I do intend to support using MontyFieldElement in the next release, but off-by-default with fiat-crypto as the default backend, at least for the crates which currently use fiat-crypto-synthesized backends

@tarcieri
Copy link
Member

tarcieri commented Oct 6, 2025

Closing this, but if you’d like to help get cpubits to an MVP, that’d be great

@tarcieri tarcieri closed this Oct 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants