Page MenuHomePhabricator

[electrum] fix int to bytes conversion for curve points when gmpy is installed
ClosedPublic

Authored by PiRK on Sep 15 2023, 07:18.

Details

Summary

ecdsa returns gmpy2.mpz objects rather than regular python integers when gmpy2 is installed, and these objects don't have a to_bytes method, so D14462 broke the application for systems that have gmpy installed.

Convert curve points to int before converting to bytes, to be sure it works.
This reduces the performance, but it is still better than the situation before D14462.

big_int = 0xdeadbeefc0ffeef0deadbeefc0ffeef0deadbeefc0ffeef0deadbeefc0ffeef0
big_mpz = mpz(big_int)
%timeit big_int.to_bytes(32, "big")
61.5 ns ± 0.375 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
%timeit int(big_mpz).to_bytes(32, "big")
138 ns ± 0.434 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
%timeit gmpy2.to_binary(big_mpz)
108 ns ± 0.273 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
%timeit int(big_int).to_bytes(32, "big")
93.1 ns ± 0.646 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

Note that other modules in the codebase already do that (ecc_fast.py, schnorr.py, fusion.py), so it was probably a known issue for a long time.

This should be fixed in gmpy in the next release (can be tested in a couple of days with an alpha release), and then this explicit int conversion can be reverted if gmpy2 can be added with a pinpointed version to the dependencies.

Test Plan

python test_runner.py

Diff Detail

Repository
rABC Bitcoin ABC
Lint
Lint Not Applicable
Unit
Tests Not Applicable