[Python-modules-commits] [python-mnemonic] 02/09: Import python-mnemonic_0.18.orig.tar.gz

Tristan Seligmann mithrandi at moszumanska.debian.org
Mon Dec 11 10:44:06 UTC 2017


This is an automated email from the git hooks/post-receive script.

mithrandi pushed a commit to branch master
in repository python-mnemonic.

commit 2b411870744c9e5f524bb63a49f3fb8e17b2e891
Author: Tristan Seligmann <mithrandi at mithrandi.net>
Date:   Mon Dec 11 11:04:43 2017 +0200

    Import python-mnemonic_0.18.orig.tar.gz
---
 LICENSE                       | 21 +++++++++++++
 MANIFEST.in                   |  1 +
 PKG-INFO                      |  4 +--
 mnemonic.egg-info/PKG-INFO    |  4 +--
 mnemonic.egg-info/SOURCES.txt |  2 ++
 mnemonic/mnemonic.py          | 72 +++++++++++++++++++++++++++++++++----------
 mnemonic/secretsharing.py     | 18 +++++++----
 mnemonic/shamir.py            |  1 +
 setup.py                      |  6 ++--
 9 files changed, 99 insertions(+), 30 deletions(-)

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..b135744
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2016 Pavol Rusnak
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..1aba38f
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+include LICENSE
diff --git a/PKG-INFO b/PKG-INFO
index 8de08a0..bb35071 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,10 +1,10 @@
 Metadata-Version: 1.1
 Name: mnemonic
-Version: 0.15
+Version: 0.18
 Summary: Implementation of Bitcoin BIP-0039
 Home-page: https://github.com/trezor/python-mnemonic
 Author: Bitcoin TREZOR
-Author-email: info at bitcointrezor.com
+Author-email: info at trezor.io
 License: UNKNOWN
 Description: UNKNOWN
 Platform: UNKNOWN
diff --git a/mnemonic.egg-info/PKG-INFO b/mnemonic.egg-info/PKG-INFO
index 8de08a0..bb35071 100644
--- a/mnemonic.egg-info/PKG-INFO
+++ b/mnemonic.egg-info/PKG-INFO
@@ -1,10 +1,10 @@
 Metadata-Version: 1.1
 Name: mnemonic
-Version: 0.15
+Version: 0.18
 Summary: Implementation of Bitcoin BIP-0039
 Home-page: https://github.com/trezor/python-mnemonic
 Author: Bitcoin TREZOR
-Author-email: info at bitcointrezor.com
+Author-email: info at trezor.io
 License: UNKNOWN
 Description: UNKNOWN
 Platform: UNKNOWN
diff --git a/mnemonic.egg-info/SOURCES.txt b/mnemonic.egg-info/SOURCES.txt
index a7f201e..ff35210 100644
--- a/mnemonic.egg-info/SOURCES.txt
+++ b/mnemonic.egg-info/SOURCES.txt
@@ -1,3 +1,5 @@
+LICENSE
+MANIFEST.in
 README.rst
 setup.py
 mnemonic/__init__.py
diff --git a/mnemonic/mnemonic.py b/mnemonic/mnemonic.py
index 374f11b..2ec6c3d 100644
--- a/mnemonic/mnemonic.py
+++ b/mnemonic/mnemonic.py
@@ -1,5 +1,6 @@
 #
 # Copyright (c) 2013 Pavol Rusnak
+# Copyright (c) 2017 mruddy
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy of
 # this software and associated documentation files (the "Software"), to deal in
@@ -31,20 +32,23 @@ from pbkdf2 import PBKDF2
 
 PBKDF2_ROUNDS = 2048
 
+
 class ConfigurationError(Exception):
     pass
 
+
 # From <http://tinyurl.com/p54ocsk>
-def binary_search(a, x, lo=0, hi=None):   # can't use a to specify default for hi
-    hi = hi if hi is not None else len(a) # hi defaults to len(a)
-    pos = bisect.bisect_left(a, x, lo, hi)   # find insertion position
-    return (pos if pos != hi and a[pos] == x else -1) # don't walk off the end
+def binary_search(a, x, lo=0, hi=None):                # can't use a to specify default for hi
+    hi = hi if hi is not None else len(a)              # hi defaults to len(a)
+    pos = bisect.bisect_left(a, x, lo, hi)             # find insertion position
+    return (pos if pos != hi and a[pos] == x else -1)  # don't walk off the end
+
 
 class Mnemonic(object):
     def __init__(self, language):
         self.radix = 2048
         with open('%s/%s.txt' % (self._get_directory(), language), 'r') as f:
-            self.wordlist = [w.strip() for w in f.readlines()]
+            self.wordlist = [w.strip().decode('utf8') if sys.version < '3' else w.strip() for w in f.readlines()]
         if len(self.wordlist) != self.radix:
             raise ConfigurationError('Wordlist should contain %d words, but it contains %d words.' % (self.radix, len(self.wordlist)))
 
