diff --git a/src/shamira.py b/src/shamira.py --- a/src/shamira.py +++ b/src/shamira.py @@ -6,7 +6,7 @@ import base64 import gf256 -def shareByte(secretB,k,n): +def _shareByte(secretB,k,n): assert n<255 coefs=[int(secretB)]+[int(b) for b in os.urandom(k-1)] points=[gf256.evaluate(coefs,i) for i in range(1,n+1)] @@ -14,11 +14,21 @@ def shareByte(secretB,k,n): def generateRaw(secret,k,n): - shares=[shareByte(b,k,n) for b in secret] + """Splits secret into shares. + + :param secret: (bytes) + :param k: number of shares necessary for secret recovery. 1 <= k <= n + :param n: (int) number of shares generated. 1 <= n < 255 + :return: [(i, (bytes) share), ...]""" + shares=[_shareByte(b,k,n) for b in secret] return [(i+1, bytes([s[i] for s in shares])) for i in range(n)] def reconstructRaw(*shares): + """Tries to recover the secret from its shares. + + :param shares: ((i, (bytes) share), ...) + :return: (bytes) reconstructed secret. Too few shares returns garbage.""" secretLen=len(shares[0][1]) res=[None]*secretLen for i in range(secretLen): @@ -28,6 +38,13 @@ def reconstructRaw(*shares): def generate(secret,k,n,encoding="b32"): + """Wraps generateRaw(). + + :param secret: (str or bytes) + :param k: number of shares necessary for secret recovery + :param n: number of shares generated + :param encoding: {hex, b32, b64} desired output encoding. Hexadecimal, Base32 or Base64. + :return: [(str) share, ...]""" if isinstance(secret,str): secret=secret.encode("utf-8") shares=generateRaw(secret,k,n) @@ -35,6 +52,12 @@ def generate(secret,k,n,encoding="b32"): def reconstruct(*shares,encoding="",raw=False): + """Wraps reconstructRaw. + + :param shares: ((str) share, ...) + :param encoding: {hex, b32, b64, ""} encoding of share strings. If not provided or empty, the function tries to guess it. + :param raw: (bool) whether to return bytes (True) or str (False) + :return: (str or bytes) reconstructed secret. Too few shares returns garbage.""" if not encoding: encoding=detectEncoding(shares)