-
Notifications
You must be signed in to change notification settings - Fork 705
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
[WIP]: Rsa keygen #733
[WIP]: Rsa keygen #733
Conversation
c6005ff
to
9cd2288
Compare
src/rsa/key_generation.rs
Outdated
for _ in 1 .. a { | ||
// Step 4.5.1 | ||
// TODO figure out how to make this compile | ||
//z_elem = bigint::elem_squared(z_elem, &w_modulus.as_partial()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@briansmith do you know how this can be made compile? Right now I'm getting sth like:
--> src/rsa/key_generation.rs:87:22
|
87 | z_elem = bigint::elem_squared(z_elem, &w_modulus.as_partial());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `arithmetic::montgomery::Unencoded`, found enum `arithmetic::montgomery::RInverse`
|
= note: expected type `rsa::bigint::Elem<_, arithmetic::montgomery::Unencoded>`
found type `rsa::bigint::Elem<_, arithmetic::montgomery::RInverse>`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now: multiply z_elem
by w_modulus.oneRR
before the loop.
Later: Refactor elem_exp_consttime
so that it returns an Elem<R>
instead of Elem<Unencoded>
by moving the into_unencoded()
to the caller.
* The licence and distribution terms for any publically available version or | ||
* derivative of this code cannot be changed. i.e. this code cannot simply be | ||
* copied and put under another distribution licence | ||
* [including the GNU Public Licence.] */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a commit that removes all the code from this file, and the other new imported files, that you didn't use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it okay if I do that once I'm done with the PR? Don't know what else will be needed from the files :).
crypto/internal.h
Outdated
@@ -370,4 +368,20 @@ static inline uint64_t from_be_u64(uint64_t x) { | |||
return x; | |||
} | |||
|
|||
static inline void *OPENSSL_memmove(void *dst, const void *src, size_t n) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everywhere you see OPENSSL_memmove
and OPENSSL_memset
being used, just use memmove
and memset
.
crypto/limbs/limbs.c
Outdated
@@ -99,6 +99,11 @@ Limb LIMBS_less_than_limb(const Limb a[], Limb b, size_t num_limbs) { | |||
return constant_time_select_w(lo, hi, lo); | |||
} | |||
|
|||
void LIMBS_sub_limb(Limb r[], const Limb a[], const Limb b, | |||
size_t num_limbs) { | |||
limbs_sub_limb(r, a, b, num_limbs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace this with
void LIMBS_odd_sub_one(Limb r[], size_t num_limbs) {
assert(num_limbs > 0);
assert(!LIMBS_are_even(r, num_limbs));
r[0] &= ~1;
}
src/limb.rs
Outdated
} | ||
|
||
#[cfg(feature = "rsa_keygen")] | ||
pub fn limbs_copy(r: &mut [Limb], a: &[Limb]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do the copying in pure Rust code. (In ring, we can copy secret values from one place to another in Rust, we just don't do any arithmetic in Rust get.)
src/limb.rs
Outdated
|
||
|
||
#[cfg(feature = "rsa_keygen")] | ||
pub fn limbs_rshift(r: &mut [Limb], n: u16) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should have secret_shift
in the name.
src/rsa/bigint.rs
Outdated
@@ -67,7 +67,7 @@ struct Width<M> { | |||
} | |||
|
|||
/// All `BoxedLimbs<M>` are stored in the same number of limbs. | |||
struct BoxedLimbs<M> { | |||
pub struct BoxedLimbs<M> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make the primality test code a submodule of bigint
so that we don't need to increase the visibility of things in bigint
.
src/rsa/key_generation.rs
Outdated
@@ -0,0 +1,147 @@ | |||
// Copyright 2018 Brian Smith. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you copied some of my code, please keep this copyright line. Please add your own copyright line.
src/rsa/key_generation.rs
Outdated
/// Implementation of the algorithm as it | ||
/// is described in FIPS 186-4 C.3.1 | ||
fn miller_rabin_test( | ||
w: &[u64], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have written this whole thing in terms of Limb
but it would be a lot clearer to write it in terms of bigint::Nonnegative
, I think.
src/rsa/key_generation.rs
Outdated
// Step 1. | ||
let mut w_m1 = vec![0; w.len()]; | ||
limb::limbs_sub_limb(&mut w_m1, w, 1); | ||
let a = limb::limbs_count_low_zero_bits(&w_m1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// for w: &Nonnegative
let w_minus_1 = w.odd_minus_1()?;
let a = w.trailing_zeros();
src/rsa/key_generation.rs
Outdated
// preparation | ||
let boxed_w = bigint::BoxedLimbs::<()>::minimal_width_from_unpadded(&w); | ||
let w_modulus = bigint::Modulus::from_boxed_limbs(boxed_w)?.0; | ||
let boxed_m = bigint::BoxedLimbs::<()>::minimal_width_from_unpadded(&m); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see Modulus::from_nonnegative_with_bit_length()
.
src/rsa/key_generation.rs
Outdated
unsafe { | ||
let b_mut_ptr = (&mut b[..]).as_mut_ptr() as * mut u8; | ||
let b_mut_slice = core::slice::from_raw_parts_mut(b_mut_ptr, b.len() * 8); | ||
rng.fill(b_mut_slice)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be factored out into a impl Elem { fn random(rng: &SecureRandom) -> Result<Self, error::Unspecified> }
method.
src/rsa/key_generation.rs
Outdated
// TODO figure out how to make this compile | ||
//z_elem = bigint::elem_squared(z_elem, &w_modulus.as_partial()); | ||
// Step 4.5.2 | ||
if limb::limbs_equal_limbs_consttime(&z_elem.limbs, &w_m1) == LimbMask::True { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You will need to convert w_m1
to an Elem<W>
and then use the Elem
comparison functions.
src/rsa/key_generation.rs
Outdated
continue; | ||
} | ||
// Step 4.5.1 | ||
if z_elem.is_one() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You will need to create a value oneR: Elem<W, R>
with value 1 * w_modulus.oneRR
and then compare using the element comparison functions.
src/rsa/key_generation.rs
Outdated
/// | ||
/// Implementation of the algorithm as it | ||
/// is described in FIPS 186-4 C.3.1 | ||
fn miller_rabin_test( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this function's type should be something like like fn miller_rabin_test<M: Prime>(w: Nonnegative, iterations: u32, rng: &SecureRandom) -> Result<Modulus<M>, error::Unspecified>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should the returned modulus contain? Will we need that value somewhere? To me it seems that only bool yes/no output is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should the returned modulus contain? Will we need that value somewhere? To me it seems that only bool yes/no output is needed.
At least, for example, we need to calculate q**-1 (mod p)
to construct the RSA key. IIUC, this function already constructs the Modulus
for the prime so we might as well return it. OTOH, if the function doesn't end up constructing the Modulus
already then we can just return a ()
.
OK, I can see now that this is going to be a lot of work from both of us. Before we do any more work, let's clarify the IPR part:
|
In order for me to effectively review this code, we need to refactor it into at least two parts: low-level routines and high-level routines. The M-R test itself should be a high-level routine that takes a Anything that deals with |
f4a92ba
to
6e0cdf1
Compare
Ready again for review @briansmith . |
34aa5c3
to
97f3c18
Compare
Rebased. ATM blocked on getting advice: #219 (comment) |
I agree to license my contributions to each file under the terms given at the top of each file I changed.
I agree to license my contributions to each file under the terms given at the top of each file I changed.
We still need to do a few more checks to generate the (p,q) primes in a valid fashion. I agree to license my contributions to each file under the terms given at the top of each file I changed.
I agree to license my contributions to each file under the terms given at the top of each file I changed.
I agree to license my contributions to each file under the terms given at the top of each file I changed.
I agree to license my contributions to each file under the terms given at the top of each file I changed.
Some lower level stuff is still left TODO. I agree to license my contributions to each file under the terms given at the top of each file I changed.
I agree to license my contributions to each file under the terms given at the top of each file I changed.
666a1db
to
6ae912e
Compare
Rebased. Multiplication still left to do, waiting on input by @briansmith . |
I agree to license my contributions to each file under the terms given at the top of each file I changed.
6ae912e
to
8f2bd17
Compare
@briansmith any news? you said:
I stopped my work on porting the multiplication functions due to that, waiting for your input. Should I continue? |
I don't know when I'll be able to write the multiplication code. It is fine to use |
Thanks for the info. You have a concrete idea how to implement it. That's great to hear! I guess I'll wait then. |
For future reference: https://eprint.iacr.org/2018/367.pdf |
@est31 Are you planning to finish this? If so, please email me at brian@briansmith.org to discuss the IPR stuff. Otherwise, let's just close this. |
@briansmith no my intention is not to close this PR. I've put already a ton of time into it and closing would mean that the time was wasted which I don't want it to be. I've also sent you an E-Mail. |
Regarding the divisibility check, check out section "3.2 Fast Divisibility Check with a Single Multiplication" in https://arxiv.org/pdf/1902.01961.pdf. Note in particular that reference [5] may or may not a better starting point than the new method that paper presents. |
@briansmith do you think I need to implement that before merging? Otherwise I'd leave it as a post-merge project. |
@briansmith is the IPR stuff cleared now? I haven't gotten any E-Mail replies. |
Still no reaction... So now I stand before the choice of bumping this yet again, waiting more time, or simply closing for being ghosted by the maintainer. I choose to close it, because I'm doubtful it'll ever be merged: At the start of this PR, it got tons of reactions by the maintainer and judging from that the general view was that this feature is wanted and the PR welcome. The atmosphere was quite positive until this comment which suggested to close the PR without any reason. It took me quite by surprise because I was waiting for @briansmith to contribute their part like they said above, and now I'm expected to finish it while the IPR situation is still not clear. There has neither been a yes nor a no in all the months since that communication and this kind of treatment is simply not okay. Also, given that I have invested so much time into my PR, the suggestion to "just close this" is quite insulting. Of course, ultimately it's their project and up to them to accept or reject stuff. I've considered closing this multiple times already but every time I stopped in the last moment, hoping that maybe if I wait a little there'd be a reply or something. After all I'm throwing away a ton of work and invested time here. What a shame :/. In retrospect, I probably shouldn't have started this project without previously doing smaller PRs to change readmes or whatever to probe how receptive the maintainer is. I used to do this but in this case, I let my guard down. My fault. Ultimately, I don't need RSA keygen as much as I used to, as I made it for rcgen which is using multiple other encryption algorithms now. But it would still have been cool to have contributed such a major thing to a crypto library. That your contribution gets rejected is always a risk of open source but it still hurts every time, especially as I have spent a good deal of time with it. Time to move on. PS: For all the people who want to add RSA key generation support, first a warning. I don't know why the maintainer has ghosted me, maybe it's because of IPR, maybe it's because the maintainer doesn't like RSA and hopes to be able to wait until RSA is deprecated, never having to worry about key generation at all. Who knows what the reason is. So before you waste time, please make sure you are ready to take the risk of your change being rejected like my PR was. I also suggest not looking at my PR or building onto it unless there are confirmations by the maintainer that this is okay (I'd personally be okay with it). Sorry that I couldn't help you. |
Opened the PR so that I can discuss with @briansmith about the code. Nothing works yet. DON'T MERGE!
List of tasks:
(p,q)
prime pair(p,q)
to create the neededp,q,dP,dQ,qInv,r_i,d_i,t_i
Important reading:
Fixes #219