-
Notifications
You must be signed in to change notification settings - Fork 480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Separating backends into their own crates? #287
Comments
Trait aliases only support auto-traits after the + so far (or the last time I checked). Are you sure you need trait aliases? trait A = B + C;
trait A: B + C {}
impl<Q: B + C> A for Q {} |
Unfortunately, I think that this is mostly infeasible, and to the extent that it is, it would not provide a benefit over the existing implementation. First, it is already possible for Second, Cargo does not allow cyclic dependencies, so if a backend is to exist in a separate Third, encapsulating common field arithmetic behaviour into a trait requires a clean abstraction boundary for the trait to encapsulate. But this is not actually how the implementation works, which is why the Finally, it's not desirable in general to have common behaviour for field arithmetic, because the whole stack of optimal implementation choices from the curve model to the hardware capabilities are interlinked, so it's likely that any particular description of methods required for field arithmetic would be a suboptimal choice for a particular set of capabilities, as is already the case for the |
One thing that seems particularly annoying with Rust right now is cross-crate inlining, at least without LTO enabled. Even if LTO solves the problem, for someone trying to write performant crypto, LTO optimizations are a particularly complex and annoying thing to reason about. If you are targeting a performant implementation right now in Rust, it's a pretty big headache to have the relevant performance-oriented code spread across multiple crates. |
@hdevalence The trait lets you break the cycle by putting the consumer in control of selecting the backend. I.e. https://docs.rs/criterion-cycles-per-byte depends on https://docs.rs/criterion but a consumer, who uses both, can use With the trait, you can split AFAICT this would not be a breaking change, as adding an type parameter with a default is identical to the type without it. |
@tarcieri The LTO issue might not be an issue due to the implicit inlining behavior with generics. |
@james-darkfox Algebra is kinda a graveyard for programming language abstractions even at the best of times, but.. ZCash's curve arithmetic has a trait and crate hierarchy already, which includes some Edwards curves like JubJub. I kinda think their traits and curves provide a better playground for work on back ends under cross crate constraints. Also, zcash's trait hierarchy actually serves an important purpose, not just aesthetics, which reduces the available pitfalls. |
Hi, I hate to be annoying, but it's really annoying currently to maintain external backends, and that is only going to get worse over time as we see more backends being produced for more exotic and new instruction sets. I still think having traits to define field/scalar backends, and also having the standard reusable 32-bit and 64-bit scalar backends in a Here's a proposal of tasks that would need to be done to get the ball rolling on this:
And do either these things:
Or:
Additionally:
Further, a bunch of these tasks are likely suitable for a new person with a bit of mentoring, and I'd be happy to supervise the work to make sure it's acceptable. |
FWIW we also have |
@Pratyush link is 404 |
fixed |
As we continue to add backends, it would be handy to have a more modular way to choose which backend is being used and to use a custom backend (e.g. for developers working on hardware that hasn't been publicly released yet) which we might not want to (or be able to) maintain within our crate.
Would it be feasible to create some sort of "backend trait" which describes what methods we expect out of the field arithmetic? And on that note, would it be possible to also separate out the scalar arithmetic so that someone could develop a chip-specific field implementation but reuse the 64-bit serial scalars?
I'm imagining providing a trait that's something like:
Unfortunately that requires the experimental trait aliases feature. I'm not sure if there's a better way to do it?
Thoughts? Opinions?
The text was updated successfully, but these errors were encountered: