diff --git a/src/shamira.py b/src/shamira.py --- a/src/shamira.py +++ b/src/shamira.py @@ -8,9 +8,16 @@ import binascii import gf256 +class SException(Exception): pass +class InvalidParams(SException): pass +class DetectionException(SException): pass +class DecodingException(SException): pass +class MalformedShare(SException): pass + + def _shareByte(secretB,k,n): if not k<=n<255: - raise ValueError("failing k<=n<255, k={0}, n={1}".format(k,n)) + raise InvalidParams("Failed k<=n<255, k={0}, n={1}".format(k,n)) coefs=[int(secretB)]+[int(b) for b in os.urandom(k-1)] points=[gf256.evaluate(coefs,i) for i in range(1,n+1)] return points @@ -65,7 +72,10 @@ def reconstruct(*shares,encoding="",raw= encoding=detectEncoding(shares) bs=reconstructRaw(*(decode(s,encoding) for s in shares)) - return bs if raw else bs.decode(encoding="utf-8") + try: + return bs if raw else bs.decode(encoding="utf-8") + except UnicodeDecodeError: + raise DecodingException('Failed to decode bytes to utf-8. Either you supplied invalid shares, or you missed the "raw" flag. Offending value: {0}'.format(bs)) def encode(share,encoding="b32"): @@ -81,14 +91,14 @@ def decode(share,encoding="b32"): (i,_,shareStr)=share.partition(".") i=int(i) if not 1<=i<=255: - raise ValueError() + raise MalformedShare("Malformed share: Failed 1<=k<=255, k={0}".format(i)) if encoding=="hex": f=base64.b16decode elif encoding=="b32": f=base64.b32decode else: f=base64.b64decode shareBytes=f(shareStr) return (i,shareBytes) except (ValueError,binascii.Error): - raise ValueError('bad share format: share="{0}", encoding="{1}"'.format(share,encoding)) + raise MalformedShare('Malformed share: share="{0}", encoding="{1}"'.format(share,encoding)) def detectEncoding(shares): @@ -100,7 +110,7 @@ def detectEncoding(shares): for (regexp, res) in classes: if all(regexp.fullmatch(share) for share in shares): return res - raise ValueError("no expected encoding detected") + raise DetectionException("No expected encoding detected") if __name__=="__main__":