Commit Graph

193 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto fe4ed7e68d mruby-numeric-ext: implement integer#gcd and Integer#lcm methods
implement Integer#gcd and Integer#lcm methods in mruby-numeric-ext with full
support for both regular integers and bigints.

key changes:
- add mrb_int_gcd euclidean algorithm for regular integer gcd calculation
- implement int_gcd and int_lcm methods with proper type checking and bigint fallback
- add mrb_bint_gcd, mrb_bint_lcm, mrb_bint_abs functions to bigint api
- register gcd and lcm methods with integer class
- add comprehensive test coverage for both regular and bigint cases

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:46 +09:00
Yukihiro "Matz" Matsumoto 7b0ee01310 mruby-random: support bigint in rand method
To achieve this, the following changes were made:

- Exported `mrb_bint_size`, `mrb_bint_from_bytes`, and `mrb_bint_sign`
  functions from `mruby-bigint` to be used in other mrbgems.
- Modified `mruby-random` to use these new functions to handle Bigint
  arguments in the `rand` method.

Co-authored-by: Gemini <gemini@google.com>
2025-08-14 10:52:46 +09:00
Yukihiro "Matz" Matsumoto 12d77d447b mruby-bigint: optimize division with single-limb divisor fast path
Implement comprehensive single-limb division optimization providing
significant performance improvements for the common case of dividing
by small numbers.

Technical implementation:
- Added mpz_div_limb() function with three optimization strategies:
  * Power-of-2 divisors: use bit shifts (q = x >> log₂(d), r = x & (d-1))
  * Single-limb to single-limb: direct hardware division
  * Multi-limb to single-limb: optimized digit-by-digit algorithm
- Integrated fast path in udiv() for yy->sz == 1 condition
- Manual bit-shift implementation to avoid function dependencies
- Proper edge case handling (zero dividend, division by zero)

Performance improvements:
- Single-limb division: 1,156K ops/sec (3.4x vs multi-limb)
- Multi->single-limb: 457K ops/sec (1.3x vs multi-limb)
- Power-of-2 division: 437K ops/sec (1.3x vs multi-limb)
- Mixed small divisions: 662K ops/sec (1.9x vs multi-limb)

Algorithm benefits:
Power-of-2 detection using (d & (d-1)) == 0 enables ultra-fast bit
operations. Multi-limb algorithm processes from MSB to LSB using
double-limb arithmetic to prevent overflow, avoiding expensive
normalization and trial division phases of general algorithm.

Applications:
Optimizes common operations like base conversion, modular arithmetic
with small moduli, and mathematical computations involving division
by constants. Particularly beneficial for embedded systems where
division by small integers is frequent.

Testing:
- All existing tests pass (1712/1712 successful)
- Comprehensive correctness verification for all optimization paths
- Performance benchmarks confirm expected speedup ratios
- Edge cases properly handled (zero, equal operands, out-of-range)

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:46 +09:00
Yukihiro "Matz" Matsumoto b689f58651 mruby-bigint: optimize modular exponentiation with barrett reduction
Implement Barrett reduction optimization for modular exponentiation operations
to significantly improve performance for cryptographic and mathematical
computations. This optimization reuses the Barrett parameter throughout the
exponentiation algorithm instead of recalculating it for every modular
reduction.

Technical implementation:
- Optimized mpz_powm() and mpz_powm_i() functions for Barrett reduction
- Automatic optimization selection based on modulus size:
  * Small moduli (1 limb): existing single-limb optimization
  * Medium moduli (2-8 limbs): Barrett reduction with parameter reuse
  * Large moduli (>8 limbs): general division fallback
- Added temporary variable management for efficient memory usage
- Maintained backward compatibility with existing API

Performance improvements:
- 37% performance improvement for medium-sized moduli operations
- Benchmark results: 76K ops/sec (Barrett) vs 55K ops/sec (general)
- Optimal for cryptographic applications (RSA, DSA, ECC operations)
- Memory efficient with no persistent state between operations

