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

[WIP]: switch to crypto-bigint for decryption #394

Draft
wants to merge 34 commits into
base: master
Choose a base branch
from

Conversation

dignifiedquire
Copy link
Member

@dignifiedquire dignifiedquire commented Nov 29, 2023

Very, very WIP

Uncomplete, unordered task list

  • switch internal storage for RsaPrivateKey
  • switch internal storage for RsaPublicKey
  • switch all code to use the new decrypt implementation
  • update public traits using BigUint to return owned versions
  • fix blinding implementation
  • switch decryption algorithm with precompute to use crypto-bigint ops
  • go through other algorithms and update what can be done without having primality checks implemented
  • review & update code for constant time operation
  • review & update code for performance
  • benchmarks

src/algorithms/rsa.rs Outdated Show resolved Hide resolved
src/algorithms/rsa.rs Outdated Show resolved Hide resolved
@bradjc
Copy link

bradjc commented Feb 13, 2024

Is it reasonable to say the implementation is fairly close, and that the remaining items would only result in minor fixes?

@tarcieri
Copy link
Member

I can potentially pick up this branch if @dignifiedquire is too busy. It looks like there's still a decent number of things to do, though the tests appear to be broken due to a [patch.crates-io] directive pointing at the local filesystem

@dignifiedquire
Copy link
Member Author

though the tests appear to be broken due to a [patch.crates-io] directive pointing at the local filesystem

this is just pointing at this branch on my machine: https://github.com/RustCrypto/crypto-bigint/tree/feat-expand-mul

@dignifiedquire
Copy link
Member Author

dignifiedquire commented Feb 15, 2024

The big changes needed to make this performant enough, is the work I started to allow different width of bigints to be operated on, as we are currently wasting a lot of time in operating on much larger values than we need to. Everything else is mostly done.

So any help with that on the cryptobigint front would be appreciated.

@tarcieri
Copy link
Member

@dignifiedquire perhaps we should get an initial working implementation landed then follow up on performance separately?

@dignifiedquire
Copy link
Member Author

@dignifiedquire perhaps we should get an initial working implementation landed then follow up on performance separately?

We could, but performance of this crate is already not great, and it goes down by at least a factor of 2 :(

@tarcieri
Copy link
Member

Better than a sidechannel vulnerability that leaks the private key!

@MasterAwesome
Copy link

@bradjc it should be possible in the future (see #51) and crypto-primes has been updated to support both with generic algorithms.

However, it will be difficult, so a first pass should probably focus on getting a heap-allocated implementation working.

Is there work required in any of the dependencies that are blocking non-alloc types from being used? If there is, I can try a stab at it parallelly.

@dignifiedquire
Copy link
Member Author

@tarcieri you are right, I will try and pull out the version that worked for a first release

@tarcieri
Copy link
Member

tarcieri commented Mar 6, 2024

@MasterAwesome the dependencies are largely ready to go, including crypto-primes.

The hard part will be making the implementation of rsa generic around the underlying integer type, and that's something we can't really even begin to explore until we have it fully migrated to crypto-bigint in any capacity.

@tarcieri
Copy link
Member

tarcieri commented Mar 6, 2024

@MasterAwesome in terms of something that would generally help with the migration, there are various avenues for crypto-bigint performance improvements to be explored: RustCrypto/crypto-bigint#403

@dignifiedquire
Copy link
Member Author

dignifiedquire commented Mar 22, 2024

Update:

done

  • merged latest master
  • switched back to fixed sizes
  • updated to crpyto-bigint alpha.12

next steps

  • figure out why 3 tests are failing
  • integrate prime number generation

@dignifiedquire
Copy link
Member Author

Almost all tests are broken, but num-bigint is not used anymore, all code is moved to crypto-bigint now

src/encoding.rs Outdated Show resolved Hide resolved
@pinkforest
Copy link

pinkforest commented Apr 2, 2024

Fixing for sede De/Serialize for BoxedUint - some TODO left there

Also serde(skip) needs a default as it's not Option<> n_params

The rest seems to be test data input migration - the previous had some str radix parse and be needs exact length

Comment on lines +79 to +80
let bits = (todo / (nprimes - i)) as u32;
*prime = generate_prime_with_rng(rng, bits, bits);
Copy link

@pinkforest pinkforest Apr 2, 2024

Choose a reason for hiding this comment

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

This needs the precision

Suggested change
let bits = (todo / (nprimes - i)) as u32;
*prime = generate_prime_with_rng(rng, bits, bits);
let bits = (todo / (nprimes - i)) as u32;
let bits_precision = BoxedUint::zero_with_precision(bits).bits_precision();
*prime = generate_prime_with_rng(rng, bits, bits_precision);

One way to get it 🤷‍♀️

The bit precision (3nd arg) causes it to trip assert - need precision not length (2nd arg) supposedly

Behind has a tripwire:

let mut random = T::random_bits_with_precision(rng, bit_length, bits_precision);
assert!(random.bits_precision() == bits_precision);

random.bits_precision() = 128, bits_precision = 85, bit_length = 85
random.bits_precision() = 512, bits_precision = 512, bit_length = 512
random.bits_precision() = 64, bits_precision = 6, bit_length = 6

The tripwire behind the scenes calls impl RandomBits try_random_bits_with_precision which does:
let mut ret = BoxedUint::zero_with_precision(bits_precision);

let e = BoxedUint::from(e);

let a1 = d * &e - &one;
let a2 = (n.as_ref() - &one).gcd(&(d * e - &one)).unwrap();

Choose a reason for hiding this comment

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

BY-GCD left side Odd but Odd-1 == Even in formula - crypto-bigint/590

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.

None yet

6 participants