Ideally this would be done in stages. I suggest the following stages:
[ ] Replace the p384_point_mul and nistz384_point_mul C functions with Rust code that calls into the C nistz384_point_add and nistz384_point_double, p384_point_select_w5, etc. functions. Additionally, anything that is doing bit-twiddling like the calculation of wvalue, booth_recode, p384_point_select_w5 should stay in C and the Rust code should call into it. If this ends up causing perf issues (I doubt it), then we can reassess.
[ ] Replace nistz384_point_double with the Rust equivalent.
[ ] Replace nistz384_point_add with the Rust equivalent, leaving the constant-time primitives like is_zero, copy_conditional, and the calculation of is_exceptional, and the field element arithmetic in C. Instead of transliterating nistz384_point_add from C to Rust, we should use the branch-free point addition algorithm that BoringSSL uses. The BoringSSL algorithm has fewer field arithmetic operations to implement and those primitives would be easier to re-implement in Rust.
[ ] To start with, the Rust field arithmetic operations (elem_mul_mont, elem_sub, elem_mul_by_2) should be wrappers around the current C implementations based on limbs.{.c,.inl,.h}. When elem_mul_mont is moved to Rust, then the prefixed_export! can be removed, since we'll no longer have C code calling the Rust implementation of bn_mul_mont.
The above is written specifically for P-384, but the same should be done for P-521. Whoever takes this on should describe how they plan to share code (generically or otherwise) between P-384 and P-521.
A future project will replace the limbs.* implementation with an all-Rust implementation, after we've developed more infrastructure to preventing timing side channels and detecting timing side channels in CI for proposed changes. I will link that when it is spec'd out.
Ideally this would be done in stages. I suggest the following stages:
is_zero
, copy_conditional, and the calculation ofis_exceptional
, and the field element arithmetic in C. Instead of transliterating nistz384_point_add from C to Rust, we should use the branch-free point addition algorithm that BoringSSL uses. The BoringSSL algorithm has fewer field arithmetic operations to implement and those primitives would be easier to re-implement in Rust.prefixed_export!
can be removed, since we'll no longer have C code calling the Rust implementation ofbn_mul_mont
.The above is written specifically for P-384, but the same should be done for P-521. Whoever takes this on should describe how they plan to share code (generically or otherwise) between P-384 and P-521.
A future project will replace the limbs.* implementation with an all-Rust implementation, after we've developed more infrastructure to preventing timing side channels and detecting timing side channels in CI for proposed changes. I will link that when it is spec'd out.