Algorithm benefits:
Barrett reduction avoids expensive division operations by precomputing
a parameter μ and reusing it throughout the binary exponentiation process.
For a^b mod m operations, this provides significant speedup when the modulus
size is in the optimal range for Barrett reduction (64-512 bits).

Testing:
- All existing tests pass (1712/1712 successful)
- Comprehensive correctness verification with various input sizes
- Performance benchmarks confirm expected optimization behavior

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:46 +09:00
Yukihiro "Matz" Matsumoto 6190234e3d mruby-bigint: integrate barrett reduction algorithm into modular arithmetic
Implement and integrate Barrett reduction algorithm to optimize modular
arithmetic operations for moderate-sized moduli (64-512 bits). This algorithm
provides significant performance improvements for cryptographic applications
and repeated modular operations.

Technical implementation:
- Added mpz_barrett_mu() to compute Barrett parameter μ = ⌊2^(2k)/m⌋
- Added mpz_barrett_reduce() with full 7-step Barrett algorithm
- Integrated into mpz_mod() with automatic selection criteria:
  * Single-limb modulus: existing fast path (unchanged)
  * Moderate moduli (2-8 limbs, dividend ≥ modulus + 2): Barrett reduction
  * Large moduli: general division fallback (unchanged)

Performance characteristics:
- Barrett reduction is most effective for 64-512 bit moduli
- Complements existing single-limb optimization for small moduli
- Transparent optimization with no API changes
- All existing tests pass (1712 tests successful)

Algorithm details:
Barrett reduction avoids expensive division by precomputing a parameter
and using only multiplications and bit shifts. The 7-step algorithm
approximates the quotient, performs modular reduction using power-of-2
operations, and applies final corrections to ensure 0 ≤ result < modulus.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:45 +09:00
Yukihiro "Matz" Matsumoto a39aabe2ac mruby-bigint: optimize modular arithmetic with single-limb fast path
Implement specialized modular reduction algorithm for single-limb modulus
to avoid expensive division operations. The optimization uses repeated
division with double-precision arithmetic for multi-limb dividends and
direct modulo operation for single-limb dividends.

Algorithm:
- Single-limb dividend: direct modulo operation (x % m)
- Multi-limb dividend: iterative reduction using double-precision arithmetic
  processing limbs from most significant to least significant

Purpose:
- Accelerate common modular arithmetic operations with small moduli
- Reduce computational overhead for cryptographic and mathematical operations
- Improve performance of rational number arithmetic that relies on modular ops

Performance impact:
- Single-limb modulus: ~1.04M ops/sec (6x improvement over general case)
- Maintains correctness for all existing modular arithmetic operations
- Zero impact on large modulus operations (fallback to existing algorithm)

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:45 +09:00
Yukihiro "Matz" Matsumoto 9ca1e52c1f mruby-bigint: reduce memory allocations in gcd algorithm
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:44 +09:00
Yukihiro "Matz" Matsumoto 3d90ce7191 mruby-bigint: add power-of-2 optimizations for gcd operations
adds efficient trailing zero counting and power-of-2 detection
with fast paths for common cases involving powers of 2

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:44 +09:00
Yukihiro "Matz" Matsumoto 1c6e061cc5 mruby-bigint: add single-limb fast path for gcd operations
optimizes gcd for single-limb numbers using binary algorithm,
avoiding multi-precision overhead for most common cases

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:44 +09:00
Yukihiro "Matz" Matsumoto 0fcfa7677d mruby-bigint: fix power-of-2 base string conversion for remaining bits
Fix incomplete digit processing in power-of-2 base string conversion:

- Add handling for remaining bits after processing all limbs
- Ensure all significant bits are converted to digits
- Maintain correct conversion for large numbers with partial bit patterns
- Add comments clarifying the conversion process

This fixes cases where the last few bits of a number might not be
converted when the total bit count doesn't align perfectly with the
base's bit width, ensuring complete and correct string representation.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:43 +09:00
Yukihiro "Matz" Matsumoto de2e8838ae mruby-bigint: replace euclidean gcd with binary gcd algorithm
Replace the traditional Euclidean GCD algorithm with Stein's binary GCD algorithm
for improved performance on large numbers:

