test: Move modinv to util and add unit test

This commit is contained in:
Fabian Jahr 2020-06-11 14:59:08 +02:00
parent b33136b6ba
commit ab30cece0e
No known key found for this signature in database
GPG Key ID: F13D1E9D890798CD
3 changed files with 33 additions and 16 deletions

View File

@ -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

View File

@ -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))

View File

@ -70,6 +70,7 @@ TEST_FRAMEWORK_MODULES = [
"address",
"blocktools",
"script",
"util",
]
EXTENDED_SCRIPTS = [