aboutsummaryrefslogtreecommitdiff
path: root/test/functional/test_framework/util.py
diff options
context:
space:
mode:
authorFabian Jahr <fjahr@protonmail.com>2020-06-11 14:59:08 +0200
committerFabian Jahr <fjahr@protonmail.com>2020-07-16 18:10:43 +0200
commitab30cece0e84a8b917cb9a219c2466574362f300 (patch)
tree262766be502124fd6d5dbfece2788ee4187229d8 /test/functional/test_framework/util.py
parentb33136b6ba9887f7db651c4c5264ca7f2f601df7 (diff)
downloadbitcoin-ab30cece0e84a8b917cb9a219c2466574362f300.tar.xz
test: Move modinv to util and add unit test
Diffstat (limited to 'test/functional/test_framework/util.py')
-rw-r--r--test/functional/test_framework/util.py31
1 files changed, 31 insertions, 0 deletions
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))