Commit Graph

16 Commits (7c2e68cc87a552c153e13517b0d0d6827f48e95b)

Author SHA1 Message Date
Michael Brown 7c2e68cc87 [crypto] Eliminate temporary working space for bigint_mod_invert()
With a slight modification to the algorithm to ignore bits of the
residue that can never contribute to the result, it is possible to
reuse the as-yet uncalculated portions of the inverse to hold the
residue.  This removes the requirement for additional temporary
working space.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-11-27 13:05:18 +00:00
Michael Brown 9cbf5c4f86 [crypto] Eliminate temporary working space for bigint_reduce()
Direct modular reduction is expected to be used in situations where
there is no requirement to retain the original (unreduced) value.

Modify the API for bigint_reduce() to reduce the value in place,
(removing the separate result buffer), impose a constraint that the
modulus and value have the same size, and require the modulus to be
passed in writable memory (to allow for scaling in place).  This
removes the requirement for additional temporary working space.

Reverse the order of arguments so that the constant input is first,
to match the usage pattern for bigint_add() et al.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-11-26 14:45:51 +00:00
Michael Brown 167a08f089 [crypto] Expose carry flag from big integer addition and subtraction
Expose the effective carry (or borrow) out flag from big integer
addition and subtraction, and use this to elide an explicit bit test
when performing x25519 reduction.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-11-26 12:55:13 +00:00
Michael Brown fa1c24d14b [crypto] Add bigint_mod_invert() to calculate inverse modulo a power of two
Montgomery multiplication requires calculating the inverse of the
modulus modulo a larger power of two.

Add bigint_mod_invert() to calculate the inverse of any (odd) big
integer modulo an arbitrary power of two, using a lightly modified
version of the algorithm presented in "A New Algorithm for Inversion
mod p^k (Koç, 2017)".

The power of two is taken to be 2^k, where k is the number of bits
available in the big integer representation of the invertend.  The
inverse modulo any smaller power of two may be obtained simply by
masking off the relevant bits in the inverse.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-10-21 17:24:53 +01:00
Michael Brown 2bf16c6ffc [crypto] Separate out bigint_reduce() from bigint_mod_multiply()
Faster modular multiplication algorithms such as Montgomery
multiplication will still require the ability to perform a single
direct modular reduction.

Neaten up the implementation of direct reduction and split it out into
a separate bigint_reduce() function, complete with its own unit tests.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-10-15 13:50:51 +01:00
Michael Brown 7e0bf4ec5c [crypto] Rename bigint_rol()/bigint_ror() to bigint_shl()/bigint_shr()
The big integer shift operations are misleadingly described as
rotations since the original x86 implementations are essentially
trivial loops around the relevant rotate-through-carry instruction.

The overall operation performed is a shift rather than a rotation.
Update the function names and descriptions to reflect this.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-10-07 13:13:43 +01:00
Michael Brown 3f4f843920 [crypto] Eliminate temporary carry space for big integer multiplication
An n-bit multiplication product may be added to up to two n-bit
integers without exceeding the range of a (2n)-bit integer:

  (2^n - 1)*(2^n - 1) + (2^n - 1) + (2^n - 1) = 2^(2n) - 1

Exploit this to perform big integer multiplication in constant time
without requiring the caller to provide temporary carry space.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-09-27 13:51:24 +01:00
Michael Brown 3def13265d [crypto] Use constant-time big integer multiplication
Big integer multiplication currently performs immediate carry
propagation from each step of the long multiplication, relying on the
fact that the overall result has a known maximum value to minimise the
number of carries performed without ever needing to explicitly check
against the result buffer size.

This is not a constant-time algorithm, since the number of carries
performed will be a function of the input values.  We could make it
constant-time by always continuing to propagate the carry until
reaching the end of the result buffer, but this would introduce a
large number of redundant zero carries.

Require callers of bigint_multiply() to provide a temporary carry
storage buffer, of the same size as the result buffer.  This allows
the carry-out from the accumulation of each double-element product to
be accumulated in the temporary carry space, and then added in via a
single call to bigint_add() after the multiplication is complete.

Since the structure of big integer multiplication is identical across
all current CPU architectures, provide a single shared implementation
of bigint_multiply().  The architecture-specific operation then
becomes the multiplication of two big integer elements and the
accumulation of the double-element product.

Note that any intermediate carry arising from accumulating the lower
half of the double-element product may be added to the upper half of
the double-element product without risk of overflow, since the result
of multiplying two n-bit integers can never have all n bits set in its
upper half.  This simplifies the carry calculations for architectures
such as RISC-V and LoongArch64 that do not have a carry flag.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-09-23 13:19:58 +01:00
Michael Brown 908174ec7e [loong64] Replace broken big integer arithmetic implementations
The slightly incomprehensible LoongArch64 implementation for
bigint_subtract() is observed to produce incorrect results for some
input values.

Replace the suspicious LoongArch64 implementations of bigint_add(),
bigint_subtract(), bigint_rol() and bigint_ror(), and add a test case
for a subtraction that was producing an incorrect result with the
previous implementation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-01-19 16:40:11 +00:00
Michael Brown bac13ba1f6 [crypto] Add bigint_swap() to conditionally swap big integers
Add a helper function bigint_swap() that can be used to conditionally
swap a pair of big integers in constant time.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-01-19 12:34:02 +00:00
Michael Brown 13e390d54e [crypto] Add bigint_copy() as a convenient wrapper macro
Big integers may be efficiently copied using bigint_shrink() (which
will always copy only the size of the destination integer), but this
is potentially confusing to a reader of the code.

Provide bigint_copy() as an alias for bigint_shrink() so that the
intention of the calling code may be more obvious.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-01-19 12:29:29 +00:00
Michael Brown 26d3ef062b [crypto] Allow multiplicand and multiplier to differ in size
Big integer multiplication is currently used only as part of modular
exponentiation, where both multiplicand and multiplier will be the
same size.

Relax this requirement to allow for the use of big integer
multiplication in other contexts.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2024-01-16 16:09:16 +00:00
Michael Brown b6ee89ffb5 [legal] Relicense files under GPL2_OR_LATER_OR_UBDL
Relicense files for which I am the sole author (as identified by
util/relicense.pl).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2015-03-02 14:17:31 +00:00
Michael Brown c3b4860ce3 [legal] Update FSF mailing address in GPL licence texts
Suggested-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2012-07-20 19:55:45 +01:00
Michael Brown 3ec773cd2b [crypto] Force caller to provide temporary storage for modular calculations
bigint_mod_multiply() and bigint_mod_exp() require a fixed amount of
temporary storage for intermediate results.  (The amount of temporary
storage required depends upon the size of the integers involved.)

When performing calculations for 4096-bit RSA the amount of temporary
storage space required will exceed 2.5kB, which is too much to
allocate on the stack.  Avoid this problem by forcing the caller to
allocate temporary storage.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2012-03-18 20:22:43 +00:00
Michael Brown 4e53303c03 [test] Add big integer self-tests
These test vectors are generated using Perl's Math::BigInt.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2012-03-13 23:27:38 +00:00