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
+try: import DLFCN as _dlfcn
+except ImportError: _dlfcn = None
+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])
+
+## Register our module.
+_base._set_home_module(_sys.modules[__name__])
+def default_lostexchook(why, ty, val, tb):
+ """`catacomb.lostexchook(WHY, TY, VAL, TB)' reports lost exceptions."""
+ _sys.stderr.write("\n\n!!! LOST EXCEPTION: %s\n" % why)
+ _sys.excepthook(ty, val, tb)
+ _sys.stderr.write("\n")
+lostexchook = default_lostexchook
## How to fix a name back into the right identifier. Alas, the rules are not
## consistent.
name = name.replace('-', '_')
## But slashes might become underscores or just vanish.
- if name.startswith('salsa20'): name = name.translate(None, '/')
+ if name.startswith('salsa20'): name = name.replace('/', '')
else: name = name.replace('/', '_')
## Done.
## Delegate methods...
def copy(me): new = me.__class__(); new._copy(me)
- def _copy(me, other): me._h = other._h
+ def _copy(me, other): me._h = other._h.copy()
def hash(me, m): me._h.hash(m); return me
def xof(me): me._h.xof(); return me
def get(me, n): return me._h.get(n)
def __mul__(me, you):
n, d = _split_rat(you)
return type(me)(me._n*n, me._d*d)
- def __div__(me, you):
+ __rmul__ = __mul__
+ def __truediv__(me, you):
n, d = _split_rat(you)
return type(me)(me._n*d, me._d*n)
- def __rdiv__(me, you):
+ def __rtruediv__(me, you):
n, d = _split_rat(you)
return type(me)(me._d*n, me._n*d)
+ __div__ = __truediv__
+ __rdiv__ = __rtruediv__
def __cmp__(me, you):
n, d = _split_rat(you)
- return type(me)(me._n*d, n*me._d)
+ return cmp(me._n*d, n*me._d)
def __rcmp__(me, you):
n, d = _split_rat(you)
return cmp(n*me._d, me._n*d)
def mont(x): return MPMont(x)
def barrett(x): return MPBarrett(x)
def reduce(x): return MPReduce(x)
- def __div__(me, you): return IntRat(me, you)
- def __rdiv__(me, you): return IntRat(you, me)
+ def __truediv__(me, you): return IntRat(me, you)
+ def __rtruediv__(me, you): return IntRat(you, me)
+ __div__ = __truediv__
+ __rdiv__ = __rtruediv__
_repr_pretty_ = _pp_str
_augment(MP, _tmp)
def halftrace(x, y): return x.reduce().halftrace(y)
def modsqrt(x, y): return x.reduce().sqrt(y)
def quadsolve(x, y): return x.reduce().quadsolve(y)
- def __div__(me, you): return GFRat(me, you)
- def __rdiv__(me, you): return GFRat(you, me)
+ def __truediv__(me, you): return GFRat(me, you)
+ def __rtruediv__(me, you): return GFRat(you, me)
+ __div__ = __truediv__
+ __rdiv__ = __rtruediv__
_repr_pretty_ = _pp_str
_augment(GF, _tmp)
class X448Priv (_XDHPriv, X448Pub):
_KEYSZ = KeySZSet(X448_KEYSZ)
def _op(me, k, X): return x448(k, X)
- ##def _hashkey(me, z): return ???
+ def _hashkey(me, z): return Shake256().hash(z).done(salsa20.keysz.default)
class _EdDSAPub (_BasePub):
def beginhash(me): return me._HASH()
class Ed25519Pub (_EdDSAPub):
_PUBSZ = KeySZSet(ED25519_PUBSZ)
_HASH = sha512
- def verify(me, msg, sig):
- return ed25519_verify(me.pub, msg, sig)
+ def verify(me, msg, sig, **kw):
+ return ed25519_verify(me.pub, msg, sig, **kw)
class Ed25519Priv (_EdDSAPriv, Ed25519Pub):
_KEYSZ = KeySZAny(ED25519_KEYSZ)
def _pubkey(me, priv): return ed25519_pubkey(priv)
- def sign(me, msg):
- return ed25519_sign(me.priv, msg, pub = me.pub)
+ 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.