diff options
author | Fabian Jahr <fjahr@protonmail.com> | 2020-06-11 14:59:08 +0200 |
---|---|---|
committer | Fabian Jahr <fjahr@protonmail.com> | 2020-07-16 18:10:43 +0200 |
commit | ab30cece0e84a8b917cb9a219c2466574362f300 (patch) | |
tree | 262766be502124fd6d5dbfece2788ee4187229d8 /test | |
parent | b33136b6ba9887f7db651c4c5264ca7f2f601df7 (diff) |
test: Move modinv to util and add unit test
Diffstat (limited to 'test')
-rw-r--r-- | test/functional/test_framework/key.py | 17 | ||||
-rw-r--r-- | test/functional/test_framework/util.py | 31 | ||||
-rwxr-xr-x | test/functional/test_runner.py | 1 |
3 files changed, 33 insertions, 16 deletions
diff --git a/test/functional/test_framework/key.py b/test/functional/test_framework/key.py index 912c0ca978..adbffb7dc7 100644 --- a/test/functional/test_framework/key.py +++ b/test/functional/test_framework/key.py @@ -8,22 +8,7 @@ keys, and is trivially vulnerable to side channel attacks. Do not use for anything but tests.""" import random -def modinv(a, n): - """Compute the modular inverse of a modulo n - - See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers. - """ - t1, t2 = 0, 1 - r1, r2 = n, a - while r2 != 0: - q = r1 // r2 - t1, t2 = t2, t1 - q * t2 - r1, r2 = r2, r1 - q * r2 - if r1 > 1: - return None - if t1 < 0: - t1 += n - return t1 +from .util import modinv def jacobi_symbol(n, k): """Compute the Jacobi symbol of n modulo k diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 52306c8c3d..641e18fae7 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -15,6 +15,7 @@ import os import random import re import time +import unittest from . import coverage from .authproxy import AuthServiceProxy, JSONRPCException @@ -629,3 +630,33 @@ def find_vout_for_address(node, txid, addr): if any([addr == a for a in tx["vout"][i]["scriptPubKey"]["addresses"]]): return i raise RuntimeError("Vout not found for address: txid=%s, addr=%s" % (txid, addr)) + +def modinv(a, n): + """Compute the modular inverse of a modulo n using the extended Euclidean + Algorithm. See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers. + """ + # TODO: Change to pow(a, -1, n) available in Python 3.8 + t1, t2 = 0, 1 + r1, r2 = n, a + while r2 != 0: + q = r1 // r2 + t1, t2 = t2, t1 - q * t2 + r1, r2 = r2, r1 - q * r2 + if r1 > 1: + return None + if t1 < 0: + t1 += n + return t1 + +class TestFrameworkUtil(unittest.TestCase): + def test_modinv(self): + test_vectors = [ + [7, 11], + [11, 29], + [90, 13], + [1891, 3797], + [6003722857, 77695236973], + ] + + for a, n in test_vectors: + self.assertEqual(modinv(a, n), pow(a, n-2, n)) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index c0bc471d5a..c948833c42 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -70,6 +70,7 @@ TEST_FRAMEWORK_MODULES = [ "address", "blocktools", "script", + "util", ] EXTENDED_SCRIPTS = [ |