Esempio n. 1
0
def sodium_add(a, b):
    """
    Given a couple of *same-sized* byte sequences, interpreted as the
    little-endian representation of two unsigned integers, compute
    the modular addition of the represented values, in constant time for
    a given common length of the byte sequences.

    :param a: input bytes buffer
    :type a: bytes
    :param b: input bytes buffer
    :type b: bytes
    :return: a byte-sequence representing, as a little-endian big integer,
             the integer value of ``(to_int(a) + to_int(b)) mod 2^(8*len(a))``
    :rtype: bytes
    """
    ensure(isinstance(a, bytes), raising=exc.TypeError)
    ensure(isinstance(b, bytes), raising=exc.TypeError)
    ln = len(a)
    ensure(len(b) == ln, raising=exc.TypeError)

    buf_a = ffi.new("unsigned char []", ln)
    buf_b = ffi.new("unsigned char []", ln)

    ffi.memmove(buf_a, a, ln)
    ffi.memmove(buf_b, b, ln)

    lib.sodium_add(buf_a, buf_b, ln)

    return ffi.buffer(buf_a, ln)[:]
Esempio n. 2
0
def crypto_core_ristretto255_sub(
        p, q
):  # (unsigned char *r, const unsigned char *p, const unsigned char *q);
    """
    Add integers ``p`` and ``q`` modulo ``L``, where ``L`` is the order of
    the main subgroup.

    :param p: a :py:data:`.crypto_core_ristretto255_SCALARBYTES`
              long bytes sequence representing an integer
    :type p: bytes
    :param q: a :py:data:`.crypto_core_ristretto255_SCALARBYTES`
              long bytes sequence representing an integer
    :type q: bytes
    :return: an integer represented as a
              :py:data:`.crypto_core_ristretto255_SCALARBYTES` long bytes sequence
    :rtype: bytes
    :raises rbcl.exceptions.UnavailableError: If called when using a
        minimal build of libsodium.
    """

    ensure(
        isinstance(p, bytes) and isinstance(q, bytes)
        and len(p) == crypto_core_ristretto255_BYTES
        and len(q) == crypto_core_ristretto255_BYTES,
        "Each integer must be a {} long bytes sequence".format(
            crypto_core_ristretto255_BYTES),
        raising=exc.TypeError,
    )

    r = ffi.new("unsigned char[]", crypto_core_ristretto255_BYTES)

    lib.crypto_core_ristretto255_sub(r, p, q)

    return ffi.buffer(r, crypto_core_ristretto255_BYTES)[:]
Esempio n. 3
0
def crypto_scalarmult_ristretto255_base(n):
    """
    Computes and returns the scalar product of a standard group element and an
    integer ``n`` on the edwards25519 curve.

    :param n: a :py:data:`.crypto_scalarmult_ristretto255_SCALARBYTES` long bytes
              sequence representing a scalar
    :type n: bytes
    :return: a point on the edwards25519 curve, represented as a
             :py:data:`.crypto_scalarmult_ristretto255_BYTES` long bytes sequence
    :rtype: bytes
    :raises rbcl.exceptions.UnavailableError: If called when using a
        minimal build of libsodium.
    """

    ensure(
        isinstance(n, bytes)
        and len(n) == crypto_scalarmult_ristretto255_SCALARBYTES,
        "Input must be a {} long bytes sequence".format(
            crypto_scalarmult_ristretto255_SCALARBYTES),
        raising=exc.TypeError,
    )

    q = ffi.new("unsigned char[]", crypto_scalarmult_ristretto255_BYTES)

    rc = lib.crypto_scalarmult_ristretto255_base(q, n)
    ensure(rc == 0, "Unexpected library error", raising=exc.RuntimeError)

    return ffi.buffer(q, crypto_scalarmult_ristretto255_BYTES)[:]
Esempio n. 4
0
def sodium_memcmp(inp1, inp2):
    """
    Compare contents of two memory regions in constant time
    """
    ensure(isinstance(inp1, bytes), raising=exc.TypeError)
    ensure(isinstance(inp2, bytes), raising=exc.TypeError)

    ln = max(len(inp1), len(inp2))

    buf1 = ffi.new("char []", ln)
    buf2 = ffi.new("char []", ln)

    ffi.memmove(buf1, inp1, len(inp1))
    ffi.memmove(buf2, inp2, len(inp2))

    eqL = len(inp1) == len(inp2)
    eqC = lib.sodium_memcmp(buf1, buf2, ln) == 0

    return eqL and eqC
Esempio n. 5
0
def randombytes(size):
    """
    Returns ``size`` number of random bytes from a cryptographically secure
    random source.

    :param size: int
    :rtype: bytes
    """
    buf = ffi.new("unsigned char[]", size)
    lib.randombytes(buf, size)
    return ffi.buffer(buf, size)[:]
Esempio n. 6
0
def sodium_pad(s, blocksize):
    """
    Pad the input bytearray ``s`` to a multiple of ``blocksize``
    using the ISO/IEC 7816-4 algorithm

    :param s: input bytes string
    :type s: bytes
    :param blocksize:
    :type blocksize: int
    :return: padded string
    :rtype: bytes
    """
    ensure(isinstance(s, bytes), raising=exc.TypeError)
    ensure(isinstance(blocksize, integer_types), raising=exc.TypeError)
    if blocksize <= 0:
        raise exc.ValueError
    s_len = len(s)
    m_len = s_len + blocksize
    buf = ffi.new("unsigned char []", m_len)
    p_len = ffi.new("size_t []", 1)
    ffi.memmove(buf, s, s_len)
    rc = lib.sodium_pad(p_len, buf, s_len, blocksize, m_len)
    ensure(rc == 0, "Padding failure", raising=exc.CryptoError)
    return ffi.buffer(buf, p_len[0])[:]
