Skip to content
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

Attempt to migrate away from bn_mul_mont into Rust #1278

Closed

Conversation

bltavares
Copy link

@bltavares bltavares commented May 4, 2021

As part of the effort to support MIPS, we would need to avoid using bn_mul_mont on C code to avoid needing to add MIPS assembly.
This commit attempts a literal port of the C code into Rust using limbs_mont_mul.

I'm opening it early to collect feedback if this is how we should approach it.

As part of the effort to support MIPS, we would need to avoid using bn_mul_mont on C code to avoid needing to add MIPS assembly.
This commit attempts a literal port of the C code into Rust using limbs_mont_mul.
@bltavares
Copy link
Author

The code currently checks in Rust, but it fails to link as ecp_nitsz384.inl code still refers to elem_mul_mont in C. Does Ring exposes Rust code as C to link back to C files?

@briansmith
Copy link
Owner

Hi, thanks for doing this. You've done almost everything exactly right. Either this weekend or next weekend, I'll experiment with tweaking this to work the way I think it should work, and I'll submit a PR for you to review the changes.

@bltavares
Copy link
Author

Thank you. It's been an learning experience so far - I appreciate the feedback on these changes

@briansmith
Copy link
Owner

For the P-384 stuff, we need to replace the current C code with code that uses the Fiat Crypto P-384 code that BoringSSL also uses. That should solve the remaining blocker. I will do that in a separate PR when I have some time.

@kkovaacs
Copy link

This is now one of the things that is missing for supporting EC algorithms in Webassembly, too.

I tried to find out if I could help with this, but it seems that BoringSSL doesn't use the Fiat Crypto P-384 code: https://boringssl.googlesource.com/boringssl/+/3359/third_party/fiat

@briansmith do you maybe have suggestions how we could move this PR forward?

@Niederb
Copy link

Niederb commented Nov 1, 2022

I'm also interested in this PR. Use case would be to do EC in WebAssembly.
@briansmith Is there something we can do to help out?

Copy link
Owner

@briansmith briansmith left a comment

Choose a reason for hiding this comment

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

Thanks for this PR. I'm very sorry about the long delay in reviewing it. I do absolutely love the idea of replacing gfp_p256.c with Rust code. In order for this approach to work we'd need to do the analogous thing for gfp_p384.c, which is much more tricky. I spent some time today looking into doing that but it looks like it will be a more involved process than I presently have time for this month.

I used this PR as inspiration for #1558, which uses basically the same code in bigint but through the bn_mul_mont interface, unfortunately.

Thanks again.

@@ -66,7 +66,6 @@ include = [
"crypto/fipsmodule/ec/ecp_nistz.h",
"crypto/fipsmodule/ec/ecp_nistz384.h",
"crypto/fipsmodule/ec/ecp_nistz384.inl",
"crypto/fipsmodule/ec/gfp_p256.c",
Copy link
Owner

Choose a reason for hiding this comment

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

\o/

@@ -1166,7 +1166,7 @@ fn greater_than(a: &Nonnegative, b: &Nonnegative) -> bool {

#[derive(Clone)]
#[repr(transparent)]
struct N0([Limb; 2]);
pub(crate) struct N0(pub(crate) [Limb; 2]);
Copy link
Owner

Choose a reason for hiding this comment

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

Instead of making the inner field pub(crate), we should replace the From<u64> for N0 with a const fn from(n0: u64) function so that we can use it instead.

@@ -66,7 +66,7 @@ pub struct CommonOps {
pub b: Elem<R>,

// In all cases, `r`, `a`, and `b` may all alias each other.
elem_mul_mont: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
elem_mul_mont: fn(r: &mut [Limb], a: &[Limb], b: &[Limb]),
Copy link
Owner

Choose a reason for hiding this comment

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

We'll have to leave this as it was so that the P256 implementation can directly call the assembly/C code without any additional overhead.

@@ -240,7 +240,7 @@ pub struct ScalarOps {
pub common: &'static CommonOps,

scalar_inv_to_mont_impl: fn(a: &Scalar) -> Scalar<R>,
scalar_mul_mont: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
scalar_mul_mont: fn(r: &mut [Limb], a: &[Limb], b: &[Limb]),
Copy link
Owner

Choose a reason for hiding this comment

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

Ditto: We'll have to leave this as it was so that the P256 implementation can directly call the assembly/C code without any additional overhead.

for i in 1..rep {
p256_scalar_mul_mont(r, r, r);
}
}
Copy link
Owner

Choose a reason for hiding this comment

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

Doing this would regress the performance on x86-64 and AArch64 targets that have an optimized implementation of this.

@briansmith
Copy link
Owner

Thanks for the contribution. My understanding is that you just wanted to get MIPS and maybe other targets working. They are all working now, so I'm closing this. I appreciate your effort here.

@briansmith briansmith closed this Oct 2, 2023
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.

4 participants