+### DSA and related schemes.
+
+class _tmp:
+ 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.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, 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:
+ pp.text('...')
+ 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.text(','); pp.breakable()
+ _pp_kv(pp, 'hash', me.hash)
+ pp.end_group(ind, ')')
+_augment(DSAPriv, _tmp)
+_augment(KCDSAPriv, _tmp)
+
+###--------------------------------------------------------------------------
+### Bernstein's elliptic curve crypto and related schemes.
+
+X25519_BASE = MP(9).storel(32)
+X448_BASE = MP(5).storel(56)
+
+Z128 = ByteString.zero(16)
+
+class _BasePub (object):
+ def __init__(me, pub, *args, **kw):
+ if not me._PUBSZ.check(len(pub)): raise ValueError, 'bad public key'
+ super(_BasePub, me).__init__(*args, **kw)
+ me.pub = pub
+ def __repr__(me): return '%s(pub = %r)' % (_clsname(me), me.pub)
+ def _pp(me, pp): _pp_kv(pp, 'pub', me.pub)
+ def _repr_pretty_(me, pp, cyclep):
+ ind = _pp_bgroup_tyname(pp, me)
+ if cyclep: pp.text('...')
+ else: me._pp(pp)
+ pp.end_group(ind, ')')
+
+class _BasePriv (object):
+ def __init__(me, priv, pub = None, *args, **kw):
+ if not me._KEYSZ.check(len(priv)): raise ValueError, 'bad private key'
+ if pub is None: pub = me._pubkey(priv)
+ super(_BasePriv, me).__init__(pub = pub, *args, **kw)
+ me.priv = priv
+ @classmethod
+ def generate(cls, rng = rand):
+ return cls(rng.block(cls._KEYSZ.default))
+ def __repr__(me):
+ return '%s(priv = %d, pub = %r)' % \
+ (_clsname(me), _repr_secret(me.priv), me.pub)
+ def _pp(me, pp):
+ _pp_kv(pp, 'priv', me.priv, secretp = True); pp.text(','); pp.breakable()
+ super(_BasePriv, me)._pp(pp)
+
+class _XDHPub (_BasePub): pass
+
+class _XDHPriv (_BasePriv):
+ def _pubkey(me, priv): return me._op(priv, me._BASE)
+ def agree(me, you): return me._op(me.priv, you.pub)
+ def boxkey(me, recip): return me._hashkey(me.agree(recip))
+ def box(me, recip, n, m): return secret_box(me.boxkey(recip), n, m)
+ def unbox(me, recip, n, c): return secret_unbox(me.boxkey(recip), n, c)
+
+class X25519Pub (_XDHPub):
+ _PUBSZ = KeySZSet(X25519_PUBSZ)
+ _BASE = X25519_BASE
+
+class X25519Priv (_XDHPriv, X25519Pub):
+ _KEYSZ = KeySZSet(X25519_KEYSZ)
+ def _op(me, k, X): return x25519(k, X)
+ def _hashkey(me, z): return hsalsa20_prf(z, Z128)
+
+class X448Pub (_XDHPub):
+ _PUBSZ = KeySZSet(X448_PUBSZ)
+ _BASE = X448_BASE
+
+class X448Priv (_XDHPriv, X448Pub):
+ _KEYSZ = KeySZSet(X448_KEYSZ)
+ def _op(me, k, X): return x448(k, X)
+ def _hashkey(me, z): return Shake256().hash(z).done(salsa20.keysz.default)
+
+class _EdDSAPub (_BasePub):
+ def beginhash(me): return me._HASH()
+ def endhash(me, h): return h.done()
+
+class _EdDSAPriv (_BasePriv, _EdDSAPub):
+ pass
+
+class Ed25519Pub (_EdDSAPub):
+ _PUBSZ = KeySZSet(ED25519_PUBSZ)
+ _HASH = sha512
+ 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, **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)
+
+###--------------------------------------------------------------------------