def crypto_lock(key, nonce, msg, ad=b''): """ :returns: (bytes(mac), bytes(ciphertext)) """ ensure_length('key', key, 32) ensure_length('nonce', nonce, 24) key = ffi.from_buffer('uint8_t[32]', key) nonce = ffi.from_buffer('uint8_t[24]', nonce) mac = ffi.new('uint8_t[16]') ct = ffi.new('uint8_t[]', len(msg)) msg = ffi.from_buffer('uint8_t[]', msg) ad = ffi.from_buffer('uint8_t[]', ad) lib.crypto_lock_aead( mac, ct, key, nonce, ad, len(ad), msg, len(msg), ) return bytes(mac), bytes(ct)
def crypto_from_eddsa_public(eddsa): ensure_length('eddsa', eddsa, 32) eddsa = ffi.from_buffer('uint8_t[32]', eddsa) x25519 = ffi.new('uint8_t[32]') lib.crypto_from_eddsa_public(x25519, eddsa) return bytes(x25519)
def crypto_sign_public_key(secret_key): ensure_length('secret_key', secret_key, 32) sk = ffi.from_buffer('uint8_t[32]', secret_key) pk = ffi.new('uint8_t[32]') lib.crypto_sign_public_key(pk, sk) return bytes(pk)
def crypto_x25519_public_key(your_secret_key): ensure_length('your_secret_key', your_secret_key, 32) sk = ffi.from_buffer('uint8_t[32]', your_secret_key) pk = ffi.new('uint8_t[32]') lib.crypto_x25519_public_key(pk, sk) return bytes(pk)
def crypto_verify16(a, b): ensure_length('a', a, 16) ensure_length('b', b, 16) return lib.crypto_verify16( ffi.from_buffer('uint8_t[16]', a), ffi.from_buffer('uint8_t[16]', b), ) == 0
def crypto_verify64(a, b): ensure_length('a', a, 64) ensure_length('b', b, 64) return lib.crypto_verify64( ffi.from_buffer('uint8_t[64]', a), ffi.from_buffer('uint8_t[64]', b), ) == 0
def crypto_verify32(a, b): ensure_length('a', a, 32) ensure_length('b', b, 32) return lib.crypto_verify32( ffi.from_buffer('uint8_t[32]', a), ffi.from_buffer('uint8_t[32]', b), ) == 0
def crypto_check(sig, public_key, msg): ensure_length('sig', sig, 64) ensure_length('public_key', public_key, 32) sig = ffi.from_buffer('uint8_t[64]', sig) pk = ffi.from_buffer('uint8_t[32]', public_key) msg = ffi.from_buffer('uint8_t[]', msg) rv = lib.crypto_check(sig, pk, msg, len(msg)) return rv == 0
def crypto_key_exchange(your_secret_key, their_public_key): ensure_length('your_secret_key', your_secret_key, 32) ensure_length('their_public_key', their_public_key, 32) sk = ffi.from_buffer('uint8_t[32]', your_secret_key) pk = ffi.from_buffer('uint8_t[32]', their_public_key) shared = ffi.new('uint8_t[32]') lib.crypto_key_exchange(shared, sk, pk) return bytes(shared)
def crypto_sign(secret_key, msg): ensure_length('secret_key', secret_key, 32) sk = ffi.from_buffer('uint8_t[32]', secret_key) msg = ffi.from_buffer('uint8_t[]', msg) sig = ffi.new('uint8_t[64]') pk = ffi.new('uint8_t[32]') lib.crypto_sign_public_key(pk, secret_key) lib.crypto_sign(sig, sk, pk, msg, len(msg)) lib.crypto_wipe(pk, 32) return bytes(sig)
def crypto_unlock(key, mac, nonce, ciphertext, ad=b''): """ :returns: None or bytes(msg) """ ensure_length('key', key, 32) ensure_length('mac', mac, 16) ensure_length('nonce', nonce, 24) key = ffi.from_buffer('uint8_t[32]', key) mac = ffi.from_buffer('uint8_t[16]', mac) nonce = ffi.from_buffer('uint8_t[24]', nonce) ct = ffi.from_buffer('uint8_t[]', ciphertext) ad = ffi.from_buffer('uint8_t[]', ad) pt = ffi.new('uint8_t[]', len(ciphertext)) rv = lib.crypto_unlock_aead( pt, key, nonce, mac, ad, len(ad), ct, len(ct), ) if rv != 0: return None return bytes(pt)