Z128 = ByteString.zero(16)
-class _BoxyPub (object):
+class _BasePub (object):
def __init__(me, pub, *args, **kw):
- if len(pub) != me._PUBSZ: raise ValueError, 'bad public key'
- super(_BoxyPub, me).__init__(*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:
- _pp_kv(pp, 'pub', me.pub)
+ if cyclep: pp.text('...')
+ else: me._pp(pp)
pp.end_group(ind, ')')
-class _BoxyPriv (_BoxyPub):
+class _BasePriv (object):
def __init__(me, priv, pub = None, *args, **kw):
- if len(priv) != me._KEYSZ: raise ValueError, 'bad private key'
- if pub is None: pub = me._op(priv, me._BASE)
- super(_BoxyPriv, me).__init__(pub = pub, *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)
- def __repr__(me): return '%s(priv = %s, pub = %r)' % \
- (_clsname(me), _repr_secret(me.priv), me.pub)
- def _repr_pretty_(me, pp, cyclep):
- ind = _pp_bgroup_tyname(pp, me)
- if cyclep:
- pp.text('...')
- else:
- _pp_kv(pp, 'priv', me.priv, True); pp.text(','); pp.breakable()
- _pp_kv(pp, 'pub', me.pub)
- pp.end_group(ind, ')')
+ 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 (_BoxyPub):
- _PUBSZ = X25519_PUBSZ
+class X25519Pub (_XDHPub):
+ _PUBSZ = KeySZSet(X25519_PUBSZ)
_BASE = X25519_BASE
-class X25519Priv (_BoxyPriv, X25519Pub):
- _KEYSZ = X25519_KEYSZ
+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 (_BoxyPub):
- _PUBSZ = X448_PUBSZ
+class X448Pub (_XDHPub):
+ _PUBSZ = KeySZSet(X448_PUBSZ)
_BASE = X448_BASE
-class X448Priv (_BoxyPriv, X448Pub):
- _KEYSZ = X448_KEYSZ
+class X448Priv (_XDHPriv, X448Pub):
+ _KEYSZ = KeySZSet(X448_KEYSZ)
def _op(me, k, X): return x448(k, X)
##def _hashkey(me, z): return ???
-class Ed25519Pub (object):
- def __init__(me, pub):
- me.pub = pub
+class _EdDSAPub (_BasePub):
+ pass
+
+class _EdDSAPriv (_BasePriv, _EdDSAPub):
+ pass
+
+class Ed25519Pub (_EdDSAPub):
+ _PUBSZ = KeySZSet(ED25519_PUBSZ)
def verify(me, msg, sig):
return ed25519_verify(me.pub, msg, sig)
-class Ed25519Priv (Ed25519Pub):
- def __init__(me, priv):
- me.priv = priv
- Ed25519Pub.__init__(me, ed25519_pubkey(priv))
+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)
- @classmethod
- def generate(cls, rng = rand):
- return cls(rng.block(ED25519_KEYSZ))
###--------------------------------------------------------------------------
### Built-in named curves and prime groups.