- Implement binary GCD (Stein's algorithm) avoiding expensive division operations
- Use bit shifts and subtraction instead of modulo operations
- Handle special cases (zero values) efficiently
- Preserve common factors of 2 for correct results
- Maintain full compatibility with existing rational number functionality

Binary GCD is significantly faster for large numbers as it avoids the costly
division operations used in the Euclidean algorithm, using only bit operations,
addition, and subtraction.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:43 +09:00
Yukihiro "Matz" Matsumoto d7ef4355a9 mruby-bigint: improve memory management with bounds checking and safety
Add overflow protection and memory safety improvements to bigint operations:

- Add overflow check in mpz_realloc to prevent integer overflow in size calculations
- Fix zero-initialization loop by preserving original size during reallocation
- Improve mpz_clear to prevent double-free by nullifying pointer after free
- Add bounds checking to mpz_get_str for string conversion buffer allocation
- Add documentation comments clarifying memory allocation strategies
- Add helper macros MPZ_TMP_INIT/CLEAR for safer temporary variable management

These changes prevent potential memory corruption, buffer overflows, and crashes
while maintaining full compatibility with existing bigint functionality.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:52:43 +09:00
Yukihiro "Matz" Matsumoto d73e337442 mruby-bigint: update README.md
The document is written by Google Jules.
2025-06-23 17:07:20 +09:00
John Bampton 781edbd446 misc: fix spelling 2025-05-14 02:01:02 +10:00
Yukihiro "Matz" Matsumoto baea6e284e mruby-bigint (mpz_bits): use lzb() 2025-04-17 08:11:27 +09:00
Yukihiro "Matz" Matsumoto 061521ead5 mruby-bigint (mpz_bits): renamed from mpz_bit_length() 2025-04-17 08:10:34 +09:00
Yukihiro "Matz" Matsumoto 16198dc985 mruby-numeric-ext (int_sqrt): translate Japanese comment (oops) 2025-04-17 01:43:03 +09:00
Yukihiro "Matz" Matsumoto ddfe65763e mruby-numeric-ext (int_sqrt): support bigint 2025-04-16 23:08:23 +09:00
Yukihiro "Matz" Matsumoto 82522a2e71 mruby-bigint (mrb_bint_to_s): add check for MRB_32BIT and MRB_INT64 2025-04-14 22:09:33 +09:00
Yukihiro "Matz" Matsumoto 9750513c25 mruby-bigint (mpz_get_str): add type cast to stop warning 2025-04-04 23:55:44 +09:00
dearblue 3b1e3d930f Hide mpz_and() symbol 2025-02-02 16:59:28 +09:00
Yukihiro "Matz" Matsumoto c83bddd856 mruby-bigint (bint_new): avoid memcpy'ing NULL pointer
The second argument of memcpy() is declared to never be NULL. Clang ASAN
report this as an undefined behavior error.
2024-12-18 13:48:11 +09:00
Hoshiumi Arata 03ed952600 Merge branch 'master' into tests_for_bigint 2024-12-13 17:31:54 +09:00
Yukihiro "Matz" Matsumoto b561abd46b Merge pull request #6457 from hoshiumiarata/fix_division_of_smallint_by_bigint 2024-12-13 14:23:52 +09:00
Hoshiumi Arata 6fb93ce6f7 mruby-bigint: fix bug with division of a small number by a bigint; fix #6456 2024-12-13 12:07:34 +09:00
Yukihiro "Matz" Matsumoto 29a2bc19a3 mruby-bigint (mpz_get_str): use UL suffix for mp_limb table 2024-12-12 17:15:02 +09:00
Hoshiumi Arata 3152402fa6 Merge branch 'master' into tests_for_bigint 2024-12-12 17:01:06 +09:00
Yukihiro "Matz" Matsumoto 423c12e985 Merge pull request #6455 from hoshiumiarata/bigint_fix_div_rounding 2024-12-12 16:13:47 +09:00
Yukihiro "Matz" Matsumoto d8e6de28e9 mruby-bigint (mrb_bint_add_n): fixed a memory leak 2024-12-11 21:29:22 +09:00
Yukihiro "Matz" Matsumoto 8bd62ca311 mruby-bigint (mrb_bint_xor): fix a bug in bigint ^ int operation
Fix #6453; ref #6444
2024-12-11 21:29:21 +09:00
Yukihiro "Matz" Matsumoto b807c0a27d mruby-bigint (mpz_pow): combine mpz_init and mpz_set 2024-12-11 21:29:21 +09:00
Yukihiro "Matz" Matsumoto 8da0db545e mruby-bigint (mpz_get_str): reduce one division 2024-12-11 21:29:21 +09:00
Hoshiumi Arata 94a3a3eb6e mruby-bigint: fix rounding behavior in mpz_mdiv and mpz_mdivmod functions 2024-12-11 21:09:46 +09:00
Hoshiumi Arata 7dfbbd1eaa Merge branch 'master' into tests_for_bigint 2024-12-09 22:38:32 +09:00
Yukihiro "Matz" Matsumoto 9af061a4ce mruby-bigint: fixed a bug in string conversion; ref #6444 2024-12-09 13:14:22 +09:00
Yukihiro "Matz" Matsumoto 6d2e7f50e2 mruby-bigint: compact mpz_add_int,mpz_sub_int calling conditions 2024-12-09 13:04:01 +09:00
Yukihiro "Matz" Matsumoto 441d4be0ad mruby-bigint: fixed a bug with bigint +/- mrb_int; close #6445 2024-12-08 23:45:25 +09:00
Hoshiumi Arata 21ccbf965e bigint: expand test cases for arithmetic operations 2024-12-04 18:34:21 +09:00
dearblue de494796ac Fixed typo 2024-11-20 21:14:55 +09:00
Yukihiro "Matz" Matsumoto dc5566e560 mruby-bigint (int_fit_limb_p): fix the logic to check mrb_int size
`int_fit_limb_p()` checks if `mrb_int` fits in `mp_limb`. Previous logic
did not work well with negative integers.
2024-11-20 11:27:54 +09:00
Yukihiro "Matz" Matsumoto fed631c21b mruby-bigint (mrb_bint_sub_n): avoid allocating mpz_z 2024-11-05 13:03:54 +09:00
Yukihiro "Matz" Matsumoto 6085ffb968 mruby-bigint (mrb_bint_add_n): avoid allocating mpz_z 2024-11-05 12:22:10 +09:00
Yukihiro "Matz" Matsumoto ef18bd86a6 mruby-bigint (mpz_sub_int): avoid allocating mpz_t for mrb_int 2024-11-05 11:52:22 +09:00
Yukihiro "Matz" Matsumoto fe12e840f3 mruby-bigint (mpz_add_int): move the function definition
To prepare `mpz_sub_int` update.
2024-11-05 11:52:22 +09:00
Yukihiro "Matz" Matsumoto 19d3620965 mruby-bigint (mrb_bint_powm): stop a warning for no return 2024-10-31 14:06:10 +09:00
Yukihiro "Matz" Matsumoto f245943aed mruby-bigint (mrb_bint_powm): fixed bugs in type casting 2024-10-24 07:21:12 +09:00
Yukihiro "Matz" Matsumoto 0b96f7f2f7 mruby-bigint (mrb_bint_to_s): add uzero_p() check 2024-10-24 07:20:24 +09:00
Yukihiro "Matz" Matsumoto c5565a37ac mruby-bigint: add checks for divided by zero by sizes and contents 2024-10-24 07:18:34 +09:00
Yukihiro "Matz" Matsumoto 5e9593e285 mruby-bigint (udiv): add assertion for divided by zero 2024-10-24 07:16:32 +09:00
Yukihiro "Matz" Matsumoto 11cff8fa7d mruby-bigint (mpz_init_set_str): should skip + in the string
When the string starts with `+` it should not cause error silently. It
might cause serious error afterwards.
2024-10-22 14:44:51 +09:00