This concept is rarely used in codebase and very much error-prone
if you forget to check it.
Instead, make it so that operations that would produce invalid integers
return an error instead.
Before:
- a separate Word element allocation of the underlying Vector<Word> was
necessary for every new word in a multi-word shift
- two additional temporary UnsignedBigInteger buffers were allocated
and passed through, including in downstream calls (e.g. Multiplication)
- an additional allocation and word shift for the carry
- FIXME note seems to point to some of these issues
After:
- main change is in LibCrypto/BigInt/Algorithms/BitwiseOperations.cpp
- one single allocation per call, using shift_left_by_n_words
- only the input "number" and "output" need to be allocated by the
caller
- downstream calls are adapted not to allocate or pass temporary
buffers
- noticeable performance improvement when running TestBigInteger:
0.41-0.42s (before) to 0.28-0.29s (after) Intel Core i9 laptop
Bonus: remove unused variables from UnsignedBigInteger::divided_by
- These were likely cut-and-paste artifacts from
UnsignedBigInteger::multiplied_by; not caught by "unused-varible".
NOTE: making this change in a separate commit than shift_right, even if
it touches the same file BitwiseOperations.cpp since:
- it is a "bonus" addition: not necessary for fixing the shift_right
bug, but logically unrelated to the shift_right code
- it brings a chain of downstream interface modifications (7 files),
unrelated to shift_right
- Before: UnsignedBigInteger::shift_right( n ) trigger index
verification error for n>31. An assumption of
num_bits<UnsignedBigInteger::BITS_IN_WORD was being made
- After: shift_right( n ) works correctly for n>31.
NOTE: "bonus" change; not necessary for fixing BigFraction::to_double
It may happen that the scalars used by SECPxxxr1 turn out to be slightly
smaller than their actual size when serialized to `UnsignedBigInteger`,
especially for P521. Handle this case by serializing zeros instead of
failing.
Originally discovered as a flaky WPT test.
Our `UnsignedBigInteger` implementation cannot handle numbers whose
size is not a multiple of 4. For this reason we need to carry the real
size around for P-521 support.
The code was printing one error message only, but multiple can be
generated in one call. Additionally, using this builtin produces
a much more descriptive output.
This replaces the old `OAEP` implementation with one backed by OpenSSL.
The changes also include some added modularity to the RSA class by
making the `RSA_EME` and `RSA_EMSE` for encryption/decryption and
signing/verifying respectively.
This commit replaces the old implementation of `EMSA_PKCS1_V1_5` with
one backed by OpenSSL. In doing so, the `sign` and `verify` methods of
RSA have been modified to behave like expected and not just be
encryption and decryption.
I was not able to split this commit because the changes to `verify` and
`sign` break pretty much everything.
It used to be that the caller would supply a buffer to write the output
to. This created an anti-pattern in multiple places where the caller
would allocate a `ByteBuffer` and then use `.bytes()` to provide it to
the `PKSystem` method. Then the callee would resize the output buffer
and reassign it, but because the resize was on `Bytes` and not on
`ByteBuffer`, the caller using the latter would cause a bug.
Additionally, in pretty much all cases the buffer was pre-allocated
shortly before.