@@ -69,6 +73,7 @@ class Mnemonic(object):
 
     @classmethod
     def detect_language(cls, code):
+        code = cls.normalize_string(code)
         first = code.split(' ')[0]
         languages = cls.list_languages()
 
@@ -80,24 +85,28 @@ class Mnemonic(object):
         raise ConfigurationError("Language not detected")
 
     def generate(self, strength=128):
-        if strength % 32 > 0:
-            raise ValueError('Strength should be divisible by 32, but it is not (%d).' % strength)
+        if strength not in [128, 160, 192, 224, 256]:
+            raise ValueError('Strength should be one of the following [128, 160, 192, 224, 256], but it is not (%d).' % strength)
         return self.to_mnemonic(os.urandom(strength // 8))
 
     # Adapted from <http://tinyurl.com/oxmn476>
     def to_entropy(self, words):
         if not isinstance(words, list):
             words = words.split(' ')
-        if len(words) % 3 > 0:
-            raise ValueError('Word list size must be multiple of three words.')
+        if len(words) not in [12, 15, 18, 21, 24]:
+            raise ValueError('Number of words must be one of the following: [12, 15, 18, 21, 24], but it is not (%d).' % len(words))
         # Look up all the words in the list and construct the
         # concatenation of the original entropy and the checksum.
         concatLenBits = len(words) * 11
         concatBits = [False] * concatLenBits
         wordindex = 0
+        if self.detect_language(' '.join(words)) == 'english':
+            use_binary_search = True
+        else:
+            use_binary_search = False
         for word in words:
             # Find the words index in the wordlist
-            ndx = binary_search(self.wordlist, word)
+            ndx = binary_search(self.wordlist, word) if use_binary_search else self.wordlist.index(word)
             if ndx < 0:
                 raise LookupError('Unable to find "%s" in word list.' % word)
             # Set the next 11 bits to the value of the index.
@@ -125,8 +134,8 @@ class Mnemonic(object):
         return entropy
 
     def to_mnemonic(self, data):
-        if len(data) % 4 > 0:
-            raise ValueError('Data length in bits should be divisible by 32, but it is not (%d bytes = %d bits).' % (len(data), len(data) * 8))
+        if len(data) not in [16, 20, 24, 28, 32]:
+            raise ValueError('Data length should be one of the following: [16, 20, 24, 28, 32], but it is not (%d).' % len(data))
         h = hashlib.sha256(data).hexdigest()
         b = bin(int(binascii.hexlify(data), 16))[2:].zfill(len(data) * 8) + \
             bin(int(h, 16))[2:].zfill(256)[:len(data) * 8 // 32]
@@ -134,16 +143,14 @@ class Mnemonic(object):
         for i in range(len(b) // 11):
             idx = int(b[i * 11:(i + 1) * 11], 2)
             result.append(self.wordlist[idx])
-        if self.detect_language(' '.join(result)) == 'japanese': # Japanese must be joined by ideographic space.
-            result_phrase = u'\xe3\x80\x80'.join(result)
+        if self.detect_language(' '.join(result)) == 'japanese':  # Japanese must be joined by ideographic space.
+            result_phrase = u'\u3000'.join(result)
         else:
             result_phrase = ' '.join(result)
         return result_phrase
 
     def check(self, mnemonic):
-        if self.detect_language(mnemonic.replace(u'\xe3\x80\x80', ' ')) == 'japanese':
-            mnemonic = mnemonic.replace(u'\xe3\x80\x80', ' ') # Japanese will likely input with ideographic space.
-        mnemonic = mnemonic.split(' ')
+        mnemonic = self.normalize_string(mnemonic).split(' ')
         if len(mnemonic) % 3 > 0:
             return False
         try:
@@ -158,8 +165,39 @@ class Mnemonic(object):
         nh = bin(int(hashlib.sha256(nd).hexdigest(), 16))[2:].zfill(256)[:l // 33]
         return h == nh
 
+    def expand_word(self, prefix):
+        if prefix in self.wordlist:
+            return prefix
+        else:
+            matches = [word for word in self.wordlist if word.startswith(prefix)]
+            if len(matches) == 1:  # matched exactly one word in the wordlist
+                return matches[0]
+            else:
+                # exact match not found.
+                # this is not a validation routine, just return the input
+                return prefix
+
+    def expand(self, mnemonic):
+        return ' '.join(map(self.expand_word, mnemonic.split(' ')))
+
     @classmethod
     def to_seed(cls, mnemonic, passphrase=''):
         mnemonic = cls.normalize_string(mnemonic)
         passphrase = cls.normalize_string(passphrase)
         return PBKDF2(mnemonic, u'mnemonic' + passphrase, iterations=PBKDF2_ROUNDS, macmodule=hmac, digestmodule=hashlib.sha512).read(64)
+
+
+def main():
+    import binascii
+    import sys
+    if len(sys.argv) > 1:
+        data = sys.argv[1]
+    else:
+        data = sys.stdin.readline().strip()
+    data = binascii.unhexlify(data)
+    m = Mnemonic('english')
+    print(m.to_mnemonic(data))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/mnemonic/secretsharing.py b/mnemonic/secretsharing.py
index 1a71b33..0c77dce 100644
--- a/mnemonic/secretsharing.py
+++ b/mnemonic/secretsharing.py
@@ -9,6 +9,7 @@
 
 from random import randint
 
+
 def egcd(a, b):
     if a == 0:
         return (b, 0, 1)
@@ -16,6 +17,7 @@ def egcd(a, b):
         g, y, x = egcd(b % a, a)
         return (g, x - (b // a) * y, y)
 
+
 def mod_inverse(k, prime):
     k = k % prime
     if k < 0:
@@ -24,6 +26,7 @@ def mod_inverse(k, prime):
         r = egcd(prime, k)[2]
     return (prime + r) % prime
 
+
 def random_polynomial(degree, intercept, upper_bound):
     """ Generates a random polynomial with positive coefficients.
     """
@@ -31,16 +34,17 @@ def random_polynomial(degree, intercept, upper_bound):
         raise ValueError('Degree must be a non-negative number.')
     coefficients = [intercept]
     for i in range(degree):
-        random_coeff = randint(0, upper_bound-1)
+        random_coeff = randint(0, upper_bound - 1)
         coefficients.append(random_coeff)
     return coefficients
 
+
 def get_polynomial_points(coefficients, num_points, prime):
     """ Calculates the first n polynomial points.
         [ (1, f(1)), (2, f(2)), ... (n, f(n)) ]
     """
     points = []
-    for x in range(1, num_points+1):
+    for x in range(1, num_points + 1):
         # start with x=1 and calculate the value of y
         y = coefficients[0]
         # calculate each term and add it to y, using modular math
@@ -52,6 +56,7 @@ def get_polynomial_points(coefficients, num_points, prime):
         points.append((x, y))
     return points
 
+
 def modular_lagrange_interpolation(x, points, prime):
     # break the points up into lists of x and y values
     x_values, y_values = zip(*points)
@@ -73,6 +78,7 @@ def modular_lagrange_interpolation(x, points, prime):
         f_x = (prime + f_x + (y_values[i] * lagrange_polynomial)) % prime
     return f_x
 
+
 def secret_int_to_points(secret_int, point_threshold, num_points, prime):
     """ Split a secret (integer) into shares (pair of integers / x,y coords).
 
@@ -85,10 +91,11 @@ def secret_int_to_points(secret_int, point_threshold, num_points, prime):
         raise ValueError("Threshold must be < the total number of points.")
     if secret_int > prime:
         raise ValueError("Error! Secret is too long for share calculation!")
-    coefficients = random_polynomial(point_threshold-1, secret_int, prime)
+    coefficients = random_polynomial(point_threshold - 1, secret_int, prime)
     points = get_polynomial_points(coefficients, num_points, prime)
     return points
 
+
 def points_to_secret_int(points, prime):
     """ Join int points into a secret int.
 
@@ -99,10 +106,9 @@ def points_to_secret_int(points, prime):
     for point in points:
         if not isinstance(point, tuple) and len(point) == 2:
             raise ValueError("Each point must be a tuple of two values.")
-        if not isinstance(point[0], int) and \
-            isinstance(point[1], int):
+        if not isinstance(point[0], int) and isinstance(point[1], int):
             raise ValueError("Each value in the point must be an int.")
     x_values, y_values = zip(*points)
     free_coefficient = modular_lagrange_interpolation(0, points, prime)
-    secret_int = free_coefficient # the secret int is the free coefficient
+    secret_int = free_coefficient  # the secret int is the free coefficient
     return secret_int
diff --git a/mnemonic/shamir.py b/mnemonic/shamir.py
index 18bf082..0ad6625 100644
--- a/mnemonic/shamir.py
+++ b/mnemonic/shamir.py
@@ -24,6 +24,7 @@ import binascii
 from .secretsharing import secret_int_to_points, points_to_secret_int
 from .mnemonic import Mnemonic
 
+
 class Shamir(object):
 
     def __init__(self, language):
diff --git a/setup.py b/setup.py
index ea7020d..dea9c76 100755
--- a/setup.py
+++ b/setup.py
@@ -3,12 +3,12 @@ from setuptools import setup
 
 setup(
     name='mnemonic',
-    version='0.15',
+    version='0.18',
     author='Bitcoin TREZOR',
-    author_email='info at bitcointrezor.com',
+    author_email='info at trezor.io',
     description='Implementation of Bitcoin BIP-0039',
     url='https://github.com/trezor/python-mnemonic',
-    packages=['mnemonic',],
+    packages=['mnemonic', ],
     package_data={'mnemonic': ['wordlist/*.txt']},
     zip_safe=False,
     install_requires=['pbkdf2'],

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-mnemonic.git



More information about the Python-modules-commits mailing list