/usr/lib/python2.7/dist-packages/mnemonic/shamir.py is in python-mnemonic 0.18-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #
# Copyright (c) 2015 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.
#
import sys
import binascii
from .secretsharing import secret_int_to_points, points_to_secret_int
from .mnemonic import Mnemonic
class Shamir(object):
def __init__(self, language):
self.mnemo = Mnemonic(language)
# see https://primes.utm.edu/lists/2small/ for biggest primes that fit into X bits
self.primes = {
15: (2**120 - 119),
19: (2**152 - 17),
23: (2**184 - 33),
27: (2**216 - 377),
31: (2**248 - 237)
}
def split(self, data, m, n):
if not len(data) in self.primes.keys():
raise Exception('Unknown data length')
if m < 2 or m > 15:
raise Exception('Invalid M provided')
if n < 2 or n > 15:
raise Exception('Invalid N provided')
prime = self.primes[len(data)]
s = secret_int_to_points(int(binascii.hexlify(data), 16), m, n, prime)
s = ['%x%x%s' % (m, x[0], ('%x' % x[1]).zfill(len(data) * 2)) for x in s]
return [self.mnemo.to_mnemonic(binascii.unhexlify(x)) for x in s]
def combine(self, shares):
words = set([len(x.split(' ')) for x in shares])
if len(words) != 1:
raise Exception('Inconsistent number of words')
datalen = list(words)[0] * 4 // 3 - 1
shares = [binascii.hexlify(self.mnemo.to_entropy(x)) for x in shares]
if sys.version > '3':
if set([int(chr(x[0]), 16) for x in shares]) != set([len(shares)]):
raise Exception('Number of shares does not match the threshold')
points = [(int(chr(x[1]), 16), int(x[2:], 16)) for x in shares]
else:
if set([int(x[0], 16) for x in shares]) != set([len(shares)]):
raise Exception('Number of shares does not match the threshold')
points = [(int(x[1], 16), int(x[2:], 16)) for x in shares]
prime = self.primes[datalen]
r = points_to_secret_int(points, prime)
r = hex(r)[2:]
if r.endswith('L'):
r = r[:-1]
r = r.zfill(datalen * 2)
return binascii.unhexlify(r)
|