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)[:]
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)[:]
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]]
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
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)[:]
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)[:]
def crypto_core_ristretto255_is_valid_point(p): # (const unsigned char *p); """ Check if ``p`` represents a point on the ristretto255 curve, in canonical form, on the main subgroup, and that the point doesn't have a small order. :param p: a :py:data:`.crypto_core_ristretto255_BYTES` long bytes sequence representing a point on the ristretto255 curve :type p: bytes :return: point validity :rtype: bool :raises rbcl.exceptions.UnavailableError: If called when using a minimal build of libsodium. """ ensure( isinstance(p, bytes) and len(p) == crypto_core_ristretto255_BYTES, "Point must be a " + str(crypto_core_ristretto255_BYTES) + "long bytes sequence", raising=exc.TypeError, ) rc = lib.crypto_core_ristretto255_is_valid_point(p) return rc == 1
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)[:]
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])[:]
def _sodium_init(): ensure( lib.sodium_init() != -1, "Could not initialize sodium", raising=exc.RuntimeError, )