예제 #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)
예제 #2
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)
예제 #3
0
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
예제 #4
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
예제 #5
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
예제 #6
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
예제 #7
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)
예제 #8
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)
예제 #9
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)
예제 #10
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)
예제 #11
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)
예제 #12
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)
예제 #13
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
예제 #14
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)
예제 #15
0
def crypto_wipe(buf):
    buf = ffi.from_buffer('uint8_t[]', buf, require_writable=True)
    lib.crypto_wipe(buf, len(buf))
예제 #16
0
def crypto_blake2b_update(ctx, msg):
    msg = ffi.from_buffer('uint8_t[]', msg)
    lib.crypto_blake2b_update(ctx, msg, len(msg))