Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 7
0
def crypto_blake2b_init(key=b'', hash_size=64):
    ensure_range('len(key)', len(key), BLAKE2B_KEY_MIN, BLAKE2B_KEY_MAX)
    ensure_range('hash_size', hash_size, BLAKE2B_HASH_MIN, BLAKE2B_HASH_MAX)

    ctx = ffi.new('crypto_blake2b_ctx *')
    key = ffi.from_buffer('uint8_t[]', key)
    lib.crypto_blake2b_general_init(ctx, hash_size, key, len(key))
    return ctx
Esempio n. 8
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)
Esempio n. 9
0
def test_crypto_lock_equivalent(key, nonce, msg):
    # we expose the more general crypto_lock_aead()
    # function, so check if we are calling it the right way
    # when ad == b''
    original_message = msg
    aead_mac, aead_ct = crypto_lock(key, nonce, msg)

    msg_size = len(msg)
    mac = ffi.new('uint8_t[16]')
    key = ffi.new('uint8_t[32]', key)
    nonce = ffi.new('uint8_t[24]', nonce)
    msg = ffi.new('uint8_t[]', msg)
    ct = ffi.new('uint8_t[]', msg_size)
    lib.crypto_lock(mac, ct, key, nonce, msg, msg_size)
    assert bytes(mac) == aead_mac
    assert bytes(ct) == aead_ct

    # check that we can decrypt this
    lib.crypto_wipe(msg, msg_size)
    rv = lib.crypto_unlock(msg, key, nonce, mac, ct, msg_size)
    assert rv == 0
    assert bytes(msg)[:-1] == original_message
Esempio n. 10
0
def crypto_blake2b(msg, key=b'', hash_size=64):
    ensure_range('len(key)', len(key), BLAKE2B_KEY_MIN, BLAKE2B_KEY_MAX)
    ensure_range('hash_size', hash_size, BLAKE2B_HASH_MIN, BLAKE2B_HASH_MAX)

    hash = ffi.new('uint8_t[]', hash_size)
    msg  = ffi.from_buffer('uint8_t[]', msg)
    key  = ffi.from_buffer('uint8_t[]', key)

    lib.crypto_blake2b_general(
        hash, hash_size,
        key, len(key),
        msg, len(msg),
    )
    return bytes(hash)
Esempio n. 11
0
def crypto_argon2i(
    password,
    salt,
    hash_size=64,
    nb_blocks=100000,
    nb_iterations=3,
    key=b'',
    ad=b'',
):
    ensure_range('len(salt)', len(salt), min=8)
    ensure_range('hash_size', hash_size, min=4)
    ensure_range('nb_blocks', nb_blocks, min=8)
    ensure_range('nb_iterations', nb_iterations, min=1)

    work_area = lib.malloc(nb_blocks * 1024)
    if work_area == ffi.NULL:  # pragma: no cover
        raise RuntimeError('malloc() returned NULL')

    try:
        password = ffi.from_buffer('uint8_t[]', password)
        salt = ffi.from_buffer('uint8_t[]', salt)
        hash = ffi.new('uint8_t[]', hash_size)
        key = ffi.from_buffer('uint8_t[]', key)
        ad = ffi.from_buffer('uint8_t[]', ad)
        lib.crypto_argon2i_general(
            hash,
            hash_size,
            work_area,
            nb_blocks,
            nb_iterations,
            password,
            len(password),
            salt,
            len(salt),
            key,
            len(key),
            ad,
            len(ad),
        )
        return bytes(hash)
    finally:
        lib.free(work_area)
Esempio n. 12
0
def crypto_blake2b_final(ctx):
    hash = ffi.new('uint8_t[]', ctx.hash_size)
    lib.crypto_blake2b_final(ctx, hash)
    return bytes(hash)