Source code for spiral.keys
import fcntl
import os
import struct
from nacl.public import PrivateKey
from zope.interface import implementer, Attribute, Interface
counterStruct = struct.Struct('<Q')
[docs]class IKeyAndNonceScheme(Interface):
"""
A key and nonce generation scheme.
"""
key = Attribute('A nacl.public.PrivateKey instance.')
[docs] def nonce(longterm=False):
"""
Generate a nonce.
:param longterm: True to increment the long-term counter; False to
increment the short-term counter.
:returns: 16 bytes.
"""
@implementer(IKeyAndNonceScheme)
[docs]class Keydir(object):
"""
A key loaded from disk, probably generated by ``curvecpmakekey``.
Nonces are eight random bytes concatenated to a counter persisted to disk.
:param keydir: The path to a key directory.
"""
def __init__(self, keydir):
self.keydir = keydir
with open(self.expertsFile('secretkey')) as infile:
self.key = PrivateKey(infile.read())
def expertsFile(self, name):
return os.path.join(self.keydir, '.expertsonly', name)
def nonce(self, longterm=False):
with open(self.expertsFile('lock'), 'r+') as lockfile:
fcntl.lockf(lockfile, fcntl.LOCK_EX)
with open(self.expertsFile('noncecounter'), 'rb+') as noncefile:
data = noncefile.read()
counter, = counterStruct.unpack(data)
counter += 1048576 if longterm else 1
noncefile.seek(0)
data = counterStruct.pack(counter)
noncefile.write(data)
return os.urandom(8) + data
@implementer(IKeyAndNonceScheme)
[docs]class EphemeralKey(object):
"""
An unpersisted, randomly-generated key.
Nonces are 16 random bytes.
"""
def __init__(self):
self.key = PrivateKey.generate()
def nonce(self, longterm=False):
return os.urandom(16)