Esempio n. 7
0
def randombytes_buf_deterministic(size, seed):
    """
    Returns ``size`` number of deterministically generated pseudorandom bytes
    from a seed

    :param size: int
    :param seed: bytes
    :rtype: bytes
    """
    if len(seed) != randombytes_SEEDBYTES:
        raise exc.TypeError("Deterministic random bytes must be generated "
                            "from 32 bytes")

    buf = ffi.new("unsigned char[]", size)
    lib.randombytes_buf_deterministic(buf, size, seed)
    return ffi.buffer(buf, size)[:]
Esempio n. 8
0
def sodium_unpad(s, blocksize):
    """
    Remove ISO/IEC 7816-4 padding from the input byte array ``s``

    :param s: input bytes string
    :type s: bytes
    :param blocksize:
    :type blocksize: int
    :return: unpadded string
    :rtype: bytes
    """
    ensure(isinstance(s, bytes), raising=exc.TypeError)
    ensure(isinstance(blocksize, integer_types), raising=exc.TypeError)
    s_len = len(s)
    u_len = ffi.new("size_t []", 1)
    rc = lib.sodium_unpad(u_len, s, s_len, blocksize)
    if rc != 0:
        raise exc.CryptoError("Unpadding failure")
    return s[:u_len[0]]
Esempio n. 9
0
def crypto_scalarmult_ristretto255(n, p):
    """
    Computes and returns the scalar product of a *clamped* integer ``n``
    and the given group element on the edwards25519 curve.
    The scalar is clamped, as done in the public key generation case,
    by setting to zero the bits in position [0, 1, 2, 255] and setting
    to one the bit in position 254.

    :param n: a :py:data:`.crypto_scalarmult_ristretto255_SCALARBYTES` long bytes
              sequence representing a scalar
    :type n: bytes
    :param p: a :py:data:`.crypto_scalarmult_ristretto255_BYTES` long bytes sequence
              representing a point on the edwards25519 curve
    :type p: bytes
    :return: a point on the edwards25519 curve, represented as a
             :py:data:`.crypto_scalarmult_ristretto255_BYTES` long bytes sequence
    :rtype: bytes
    :raises rbcl.exceptions.UnavailableError: If called when using a
        minimal build of libsodium.
    """

    ensure(
        isinstance(n, bytes)
        and len(n) == crypto_scalarmult_ristretto255_SCALARBYTES,
        "Input must be a {} long bytes sequence".format(
            crypto_scalarmult_ristretto255_SCALARBYTES),
        raising=exc.TypeError,
    )

    ensure(
        isinstance(p, bytes)
        and len(p) == crypto_scalarmult_ristretto255_BYTES,
        "Input must be a {} long bytes sequence".format(
            crypto_scalarmult_ristretto255_BYTES),
        raising=exc.TypeError,
    )

    q = ffi.new("unsigned char[]", crypto_scalarmult_ristretto255_BYTES)

    rc = lib.crypto_scalarmult_ristretto255(q, n, p)
    ensure(rc == 0, "Unexpected library error", raising=exc.RuntimeError)

    return ffi.buffer(q, crypto_scalarmult_ristretto255_BYTES)[:]
Esempio n. 10
0
def sodium_increment(inp):
    """
    Increment the value of a byte-sequence interpreted
    as the little-endian representation of a unsigned big integer.

    :param inp: input bytes buffer
    :type inp: bytes
    :return: a byte-sequence representing, as a little-endian
             unsigned big integer, the value ``to_int(inp)``
             incremented by one.
    :rtype: bytes

    """
    ensure(isinstance(inp, bytes), raising=exc.TypeError)

    ln = len(inp)
    buf = ffi.new("unsigned char []", ln)

    ffi.memmove(buf, inp, ln)

    lib.sodium_increment(buf, ln)

    return ffi.buffer(buf, ln)[:]
Esempio n. 11
0
def crypto_core_ristretto255_scalar_random():  # (unsigned char *r);
    """
    Add integers ``p`` and ``q`` modulo ``L``, where ``L`` is the order of
    the main subgroup.

    :param p: a :py:data:`.crypto_core_ristretto255_SCALARBYTES`
              long bytes sequence representing an integer
    :type p: bytes
    :param q: a :py:data:`.crypto_core_ristretto255_SCALARBYTES`
              long bytes sequence representing an integer
    :type q: bytes
    :return: an integer represented as a
              :py:data:`.crypto_core_ristretto255_SCALARBYTES` long bytes sequence
    :rtype: bytes
    :raises rbcl.exceptions.UnavailableError: If called when using a
        minimal build of libsodium.
    """

    r = ffi.new("unsigned char[]", crypto_core_ristretto255_SCALARBYTES)

    lib.crypto_core_ristretto255_scalar_random(r)

    return ffi.buffer(r, crypto_core_ristretto255_SCALARBYTES)[:]