X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/f1b0cf0da6b3bcc530d7f72982278510d94f6456..dfb915d33e3733296899366ee27ba1344743c3e5:/catacomb/__init__.py diff --git a/catacomb/__init__.py b/catacomb/__init__.py index 5cbf993..bb7703e 100644 --- a/catacomb/__init__.py +++ b/catacomb/__init__.py @@ -25,18 +25,47 @@ from __future__ import with_statement -import _base -import types as _types from binascii import hexlify as _hexify, unhexlify as _unhexify from contextlib import contextmanager as _ctxmgr -from sys import argv as _argv +import DLFCN as _dlfcn +import os as _os from struct import pack as _pack +import sys as _sys +import types as _types + +###-------------------------------------------------------------------------- +### Import the main C extension module. + +try: + _dlflags = _odlflags = _sys.getdlopenflags() +except AttributeError: + _dlflags = _odlflags = -1 + +## Set the `deep binding' flag. Python has its own different MD5 +## implementation, and some distributions export `md5_init' and friends so +## they override our versions, which doesn't end well. Figure out how to +## turn this flag on so we don't have the problem. +if _dlflags >= 0: + try: _dlflags |= _dlfcn.RTLD_DEEPBIND + except AttributeError: + try: _dlflags |= _os.RTLD_DEEPBIND + except AttributeError: + if _os.uname()[0] == 'Linux': _dlflags |= 8 # magic knowledge + else: pass # can't do this. + _sys.setdlopenflags(_dlflags) + +import _base + +if _odlflags >= 0: + _sys.setdlopenflags(_odlflags) + +del _dlflags, _odlflags ###-------------------------------------------------------------------------- ### Basic stuff. -## For the benefit of the default keyreporter, we need the program na,e. -_base._ego(_argv[0]) +## For the benefit of the default keyreporter, we need the program name. +_base._ego(_sys.argv[0]) ## How to fix a name back into the right identifier. Alas, the rules are not ## consistent. @@ -236,7 +265,7 @@ class _tmp: me.bytepad_after() _augment(Shake, _tmp) _augment(_ShakeBase, _tmp) -Shake._Z = _ShakeBase._Z = ByteString(200*'\0') +Shake._Z = _ShakeBase._Z = ByteString.zero(200) class KMAC (_ShakeBase): _FUNC = 'KMAC' @@ -263,7 +292,7 @@ def secret_box(k, n, m): s = E.enczero(poly1305.masksz) y = E.encrypt(m) t = poly1305(r)(s).hash(y).done() - return ByteString(t + y) + return t + y def secret_unbox(k, n, c): E = xsalsa20(k).setiv(n) @@ -520,6 +549,7 @@ class _tmp: def __repr__(me): return '%s(%d)' % (_clsname(me), me.default) def check(me, sz): return True def best(me, sz): return sz + def pad(me, sz): return sz _augment(KeySZAny, _tmp) class _tmp: @@ -536,11 +566,15 @@ class _tmp: pp.pretty(me.max); pp.text(','); pp.breakable() pp.pretty(me.mod) pp.end_group(ind, ')') - def check(me, sz): return me.min <= sz <= me.max and sz % me.mod == 0 + def check(me, sz): return me.min <= sz <= me.max and sz%me.mod == 0 def best(me, sz): if sz < me.min: raise ValueError, 'key too small' elif sz > me.max: return me.max - else: return sz - (sz % me.mod) + else: return sz - sz%me.mod + def pad(me, sz): + if sz > me.max: raise ValueError, 'key too large' + elif sz < me.min: return me.min + else: sz += me.mod; return sz - sz%me.mod _augment(KeySZRange, _tmp) class _tmp: @@ -562,6 +596,12 @@ class _tmp: if found < i <= sz: found = i if found < 0: raise ValueError, 'key too small' return found + def pad(me, sz): + found = -1 + for i in me.set: + if sz <= i and (found == -1 or i < found): found = i + if found < 0: raise ValueError, 'key too large' + return found _augment(KeySZSet, _tmp) ###-------------------------------------------------------------------------- @@ -800,21 +840,23 @@ _augment(RSAPriv, _tmp) ### DSA and related schemes. class _tmp: - def __repr__(me): return '%s(G = %r, p = %r)' % (_clsname(me), me.G, me.p) + def __repr__(me): return '%s(G = %r, p = %r, hash = %r)' % \ + (_clsname(me), me.G, me.p, me.hash) def _repr_pretty_(me, pp, cyclep): ind = _pp_bgroup_tyname(pp, me) if cyclep: pp.text('...') else: _pp_kv(pp, 'G', me.G); pp.text(','); pp.breakable() - _pp_kv(pp, 'p', me.p) + _pp_kv(pp, 'p', me.p); pp.text(','); pp.breakable() + _pp_kv(pp, 'hash', me.hash) pp.end_group(ind, ')') _augment(DSAPub, _tmp) _augment(KCDSAPub, _tmp) class _tmp: - def __repr__(me): return '%s(G = %r, u = %s, p = %r)' % \ - (_clsname(me), me.G, _repr_secret(me.u), me.p) + def __repr__(me): return '%s(G = %r, u = %s, p = %r, hash = %r)' % \ + (_clsname(me), me.G, _repr_secret(me.u), me.p, me.hash) def _repr_pretty_(me, pp, cyclep): ind = _pp_bgroup_tyname(pp, me) if cyclep: @@ -822,7 +864,8 @@ class _tmp: else: _pp_kv(pp, 'G', me.G); pp.text(','); pp.breakable() _pp_kv(pp, 'u', me.u, True); pp.text(','); pp.breakable() - _pp_kv(pp, 'p', me.p) + _pp_kv(pp, 'p', me.p); pp.text(','); pp.breakable() + _pp_kv(pp, 'hash', me.hash) pp.end_group(ind, ')') _augment(DSAPriv, _tmp) _augment(KCDSAPriv, _tmp) @@ -910,6 +953,18 @@ class Ed25519Priv (_EdDSAPriv, Ed25519Pub): def sign(me, msg, **kw): return ed25519_sign(me.priv, msg, pub = me.pub, **kw) +class Ed448Pub (_EdDSAPub): + _PUBSZ = KeySZSet(ED448_PUBSZ) + _HASH = shake256 + def verify(me, msg, sig, **kw): + return ed448_verify(me.pub, msg, sig, **kw) + +class Ed448Priv (_EdDSAPriv, Ed448Pub): + _KEYSZ = KeySZAny(ED448_KEYSZ) + def _pubkey(me, priv): return ed448_pubkey(priv) + def sign(me, msg, **kw): + return ed448_sign(me.priv, msg, pub = me.pub, **kw) + ###-------------------------------------------------------------------------- ### Built-in named curves and prime groups.