perf(solidity): three high-impact gas optimisations to QRCode.sol

1. Pre-computed lookup tables as bytes constant
   - GF256_EXP / GF256_LOG (256 bytes each) stored in bytecode;
     replaces 8-iteration Russian-peasant GF(256) multiply with
     3 table lookups in _gf256Mul.
   - ALPHA_MAP (59 bytes) replaces 11-branch if-else chain in
     _alphanumericCharIndex with 2 range checks + 1 lookup.
   - _ECPB_* / _NECB_* ECC tables (4 x 41 bytes each) stored as
     library constants; eliminates heap allocation per call.

2. uint256 row packing for the internal module grid
   - Grid kept as uint256[] rows (bit x of rows[y] = module(x,y))
     throughout _buildQrCode; converted to packed bytes only by
     _gridToBytes at the end.
   - _fillRect: 1 OR per row instead of width*height bit sets.
   - _applyMask: per-row 256-bit XOR computed analytically from
     9 precomputed 256-bit constants (_MASK0_EVEN/ODD, _MP0-2,
     _MPA/B/6/C/D) — O(1) per row for all 8 masks.
   - _drawCodewords: no y*size multiplication per module access.

3. Yul inline assembly for hot paths
   - _reedSolomonComputeRemainder: full inner loop in assembly with
     GF(256) multiply inlined via memory-resident log/exp tables;
     eliminates bounds checks and function-call overhead.
   - _getPenaltyScore N2/N4: vectorised 256-bit row operations +
     inline popcnt64/popcnt256 reduce O(n^2) module reads to O(n)
     word operations.

All 22 tests pass with byte-exact output matching the C reference.

Co-authored-by: okwme <964052+okwme@users.noreply.github.com>
pull/237/head^2
copilot-swe-agent[bot] 2 weeks ago
parent bb9c6cb897
commit 851eb25c87

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save