text: #!/usr/bin/env python
  # -*- coding: utf-8 -*-
  # Author: Dusan Klinec, ph4r05
  
  import os
  import ctypes as ct
  from trezor_crypto import trezor_ctypes as tt
  from trezor_crypto import mod_base
  
  
  # Loaded library instance
  CLIB = None
  
  
  def open_lib(lib_path=None, try_env=False, no_init=False):
      """
      Opens the library
      :param lib_path:
      :param try_env:
      :param no_init:
      :return:
      """
      global CLIB
      ext_fpath = lib_path
  
      if ext_fpath is None:
          ext_base = 'tcry_ctype'
          mods, basedir = mod_base.get_ext_outputs()
          ext_name = '%s%s' % (ext_base, mod_base.get_mod_suffix())
          extensions = ['.so', '.dylib', '.dll', '.pyd']
          ext_guesses = ['%s%s' % (ext_base, x) for x in extensions]
  
          if ext_name in mods:
              ext_fpath = os.path.join(basedir, ext_name)
          else:
              for g in ext_guesses:
                  if g in mods:
                      ext_fpath = os.path.join(basedir, g)
  
      if ext_fpath is None and try_env:
          ext_fpath = os.getenv('LIBTREZOR_CRYPTO_PATH', None)
  
      if ext_fpath is None or not os.path.exists(ext_fpath):
          raise FileNotFoundError('Trezor-Crypto lib not found')
  
      CLIB = ct.cdll.LoadLibrary(ext_fpath)
      if not no_init:
          setup_lib(CLIB)
          init_lib()
  
      return CLIB
  
  
  def cl():
      """
      Returns CLIB
      :return:
      """
      return CLIB
  
  
  def init_lib():
      """
      Initializes Trezor crypto library
      :return:
      """
      res = cl().random_init()
      if res < 0:
          raise ValueError('Library initialization error: %s' % res)
      return res
  
  
  def setup_lib(CLIB):
      """
      Setup the CLIB - define fncs
      :param CLIB:
      :return:
      """
      
      # size_t address_prefix_bytes_len(uint32_t address_type)
      CLIB.address_prefix_bytes_len.argtypes = [tt.uint32_t]
      CLIB.address_prefix_bytes_len.restype = tt.size_t
      
      # void address_write_prefix_bytes(uint32_t address_type, uint8_t *out)
      CLIB.address_write_prefix_bytes.argtypes = [tt.uint32_t, tt.POINTER(tt.uint8_t)]
      
      # bool address_check_prefix(const uint8_t *addr, uint32_t address_type)
      CLIB.address_check_prefix.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t]
      CLIB.address_check_prefix.restype = ct.c_bool
      
      # char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, const char *alphabet)
      CLIB.base32_encode.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.POINTER(ct.c_byte), tt.size_t, tt.POINTER(ct.c_byte)]
      CLIB.base32_encode.restype = tt.POINTER(ct.c_byte)
      
      # void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out)
      CLIB.base32_encode_unsafe.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.POINTER(tt.uint8_t)]
      
      # uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out, size_t outlen, const char *alphabet)
      CLIB.base32_decode.argtypes = [tt.POINTER(ct.c_byte), tt.size_t, tt.POINTER(tt.uint8_t), tt.size_t, tt.POINTER(ct.c_byte)]
      CLIB.base32_decode.restype = tt.POINTER(tt.uint8_t)
      
      # bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out, const char *alphabet)
      CLIB.base32_decode_unsafe.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.POINTER(tt.uint8_t), tt.POINTER(ct.c_byte)]
      CLIB.base32_decode_unsafe.restype = ct.c_bool
      
      # size_t base32_encoded_length(size_t inlen)
      CLIB.base32_encoded_length.argtypes = [tt.size_t]
      CLIB.base32_encoded_length.restype = tt.size_t
      
      # size_t base32_decoded_length(size_t inlen)
      CLIB.base32_decoded_length.argtypes = [tt.size_t]
      CLIB.base32_decoded_length.restype = tt.size_t
      
      # void sha1_Transform(const uint32_t *state_in, const uint32_t *data, uint32_t *state_out)
      CLIB.sha1_Transform.argtypes = [tt.POINTER(tt.uint32_t), tt.POINTER(tt.uint32_t), tt.POINTER(tt.uint32_t)]
      
      # void sha1_Init(SHA1_CTX *)
      CLIB.sha1_Init.argtypes = [tt.POINTER(tt.SHA1_CTX)]
      
      # void sha1_Update(SHA1_CTX *, const uint8_t *, size_t)
      CLIB.sha1_Update.argtypes = [tt.POINTER(tt.SHA1_CTX), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void sha1_Final(SHA1_CTX *, uint8_t [20])
      CLIB.sha1_Final.argtypes = [tt.POINTER(tt.SHA1_CTX), tt.uint8_t * 20]
      
      # char *sha1_End(SHA1_CTX *, char [(20 * 2) + 1])
      CLIB.sha1_End.argtypes = [tt.POINTER(tt.SHA1_CTX), ct.c_byte * 41]
      CLIB.sha1_End.restype = tt.POINTER(ct.c_byte)
      
      # void sha1_Raw(const uint8_t *, size_t, uint8_t [20])
      CLIB.sha1_Raw.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.uint8_t * 20]
      
      # char *sha1_Data(const uint8_t *, size_t, char [(20 * 2) + 1])
      CLIB.sha1_Data.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, ct.c_byte * 41]
      CLIB.sha1_Data.restype = tt.POINTER(ct.c_byte)
      
      # void sha256_Transform(const uint32_t *state_in, const uint32_t *data, uint32_t *state_out)
      CLIB.sha256_Transform.argtypes = [tt.POINTER(tt.uint32_t), tt.POINTER(tt.uint32_t), tt.POINTER(tt.uint32_t)]
      
      # void sha256_Init(SHA256_CTX *)
      CLIB.sha256_Init.argtypes = [tt.POINTER(tt.SHA256_CTX)]
      
      # void sha256_Update(SHA256_CTX *, const uint8_t *, size_t)
      CLIB.sha256_Update.argtypes = [tt.POINTER(tt.SHA256_CTX), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void sha256_Final(SHA256_CTX *, uint8_t [32])
      CLIB.sha256_Final.argtypes = [tt.POINTER(tt.SHA256_CTX), tt.uint8_t * 32]
      
      # char *sha256_End(SHA256_CTX *, char [(32 * 2) + 1])
      CLIB.sha256_End.argtypes = [tt.POINTER(tt.SHA256_CTX), ct.c_byte * 65]
      CLIB.sha256_End.restype = tt.POINTER(ct.c_byte)
      
      # void sha256_Raw(const uint8_t *, size_t, uint8_t [32])
      CLIB.sha256_Raw.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.uint8_t * 32]
      
      # char *sha256_Data(const uint8_t *, size_t, char [(32 * 2) + 1])
      CLIB.sha256_Data.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, ct.c_byte * 65]
      CLIB.sha256_Data.restype = tt.POINTER(ct.c_byte)
      
      # void sha512_Transform(const uint64_t *state_in, const uint64_t *data, uint64_t *state_out)
      CLIB.sha512_Transform.argtypes = [tt.POINTER(tt.uint64_t), tt.POINTER(tt.uint64_t), tt.POINTER(tt.uint64_t)]
      
      # void sha512_Init(SHA512_CTX *)
      CLIB.sha512_Init.argtypes = [tt.POINTER(tt.SHA512_CTX)]
      
      # void sha512_Update(SHA512_CTX *, const uint8_t *, size_t)
      CLIB.sha512_Update.argtypes = [tt.POINTER(tt.SHA512_CTX), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void sha512_Final(SHA512_CTX *, uint8_t [64])
      CLIB.sha512_Final.argtypes = [tt.POINTER(tt.SHA512_CTX), tt.uint8_t * 64]
      
      # char *sha512_End(SHA512_CTX *, char [(64 * 2) + 1])
      CLIB.sha512_End.argtypes = [tt.POINTER(tt.SHA512_CTX), ct.c_byte * 129]
      CLIB.sha512_End.restype = tt.POINTER(ct.c_byte)
      
      # void sha512_Raw(const uint8_t *, size_t, uint8_t [64])
      CLIB.sha512_Raw.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.uint8_t * 64]
      
      # char *sha512_Data(const uint8_t *, size_t, char [(64 * 2) + 1])
      CLIB.sha512_Data.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, ct.c_byte * 129]
      CLIB.sha512_Data.restype = tt.POINTER(ct.c_byte)
      
      # void sha3_224_Init(SHA3_CTX *ctx)
      CLIB.sha3_224_Init.argtypes = [tt.POINTER(tt.SHA3_CTX)]
      
      # void sha3_256_Init(SHA3_CTX *ctx)
      CLIB.sha3_256_Init.argtypes = [tt.POINTER(tt.SHA3_CTX)]
      
      # void sha3_384_Init(SHA3_CTX *ctx)
      CLIB.sha3_384_Init.argtypes = [tt.POINTER(tt.SHA3_CTX)]
      
      # void sha3_512_Init(SHA3_CTX *ctx)
      CLIB.sha3_512_Init.argtypes = [tt.POINTER(tt.SHA3_CTX)]
      
      # void sha3_Update(SHA3_CTX *ctx, const char *msg, size_t size)
      CLIB.sha3_Update.argtypes = [tt.POINTER(tt.SHA3_CTX), tt.POINTER(ct.c_ubyte), tt.size_t]
      
      # void sha3_Final(SHA3_CTX *ctx, char *result)
      CLIB.sha3_Final.argtypes = [tt.POINTER(tt.SHA3_CTX), tt.POINTER(ct.c_ubyte)]
      
      # void keccak_Final(SHA3_CTX *ctx, char *result)
      CLIB.keccak_Final.argtypes = [tt.POINTER(tt.SHA3_CTX), tt.POINTER(ct.c_ubyte)]
      
      # void keccak_256(const char *data, size_t len, char *digest)
      CLIB.keccak_256.argtypes = [tt.POINTER(ct.c_ubyte), tt.size_t, tt.POINTER(ct.c_ubyte)]
      
      # void keccak_512(const char *data, size_t len, char *digest)
      CLIB.keccak_512.argtypes = [tt.POINTER(ct.c_ubyte), tt.size_t, tt.POINTER(ct.c_ubyte)]
      
      # void sha3_256(const char *data, size_t len, char *digest)
      CLIB.sha3_256.argtypes = [tt.POINTER(ct.c_ubyte), tt.size_t, tt.POINTER(ct.c_ubyte)]
      
      # void sha3_512(const char *data, size_t len, char *digest)
      CLIB.sha3_512.argtypes = [tt.POINTER(ct.c_ubyte), tt.size_t, tt.POINTER(ct.c_ubyte)]
      
      # void blake256_Init(BLAKE256_CTX *)
      CLIB.blake256_Init.argtypes = [tt.POINTER(tt.BLAKE256_CTX)]
      
      # void blake256_Update(BLAKE256_CTX *, const uint8_t *, size_t)
      CLIB.blake256_Update.argtypes = [tt.POINTER(tt.BLAKE256_CTX), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void blake256_Final(BLAKE256_CTX *, uint8_t *)
      CLIB.blake256_Final.argtypes = [tt.POINTER(tt.BLAKE256_CTX), tt.POINTER(tt.uint8_t)]
      
      # void blake256(const uint8_t *, size_t, uint8_t *)
      CLIB.blake256.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.POINTER(tt.uint8_t)]
      
      # void groestl512_Init(void *cc)
      CLIB.groestl512_Init.argtypes = [ct.c_void_p]
      
      # void groestl512_Update(void *cc, const void *data, size_t len)
      CLIB.groestl512_Update.argtypes = [ct.c_void_p, ct.c_void_p, tt.size_t]
      
      # void groestl512_Final(void *cc, void *dst)
      CLIB.groestl512_Final.argtypes = [ct.c_void_p, ct.c_void_p]
      
      # void groestl512_DoubleTrunc(void *cc, void *dst)
      CLIB.groestl512_DoubleTrunc.argtypes = [ct.c_void_p, ct.c_void_p]
      
      # int blake2b_Init(blake2b_state *S, size_t outlen)
      CLIB.blake2b_Init.argtypes = [tt.POINTER(tt.blake2b_state), tt.size_t]
      CLIB.blake2b_Init.restype = ct.c_int
      
      # int blake2b_InitKey(blake2b_state *S, size_t outlen, const void *key, size_t keylen)
      CLIB.blake2b_InitKey.argtypes = [tt.POINTER(tt.blake2b_state), tt.size_t, ct.c_void_p, tt.size_t]
      CLIB.blake2b_InitKey.restype = ct.c_int
      
      # int blake2b_InitPersonal(blake2b_state *S, size_t outlen, const void *personal, size_t personal_len)
      CLIB.blake2b_InitPersonal.argtypes = [tt.POINTER(tt.blake2b_state), tt.size_t, ct.c_void_p, tt.size_t]
      CLIB.blake2b_InitPersonal.restype = ct.c_int
      
      # int blake2b_Update(blake2b_state *S, const void *pin, size_t inlen)
      CLIB.blake2b_Update.argtypes = [tt.POINTER(tt.blake2b_state), ct.c_void_p, tt.size_t]
      CLIB.blake2b_Update.restype = ct.c_int
      
      # int blake2b_Final(blake2b_state *S, void *out, size_t outlen)
      CLIB.blake2b_Final.argtypes = [tt.POINTER(tt.blake2b_state), ct.c_void_p, tt.size_t]
      CLIB.blake2b_Final.restype = ct.c_int
      
      # int blake2b(const uint8_t *msg, uint32_t msg_len, void *out, size_t outlen)
      CLIB.blake2b.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t, ct.c_void_p, tt.size_t]
      CLIB.blake2b.restype = ct.c_int
      
      # int blake2b_Key(const uint8_t *msg, uint32_t msg_len, const void *key, size_t keylen, void *out, size_t outlen)
      CLIB.blake2b_Key.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t, ct.c_void_p, tt.size_t, ct.c_void_p, tt.size_t]
      CLIB.blake2b_Key.restype = ct.c_int
      
      # void hasher_Init(Hasher *hasher, HasherType type)
      CLIB.hasher_Init.argtypes = [tt.POINTER(tt.Hasher), tt.HasherType]
      
      # void hasher_Reset(Hasher *hasher)
      CLIB.hasher_Reset.argtypes = [tt.POINTER(tt.Hasher)]
      
      # void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length)
      CLIB.hasher_Update.argtypes = [tt.POINTER(tt.Hasher), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void hasher_Final(Hasher *hasher, uint8_t hash[32])
      CLIB.hasher_Final.argtypes = [tt.POINTER(tt.Hasher), tt.uint8_t * 32]
      
      # void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[32])
      CLIB.hasher_Raw.argtypes = [tt.HasherType, tt.POINTER(tt.uint8_t), tt.size_t, tt.uint8_t * 32]
      
      # int base58_encode_check(const uint8_t *data, int len, HasherType hasher_type, char *str, int strsize)
      CLIB.base58_encode_check.argtypes = [tt.POINTER(tt.uint8_t), ct.c_int, tt.HasherType, tt.POINTER(ct.c_byte), ct.c_int]
      CLIB.base58_encode_check.restype = ct.c_int
      
      # int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen)
      CLIB.base58_decode_check.argtypes = [tt.POINTER(ct.c_byte), tt.HasherType, tt.POINTER(tt.uint8_t), ct.c_int]
      CLIB.base58_decode_check.restype = ct.c_int
      
      # bool b58tobin(void *bin, size_t *binszp, const char *b58)
      CLIB.b58tobin.argtypes = [ct.c_void_p, tt.POINTER(tt.size_t), tt.POINTER(ct.c_byte)]
      CLIB.b58tobin.restype = ct.c_bool
      
      # int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str)
      CLIB.b58check.argtypes = [ct.c_void_p, tt.size_t, tt.HasherType, tt.POINTER(ct.c_byte)]
      CLIB.b58check.restype = ct.c_int
      
      # bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
      CLIB.b58enc.argtypes = [tt.POINTER(ct.c_byte), tt.POINTER(tt.size_t), ct.c_void_p, tt.size_t]
      CLIB.b58enc.restype = ct.c_bool
      
      # uint32_t random32(void)
      CLIB.random32.argtypes = []
      CLIB.random32.restype = tt.uint32_t
      
      # void random_buffer(uint8_t *buf, size_t len)
      CLIB.random_buffer.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t]
      
      # uint32_t random_uniform(uint32_t n)
      CLIB.random_uniform.argtypes = [tt.uint32_t]
      CLIB.random_uniform.restype = tt.uint32_t
      
      # void random_permute(char *buf, size_t len)
      CLIB.random_permute.argtypes = [tt.POINTER(ct.c_byte), tt.size_t]
      
      # int random_init(void)
      CLIB.random_init.argtypes = []
      CLIB.random_init.restype = ct.c_int
      
      # void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, const uint32_t keylen)
      CLIB.hmac_sha256_Init.argtypes = [tt.POINTER(tt.HMAC_SHA256_CTX), tt.POINTER(tt.uint8_t), tt.uint32_t]
      
      # void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg, const uint32_t msglen)
      CLIB.hmac_sha256_Update.argtypes = [tt.POINTER(tt.HMAC_SHA256_CTX), tt.POINTER(tt.uint8_t), tt.uint32_t]
      
      # void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac)
      CLIB.hmac_sha256_Final.argtypes = [tt.POINTER(tt.HMAC_SHA256_CTX), tt.POINTER(tt.uint8_t)]
      
      # void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac)
      CLIB.hmac_sha256.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t, tt.POINTER(tt.uint8_t), tt.uint32_t, tt.POINTER(tt.uint8_t)]
      
      # void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *opad_digest, uint32_t *ipad_digest)
      CLIB.hmac_sha256_prepare.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t, tt.POINTER(tt.uint32_t), tt.POINTER(tt.uint32_t)]
      
      # void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, const uint32_t keylen)
      CLIB.hmac_sha512_Init.argtypes = [tt.POINTER(tt.HMAC_SHA512_CTX), tt.POINTER(tt.uint8_t), tt.uint32_t]
      
      # void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg, const uint32_t msglen)
      CLIB.hmac_sha512_Update.argtypes = [tt.POINTER(tt.HMAC_SHA512_CTX), tt.POINTER(tt.uint8_t), tt.uint32_t]
      
      # void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac)
      CLIB.hmac_sha512_Final.argtypes = [tt.POINTER(tt.HMAC_SHA512_CTX), tt.POINTER(tt.uint8_t)]
      
      # void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac)
      CLIB.hmac_sha512.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t, tt.POINTER(tt.uint8_t), tt.uint32_t, tt.POINTER(tt.uint8_t)]
      
      # void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, uint64_t *opad_digest, uint64_t *ipad_digest)
      CLIB.hmac_sha512_prepare.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t, tt.POINTER(tt.uint64_t), tt.POINTER(tt.uint64_t)]
      
      # void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen)
      CLIB.pbkdf2_hmac_sha256_Init.argtypes = [tt.POINTER(tt.PBKDF2_HMAC_SHA256_CTX), tt.POINTER(tt.uint8_t), ct.c_int, tt.POINTER(tt.uint8_t), ct.c_int]
      
      # void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations)
      CLIB.pbkdf2_hmac_sha256_Update.argtypes = [tt.POINTER(tt.PBKDF2_HMAC_SHA256_CTX), tt.uint32_t]
      
      # void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key)
      CLIB.pbkdf2_hmac_sha256_Final.argtypes = [tt.POINTER(tt.PBKDF2_HMAC_SHA256_CTX), tt.POINTER(tt.uint8_t)]
      
      # void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key)
      CLIB.pbkdf2_hmac_sha256.argtypes = [tt.POINTER(tt.uint8_t), ct.c_int, tt.POINTER(tt.uint8_t), ct.c_int, tt.uint32_t, tt.POINTER(tt.uint8_t)]
      
      # void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen)
      CLIB.pbkdf2_hmac_sha512_Init.argtypes = [tt.POINTER(tt.PBKDF2_HMAC_SHA512_CTX), tt.POINTER(tt.uint8_t), ct.c_int, tt.POINTER(tt.uint8_t), ct.c_int]
      
      # void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations)
      CLIB.pbkdf2_hmac_sha512_Update.argtypes = [tt.POINTER(tt.PBKDF2_HMAC_SHA512_CTX), tt.uint32_t]
      
      # void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key)
      CLIB.pbkdf2_hmac_sha512_Final.argtypes = [tt.POINTER(tt.PBKDF2_HMAC_SHA512_CTX), tt.POINTER(tt.uint8_t)]
      
      # void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key)
      CLIB.pbkdf2_hmac_sha512.argtypes = [tt.POINTER(tt.uint8_t), ct.c_int, tt.POINTER(tt.uint8_t), ct.c_int, tt.uint32_t, tt.POINTER(tt.uint8_t)]
      
      # uint32_t read_be(const uint8_t *data)
      CLIB.read_be.argtypes = [tt.POINTER(tt.uint8_t)]
      CLIB.read_be.restype = tt.uint32_t
      
      # void write_be(uint8_t *data, uint32_t x)
      CLIB.write_be.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t]
      
      # uint32_t read_le(const uint8_t *data)
      CLIB.read_le.argtypes = [tt.POINTER(tt.uint8_t)]
      CLIB.read_le.restype = tt.uint32_t
      
      # void write_le(uint8_t *data, uint32_t x)
      CLIB.write_le.argtypes = [tt.POINTER(tt.uint8_t), tt.uint32_t]
      
      # void bn_read_be(const uint8_t *in_number, bignum256 *out_number)
      CLIB.bn_read_be.argtypes = [tt.POINTER(tt.uint8_t), tt.POINTER(tt.bignum256)]
      
      # void bn_write_be(const bignum256 *in_number, uint8_t *out_number)
      CLIB.bn_write_be.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.uint8_t)]
      
      # void bn_read_le(const uint8_t *in_number, bignum256 *out_number)
      CLIB.bn_read_le.argtypes = [tt.POINTER(tt.uint8_t), tt.POINTER(tt.bignum256)]
      
      # void bn_write_le(const bignum256 *in_number, uint8_t *out_number)
      CLIB.bn_write_le.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.uint8_t)]
      
      # void bn_read_uint32(uint32_t in_number, bignum256 *out_number)
      CLIB.bn_read_uint32.argtypes = [tt.uint32_t, tt.POINTER(tt.bignum256)]
      
      # void bn_read_uint64(uint64_t in_number, bignum256 *out_number)
      CLIB.bn_read_uint64.argtypes = [tt.uint64_t, tt.POINTER(tt.bignum256)]
      
      # int bn_bitcount(const bignum256 *a)
      CLIB.bn_bitcount.argtypes = [tt.POINTER(tt.bignum256)]
      CLIB.bn_bitcount.restype = ct.c_int
      
      # int bn_digitcount(const bignum256 *a)
      CLIB.bn_digitcount.argtypes = [tt.POINTER(tt.bignum256)]
      CLIB.bn_digitcount.restype = ct.c_uint
      
      # void bn_zero(bignum256 *a)
      CLIB.bn_zero.argtypes = [tt.POINTER(tt.bignum256)]
      
      # int bn_is_zero(const bignum256 *a)
      CLIB.bn_is_zero.argtypes = [tt.POINTER(tt.bignum256)]
      CLIB.bn_is_zero.restype = ct.c_int
      
      # void bn_one(bignum256 *a)
      CLIB.bn_one.argtypes = [tt.POINTER(tt.bignum256)]
      
      # int bn_is_less(const bignum256 *a, const bignum256 *b)
      CLIB.bn_is_less.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      CLIB.bn_is_less.restype = ct.c_int
      
      # int bn_is_equal(const bignum256 *a, const bignum256 *b)
      CLIB.bn_is_equal.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      CLIB.bn_is_equal.restype = ct.c_int
      
      # void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase, const bignum256 *falsecase)
      CLIB.bn_cmov.argtypes = [tt.POINTER(tt.bignum256), ct.c_int, tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_lshift(bignum256 *a)
      CLIB.bn_lshift.argtypes = [tt.POINTER(tt.bignum256)]
      
      # void bn_rshift(bignum256 *a)
      CLIB.bn_rshift.argtypes = [tt.POINTER(tt.bignum256)]
      
      # void bn_setbit(bignum256 *a, uint8_t bit)
      CLIB.bn_setbit.argtypes = [tt.POINTER(tt.bignum256), tt.uint8_t]
      
      # void bn_clearbit(bignum256 *a, uint8_t bit)
      CLIB.bn_clearbit.argtypes = [tt.POINTER(tt.bignum256), tt.uint8_t]
      
      # uint32_t bn_testbit(bignum256 *a, uint8_t bit)
      CLIB.bn_testbit.argtypes = [tt.POINTER(tt.bignum256), tt.uint8_t]
      CLIB.bn_testbit.restype = tt.uint32_t
      
      # void bn_xor(bignum256 *a, const bignum256 *b, const bignum256 *c)
      CLIB.bn_xor.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_mult_half(bignum256 *x, const bignum256 *prime)
      CLIB.bn_mult_half.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime)
      CLIB.bn_mult_k.argtypes = [tt.POINTER(tt.bignum256), tt.uint8_t, tt.POINTER(tt.bignum256)]
      
      # void bn_mod(bignum256 *x, const bignum256 *prime)
      CLIB.bn_mod.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime)
      CLIB.bn_multiply.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_fast_mod(bignum256 *x, const bignum256 *prime)
      CLIB.bn_fast_mod.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_sqrt(bignum256 *x, const bignum256 *prime)
      CLIB.bn_sqrt.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_inverse(bignum256 *x, const bignum256 *prime)
      CLIB.bn_inverse.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_normalize(bignum256 *a)
      CLIB.bn_normalize.argtypes = [tt.POINTER(tt.bignum256)]
      
      # void bn_add(bignum256 *a, const bignum256 *b)
      CLIB.bn_add.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_addmod(bignum256 *a, const bignum256 *b, const bignum256 *prime)
      CLIB.bn_addmod.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_addi(bignum256 *a, uint32_t b)
      CLIB.bn_addi.argtypes = [tt.POINTER(tt.bignum256), tt.uint32_t]
      
      # void bn_subi(bignum256 *a, uint32_t b, const bignum256 *prime)
      CLIB.bn_subi.argtypes = [tt.POINTER(tt.bignum256), tt.uint32_t, tt.POINTER(tt.bignum256)]
      
      # void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res, const bignum256 *prime)
      CLIB.bn_subtractmod.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res)
      CLIB.bn_subtract.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256), tt.POINTER(tt.bignum256)]
      
      # void bn_divmod58(bignum256 *a, uint32_t *r)
      CLIB.bn_divmod58.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.uint32_t)]
      
      # void bn_divmod1000(bignum256 *a, uint32_t *r)
      CLIB.bn_divmod1000.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(tt.uint32_t)]
      
      # size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix, int decimals, int exponent, bool trailing, char *out, size_t outlen)
      CLIB.bn_format.argtypes = [tt.POINTER(tt.bignum256), tt.POINTER(ct.c_byte), tt.POINTER(ct.c_byte), ct.c_uint, ct.c_int, ct.c_bool, tt.POINTER(ct.c_byte), tt.size_t]
      CLIB.bn_format.restype = tt.size_t
      
      # void ECRYPT_init(void)
      CLIB.ECRYPT_init.argtypes = []
      
      # void ECRYPT_keysetup(ECRYPT_ctx *ctx, const u8 *key, u32 keysize, u32 ivsize)
      CLIB.ECRYPT_keysetup.argtypes = [tt.POINTER(tt.ECRYPT_ctx), tt.POINTER(tt.u8), tt.u32, tt.u32]
      
      # void ECRYPT_ivsetup(ECRYPT_ctx *ctx, const u8 *iv)
      CLIB.ECRYPT_ivsetup.argtypes = [tt.POINTER(tt.ECRYPT_ctx), tt.POINTER(tt.u8)]
      
      # void ECRYPT_encrypt_bytes(ECRYPT_ctx *ctx, const u8 *plaintext, u8 *ciphertext, u32 msglen)
      CLIB.ECRYPT_encrypt_bytes.argtypes = [tt.POINTER(tt.ECRYPT_ctx), tt.POINTER(tt.u8), tt.POINTER(tt.u8), tt.u32]
      
      # void ECRYPT_decrypt_bytes(ECRYPT_ctx *ctx, const u8 *ciphertext, u8 *plaintext, u32 msglen)
      CLIB.ECRYPT_decrypt_bytes.argtypes = [tt.POINTER(tt.ECRYPT_ctx), tt.POINTER(tt.u8), tt.POINTER(tt.u8), tt.u32]
      
      # void ECRYPT_keystream_bytes(ECRYPT_ctx *ctx, u8 *keystream, u32 length)
      CLIB.ECRYPT_keystream_bytes.argtypes = [tt.POINTER(tt.ECRYPT_ctx), tt.POINTER(tt.u8), tt.u32]
      
      # void poly1305_init(poly1305_context *ctx, const char key[32])
      CLIB.poly1305_init.argtypes = [tt.POINTER(tt.poly1305_context), ct.c_ubyte * 32]
      
      # void poly1305_update(poly1305_context *ctx, const char *m, size_t bytes)
      CLIB.poly1305_update.argtypes = [tt.POINTER(tt.poly1305_context), tt.POINTER(ct.c_ubyte), tt.size_t]
      
      # void poly1305_finish(poly1305_context *ctx, char mac[16])
      CLIB.poly1305_finish.argtypes = [tt.POINTER(tt.poly1305_context), ct.c_ubyte * 16]
      
      # void poly1305_auth(char mac[16], const char *m, size_t bytes, const char key[32])
      CLIB.poly1305_auth.argtypes = [ct.c_ubyte * 16, tt.POINTER(ct.c_ubyte), tt.size_t, ct.c_ubyte * 32]
      
      # int poly1305_verify(const char mac1[16], const char mac2[16])
      CLIB.poly1305_verify.argtypes = [ct.c_ubyte * 16, ct.c_ubyte * 16]
      CLIB.poly1305_verify.restype = ct.c_int
      
      # int poly1305_power_on_self_test(void)
      CLIB.poly1305_power_on_self_test.argtypes = []
      CLIB.poly1305_power_on_self_test.restype = ct.c_int
      
      # void xchacha20poly1305_init(chacha20poly1305_ctx *ctx, uint8_t key[32], uint8_t nonce[24])
      CLIB.xchacha20poly1305_init.argtypes = [tt.POINTER(tt.chacha20poly1305_ctx), tt.uint8_t * 32, tt.uint8_t * 24]
      
      # void chacha20poly1305_encrypt(chacha20poly1305_ctx *ctx, uint8_t *in, uint8_t *out, size_t n)
      CLIB.chacha20poly1305_encrypt.argtypes = [tt.POINTER(tt.chacha20poly1305_ctx), tt.POINTER(tt.uint8_t), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void chacha20poly1305_decrypt(chacha20poly1305_ctx *ctx, uint8_t *in, uint8_t *out, size_t n)
      CLIB.chacha20poly1305_decrypt.argtypes = [tt.POINTER(tt.chacha20poly1305_ctx), tt.POINTER(tt.uint8_t), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void chacha20poly1305_auth(chacha20poly1305_ctx *ctx, uint8_t *in, size_t n)
      CLIB.chacha20poly1305_auth.argtypes = [tt.POINTER(tt.chacha20poly1305_ctx), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void chacha20poly1305_finish(chacha20poly1305_ctx *ctx, uint8_t mac[16])
      CLIB.chacha20poly1305_finish.argtypes = [tt.POINTER(tt.chacha20poly1305_ctx), tt.uint8_t * 16]
      
      # void rfc7539_init(chacha20poly1305_ctx *ctx, uint8_t key[32], uint8_t nonce[12])
      CLIB.rfc7539_init.argtypes = [tt.POINTER(tt.chacha20poly1305_ctx), tt.uint8_t * 32, tt.uint8_t * 12]
      
      # void rfc7539_auth(chacha20poly1305_ctx *ctx, uint8_t *in, size_t n)
      CLIB.rfc7539_auth.argtypes = [tt.POINTER(tt.chacha20poly1305_ctx), tt.POINTER(tt.uint8_t), tt.size_t]
      
      # void rfc7539_finish(chacha20poly1305_ctx *ctx, int64_t alen, int64_t plen, uint8_t mac[16])
      CLIB.rfc7539_finish.argtypes = [tt.POINTER(tt.chacha20poly1305_ctx), tt.int64_t, tt.int64_t, tt.uint8_t * 16]
      
      # int xmr_base58_addr_encode_check(uint64_t tag, const uint8_t *data, size_t binsz, char *b58, size_t b58sz)
      CLIB.xmr_base58_addr_encode_check.argtypes = [tt.uint64_t, tt.POINTER(tt.uint8_t), tt.size_t, tt.POINTER(ct.c_byte), tt.size_t]
      CLIB.xmr_base58_addr_encode_check.restype = ct.c_int
      
      # int xmr_base58_addr_decode_check(const char *addr, size_t sz, uint64_t *tag, void *data, size_t datalen)
      CLIB.xmr_base58_addr_decode_check.argtypes = [tt.POINTER(ct.c_byte), tt.size_t, tt.POINTER(tt.uint64_t), ct.c_void_p, tt.size_t]
      CLIB.xmr_base58_addr_decode_check.restype = ct.c_int
      
      # bool xmr_base58_encode(char *b58, size_t *b58sz, const void *data, size_t binsz)
      CLIB.xmr_base58_encode.argtypes = [tt.POINTER(ct.c_byte), tt.POINTER(tt.size_t), ct.c_void_p, tt.size_t]
      CLIB.xmr_base58_encode.restype = ct.c_bool
      
      # bool xmr_base58_decode(const char *b58, size_t b58sz, void *data, size_t *binsz)
      CLIB.xmr_base58_decode.argtypes = [tt.POINTER(ct.c_byte), tt.size_t, ct.c_void_p, tt.POINTER(tt.size_t)]
      CLIB.xmr_base58_decode.restype = ct.c_bool
      
      # int xmr_size_varint(uint64_t num)
      CLIB.xmr_size_varint.argtypes = [tt.uint64_t]
      CLIB.xmr_size_varint.restype = ct.c_int
      
      # int xmr_write_varint(uint8_t *buff, size_t buff_size, uint64_t num)
      CLIB.xmr_write_varint.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.uint64_t]
      CLIB.xmr_write_varint.restype = ct.c_int
      
      # int xmr_read_varint(uint8_t *buff, size_t buff_size, uint64_t *val)
      CLIB.xmr_read_varint.argtypes = [tt.POINTER(tt.uint8_t), tt.size_t, tt.POINTER(tt.uint64_t)]
      CLIB.xmr_read_varint.restype = ct.c_int
      
      # void curve25519_copy(bignum25519 out, const bignum25519 in)
      CLIB.curve25519_copy.argtypes = [tt.bignum25519, tt.bignum25519]
      
      # void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b)
      CLIB.curve25519_add.argtypes = [tt.bignum25519, tt.bignum25519, tt.bignum25519]
      
      # void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b)
      CLIB.curve25519_add_after_basic.argtypes = [tt.bignum25519, tt.bignum25519, tt.bignum25519]
      
      # void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b)
      CLIB.curve25519_add_reduce.argtypes = [tt.bignum25519, tt.bignum25519, tt.bignum25519]
      
      # void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b)
      CLIB.curve25519_sub.argtypes = [tt.bignum25519, tt.bignum25519, tt.bignum25519]
      
      # void curve25519_scalar_product(bignum25519 out, const bignum25519 in, const uint32_t scalar)
      CLIB.curve25519_scalar_product.argtypes = [tt.bignum25519, tt.bignum25519, tt.uint32_t]
      
      # void curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b)
      CLIB.curve25519_sub_after_basic.argtypes = [tt.bignum25519, tt.bignum25519, tt.bignum25519]
      
      # void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b)
      CLIB.curve25519_sub_reduce.argtypes = [tt.bignum25519, tt.bignum25519, tt.bignum25519]
      
      # void curve25519_neg(bignum25519 out, const bignum25519 a)
      CLIB.curve25519_neg.argtypes = [tt.bignum25519, tt.bignum25519]
      
      # void curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b)
      CLIB.curve25519_mul.argtypes = [tt.bignum25519, tt.bignum25519, tt.bignum25519]
      
      # void curve25519_square(bignum25519 out, const bignum25519 in)
      CLIB.curve25519_square.argtypes = [tt.bignum25519, tt.bignum25519]
      
      # void curve25519_square_times(bignum25519 out, const bignum25519 in, int count)
      CLIB.curve25519_square_times.argtypes = [tt.bignum25519, tt.bignum25519, ct.c_int]
      
      # void curve25519_expand(bignum25519 out, const char in[32])
      CLIB.curve25519_expand.argtypes = [tt.bignum25519, ct.c_ubyte * 32]
      
      # void curve25519_contract(char out[32], const bignum25519 in)
      CLIB.curve25519_contract.argtypes = [ct.c_ubyte * 32, tt.bignum25519]
      
      # void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap)
      CLIB.curve25519_swap_conditional.argtypes = [tt.bignum25519, tt.bignum25519, tt.uint32_t]
      
      # void curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b)
      CLIB.curve25519_pow_two5mtwo0_two250mtwo0.argtypes = [tt.bignum25519]
      
      # void curve25519_recip(bignum25519 out, const bignum25519 z)
      CLIB.curve25519_recip.argtypes = [tt.bignum25519, tt.bignum25519]
      
      # void curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z)
      CLIB.curve25519_pow_two252m3.argtypes = [tt.bignum25519, tt.bignum25519]
      
      # void reduce256_modm(bignum256modm r)
      CLIB.reduce256_modm.argtypes = [tt.bignum256modm]
      
      # void barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1)
      CLIB.barrett_reduce256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm, tt.bignum256modm]
      
      # void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y)
      CLIB.add256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm, tt.bignum256modm]
      
      # void neg256_modm(bignum256modm r, const bignum256modm x)
      CLIB.neg256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm]
      
      # void sub256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y)
      CLIB.sub256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm, tt.bignum256modm]
      
      # void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y)
      CLIB.mul256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm, tt.bignum256modm]
      
      # void expand256_modm(bignum256modm out, const char *in, size_t len)
      CLIB.expand256_modm.argtypes = [tt.bignum256modm, tt.POINTER(ct.c_ubyte), tt.size_t]
      
      # void expand_raw256_modm(bignum256modm out, const char in[32])
      CLIB.expand_raw256_modm.argtypes = [tt.bignum256modm, ct.c_ubyte * 32]
      
      # int is_reduced256_modm(const bignum256modm in)
      CLIB.is_reduced256_modm.argtypes = [tt.bignum256modm]
      CLIB.is_reduced256_modm.restype = ct.c_int
      
      # void contract256_modm(char out[32], const bignum256modm in)
      CLIB.contract256_modm.argtypes = [ct.c_ubyte * 32, tt.bignum256modm]
      
      # void contract256_window4_modm(char r[64], const bignum256modm in)
      CLIB.contract256_window4_modm.argtypes = [ct.c_byte * 64, tt.bignum256modm]
      
      # void contract256_slidingwindow_modm(char r[256], const bignum256modm s, int windowsize)
      CLIB.contract256_slidingwindow_modm.argtypes = [ct.c_byte * 256, tt.bignum256modm, ct.c_int]
      
      # void set256_modm(bignum256modm r, uint64_t v)
      CLIB.set256_modm.argtypes = [tt.bignum256modm, tt.uint64_t]
      
      # int get256_modm(uint64_t *v, const bignum256modm r)
      CLIB.get256_modm.argtypes = [tt.POINTER(tt.uint64_t), tt.bignum256modm]
      CLIB.get256_modm.restype = ct.c_int
      
      # int eq256_modm(const bignum256modm x, const bignum256modm y)
      CLIB.eq256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm]
      CLIB.eq256_modm.restype = ct.c_int
      
      # int cmp256_modm(const bignum256modm x, const bignum256modm y)
      CLIB.cmp256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm]
      CLIB.cmp256_modm.restype = ct.c_int
      
      # int iszero256_modm(const bignum256modm x)
      CLIB.iszero256_modm.argtypes = [tt.bignum256modm]
      CLIB.iszero256_modm.restype = ct.c_int
      
      # void copy256_modm(bignum256modm r, const bignum256modm x)
      CLIB.copy256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm]
      
      # int check256_modm(const bignum256modm x)
      CLIB.check256_modm.argtypes = [tt.bignum256modm]
      CLIB.check256_modm.restype = ct.c_int
      
      # void mulsub256_modm(bignum256modm r, const bignum256modm a, const bignum256modm b, const bignum256modm c)
      CLIB.mulsub256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm, tt.bignum256modm, tt.bignum256modm]
      
      # void muladd256_modm(bignum256modm r, const bignum256modm a, const bignum256modm b, const bignum256modm c)
      CLIB.muladd256_modm.argtypes = [tt.bignum256modm, tt.bignum256modm, tt.bignum256modm, tt.bignum256modm]
      
      # int ed25519_verify(const char *x, const char *y, size_t len)
      CLIB.ed25519_verify.argtypes = [tt.POINTER(ct.c_ubyte), tt.POINTER(ct.c_ubyte), tt.size_t]
      CLIB.ed25519_verify.restype = ct.c_int
      
      # void ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p)
      CLIB.ge25519_p1p1_to_partial.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519_p1p1)]
      
      # void ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p)
      CLIB.ge25519_p1p1_to_full.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519_p1p1)]
      
      # void ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r)
      CLIB.ge25519_full_to_pniels.argtypes = [tt.POINTER(tt.ge25519_pniels), tt.POINTER(tt.ge25519)]
      
      # void ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p)
      CLIB.ge25519_double_p1p1.argtypes = [tt.POINTER(tt.ge25519_p1p1), tt.POINTER(tt.ge25519)]
      
      # void ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, char signbit)
      CLIB.ge25519_nielsadd2_p1p1.argtypes = [tt.POINTER(tt.ge25519_p1p1), tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519_niels), ct.c_ubyte]
      
      # void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, char signbit)
      CLIB.ge25519_pnielsadd_p1p1.argtypes = [tt.POINTER(tt.ge25519_p1p1), tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519_pniels), ct.c_ubyte]
      
      # void ge25519_double_partial(ge25519 *r, const ge25519 *p)
      CLIB.ge25519_double_partial.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519)]
      
      # void ge25519_double(ge25519 *r, const ge25519 *p)
      CLIB.ge25519_double.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519)]
      
      # void ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q)
      CLIB.ge25519_nielsadd2.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519_niels)]
      
      # void ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q)
      CLIB.ge25519_pnielsadd.argtypes = [tt.POINTER(tt.ge25519_pniels), tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519_pniels)]
      
      # void ge25519_pack(char r[32], const ge25519 *p)
      CLIB.ge25519_pack.argtypes = [ct.c_ubyte * 32, tt.POINTER(tt.ge25519)]
      
      # int ge25519_unpack_negative_vartime(ge25519 *r, const char p[32])
      CLIB.ge25519_unpack_negative_vartime.argtypes = [tt.POINTER(tt.ge25519), ct.c_ubyte * 32]
      CLIB.ge25519_unpack_negative_vartime.restype = ct.c_int
      
      # void ge25519_set_neutral(ge25519 *r)
      CLIB.ge25519_set_neutral.argtypes = [tt.POINTER(tt.ge25519)]
      
      # void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2)
      CLIB.ge25519_double_scalarmult_vartime.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519), tt.bignum256modm, tt.bignum256modm]
      
      # void ge25519_double_scalarmult_vartime2(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const ge25519 *p2, const bignum256modm s2)
      CLIB.ge25519_double_scalarmult_vartime2.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519), tt.bignum256modm, tt.POINTER(tt.ge25519), tt.bignum256modm]
      
      # void ge25519_scalarmult(ge25519 *r, const ge25519 *p1, const bignum256modm s1)
      CLIB.ge25519_scalarmult.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519), tt.bignum256modm]
      
      # void curve25519_set(bignum25519 r, uint32_t x)
      CLIB.curve25519_set.argtypes = [tt.bignum25519, tt.uint32_t]
      
      # void curve25519_set_d(bignum25519 r)
      CLIB.curve25519_set_d.argtypes = [tt.bignum25519]
      
      # void curve25519_set_2d(bignum25519 r)
      CLIB.curve25519_set_2d.argtypes = [tt.bignum25519]
      
      # void curve25519_set_sqrtneg1(bignum25519 r)
      CLIB.curve25519_set_sqrtneg1.argtypes = [tt.bignum25519]
      
      # int curve25519_isnegative(const bignum25519 f)
      CLIB.curve25519_isnegative.argtypes = [tt.bignum25519]
      CLIB.curve25519_isnegative.restype = ct.c_int
      
      # int curve25519_isnonzero(const bignum25519 f)
      CLIB.curve25519_isnonzero.argtypes = [tt.bignum25519]
      CLIB.curve25519_isnonzero.restype = ct.c_int
      
      # void curve25519_reduce(bignum25519 r, const bignum25519 in)
      CLIB.curve25519_reduce.argtypes = [tt.bignum25519, tt.bignum25519]
      
      # void curve25519_expand_reduce(bignum25519 out, const char in[32])
      CLIB.curve25519_expand_reduce.argtypes = [tt.bignum25519, ct.c_ubyte * 32]
      
      # int ge25519_check(const ge25519 *r)
      CLIB.ge25519_check.argtypes = [tt.POINTER(tt.ge25519)]
      CLIB.ge25519_check.restype = ct.c_int
      
      # int ge25519_eq(const ge25519 *a, const ge25519 *b)
      CLIB.ge25519_eq.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519)]
      CLIB.ge25519_eq.restype = ct.c_int
      
      # void ge25519_copy(ge25519 *dst, const ge25519 *src)
      CLIB.ge25519_copy.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519)]
      
      # void ge25519_set_base(ge25519 *r)
      CLIB.ge25519_set_base.argtypes = [tt.POINTER(tt.ge25519)]
      
      # void ge25519_mul8(ge25519 *r, const ge25519 *t)
      CLIB.ge25519_mul8.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519)]
      
      # void ge25519_neg_partial(ge25519 *r)
      CLIB.ge25519_neg_partial.argtypes = [tt.POINTER(tt.ge25519)]
      
      # void ge25519_neg_full(ge25519 *r)
      CLIB.ge25519_neg_full.argtypes = [tt.POINTER(tt.ge25519)]
      
      # void ge25519_reduce(ge25519 *r, const ge25519 *t)
      CLIB.ge25519_reduce.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519)]
      
      # void ge25519_norm(ge25519 *r, const ge25519 *t)
      CLIB.ge25519_norm.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519)]
      
      # void ge25519_add(ge25519 *r, const ge25519 *a, const ge25519 *b, char signbit)
      CLIB.ge25519_add.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519), ct.c_ubyte]
      
      # void ge25519_fromfe_frombytes_vartime(ge25519 *r, const char *s)
      CLIB.ge25519_fromfe_frombytes_vartime.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(ct.c_ubyte)]
      
      # int ge25519_unpack_vartime(ge25519 *r, const char *s)
      CLIB.ge25519_unpack_vartime.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(ct.c_ubyte)]
      CLIB.ge25519_unpack_vartime.restype = ct.c_int
      
      # void ge25519_scalarmult_base_wrapper(ge25519 *r, const bignum256modm s)
      CLIB.ge25519_scalarmult_base_wrapper.argtypes = [tt.POINTER(tt.ge25519), tt.bignum256modm]
      
      # void ge25519_set_xmr_h(ge25519 *r)
      CLIB.ge25519_set_xmr_h.argtypes = [tt.POINTER(tt.ge25519)]
      
      # void xmr_random_scalar(bignum256modm m)
      CLIB.xmr_random_scalar.argtypes = [tt.bignum256modm]
      
      # void xmr_fast_hash(uint8_t *hash, const void *data, size_t length)
      CLIB.xmr_fast_hash.argtypes = [tt.POINTER(tt.uint8_t), ct.c_void_p, tt.size_t]
      
      # void xmr_hasher_init(Hasher *hasher)
      CLIB.xmr_hasher_init.argtypes = [tt.POINTER(tt.Hasher)]
      
      # void xmr_hasher_update(Hasher *hasher, const void *data, size_t length)
      CLIB.xmr_hasher_update.argtypes = [tt.POINTER(tt.Hasher), ct.c_void_p, tt.size_t]
      
      # void xmr_hasher_final(Hasher *hasher, uint8_t *hash)
      CLIB.xmr_hasher_final.argtypes = [tt.POINTER(tt.Hasher), tt.POINTER(tt.uint8_t)]
      
      # void xmr_hasher_copy(Hasher *dst, const Hasher *src)
      CLIB.xmr_hasher_copy.argtypes = [tt.POINTER(tt.Hasher), tt.POINTER(tt.Hasher)]
      
      # void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length)
      CLIB.xmr_hash_to_scalar.argtypes = [tt.bignum256modm, ct.c_void_p, tt.size_t]
      
      # void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length)
      CLIB.xmr_hash_to_ec.argtypes = [tt.POINTER(tt.ge25519), ct.c_void_p, tt.size_t]
      
      # void xmr_derivation_to_scalar(bignum256modm s, const ge25519 *p, uint32_t output_index)
      CLIB.xmr_derivation_to_scalar.argtypes = [tt.bignum256modm, tt.POINTER(tt.ge25519), tt.uint32_t]
      
      # void xmr_generate_key_derivation(ge25519 *r, const ge25519 *A, const bignum256modm b)
      CLIB.xmr_generate_key_derivation.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519), tt.bignum256modm]
      
      # void xmr_derive_private_key(bignum256modm s, const ge25519 *deriv, uint32_t idx, const bignum256modm base)
      CLIB.xmr_derive_private_key.argtypes = [tt.bignum256modm, tt.POINTER(tt.ge25519), tt.uint32_t, tt.bignum256modm]
      
      # void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx, const ge25519 *base)
      CLIB.xmr_derive_public_key.argtypes = [tt.POINTER(tt.ge25519), tt.POINTER(tt.ge25519), tt.uint32_t, tt.POINTER(tt.ge25519)]
      
      # void xmr_add_keys2(ge25519 *r, const bignum256modm a, const bignum256modm b, const ge25519 *B)
      CLIB.xmr_add_keys2.argtypes = [tt.POINTER(tt.ge25519), tt.bignum256modm, tt.bignum256modm, tt.POINTER(tt.ge25519)]
      
      # void xmr_add_keys2_vartime(ge25519 *r, const bignum256modm a, const bignum256modm b, const ge25519 *B)
      CLIB.xmr_add_keys2_vartime.argtypes = [tt.POINTER(tt.ge25519), tt.bignum256modm, tt.bignum256modm, tt.POINTER(tt.ge25519)]
      
      # void xmr_add_keys3(ge25519 *r, const bignum256modm a, const ge25519 *A, const bignum256modm b, const ge25519 *B)
      CLIB.xmr_add_keys3.argtypes = [tt.POINTER(tt.ge25519), tt.bignum256modm, tt.POINTER(tt.ge25519), tt.bignum256modm, tt.POINTER(tt.ge25519)]
      
      # void xmr_add_keys3_vartime(ge25519 *r, const bignum256modm a, const ge25519 *A, const bignum256modm b, const ge25519 *B)
      CLIB.xmr_add_keys3_vartime.argtypes = [tt.POINTER(tt.ge25519), tt.bignum256modm, tt.POINTER(tt.ge25519), tt.bignum256modm, tt.POINTER(tt.ge25519)]
      
      # void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, uint32_t minor, const bignum256modm m)
      CLIB.xmr_get_subaddress_secret_key.argtypes = [tt.bignum256modm, tt.uint32_t, tt.uint32_t, tt.bignum256modm]
      
      # void xmr_gen_c(ge25519 *r, const bignum256modm a, uint64_t amount)
      CLIB.xmr_gen_c.argtypes = [tt.POINTER(tt.ge25519), tt.bignum256modm, tt.uint64_t]
      
      # void xmr_gen_range_sig(xmr_range_sig_t *sig, ge25519 *C, bignum256modm mask, xmr_amount amount, bignum256modm *last_mask)
      CLIB.xmr_gen_range_sig.argtypes = [tt.POINTER(tt.xmr_range_sig_t), tt.POINTER(tt.ge25519), tt.bignum256modm, tt.xmr_amount, tt.POINTER(tt.bignum256modm)]
      
      # void xmr_gen_range_sig_ex(xmr_range_sig_t *sig, ge25519 *C, bignum256modm mask, xmr_amount amount, bignum256modm *last_mask, bignum256modm ai[64], bignum256modm alpha[64])
      CLIB.xmr_gen_range_sig_ex.argtypes = [tt.POINTER(tt.xmr_range_sig_t), tt.POINTER(tt.ge25519), tt.bignum256modm, tt.xmr_amount, tt.POINTER(tt.bignum256modm), tt.bignum256modm * 64, tt.bignum256modm * 64]
  
  
  #
  # Wrappers
  #
  
  
  def address_prefix_bytes_len(address_type): 
      return int(CLIB.address_prefix_bytes_len(address_type))
  
  
  def address_write_prefix_bytes(address_type, out): 
      CLIB.address_write_prefix_bytes(address_type, out)
  
  
  def address_write_prefix_bytes_r(address_type): 
      out = (tt.uint8_t)()
      CLIB.address_write_prefix_bytes(address_type, out)
      return int(out)
  
  
  def address_check_prefix(addr, address_type): 
      return int(CLIB.address_check_prefix(addr, address_type))
  
  
  def base32_encode(in_, inlen, out, outlen, alphabet): 
      return bytes(CLIB.base32_encode(in_, inlen, out, outlen, alphabet))
  
  
  def base32_encode_unsafe(in_, inlen, out): 
      CLIB.base32_encode_unsafe(in_, inlen, out)
  
  
  def base32_encode_unsafe_r(in_, inlen): 
      out = (tt.uint8_t)()
      CLIB.base32_encode_unsafe(in_, inlen, out)
      return bytes(out)
  
  
  def base32_decode(in_, inlen, out, outlen, alphabet): 
      return bytes(CLIB.base32_decode(in_, inlen, out, outlen, alphabet))
  
  
  def base32_decode_unsafe(in_, inlen, out, alphabet): 
      return int(CLIB.base32_decode_unsafe(in_, inlen, out, alphabet))
  
  
  def base32_encoded_length(inlen): 
      return int(CLIB.base32_encoded_length(inlen))
  
  
  def base32_decoded_length(inlen): 
      return int(CLIB.base32_decoded_length(inlen))
  
  
  def sha1_Transform(state_in, data, state_out): 
      CLIB.sha1_Transform(ct.byref(state_in), ct.byref(data), ct.byref(state_out))
  
  
  def sha1_Transform_r(state_in, data): 
      state_out = (tt.uint32_t)()
      CLIB.sha1_Transform(ct.byref(state_in), ct.byref(data), ct.byref(state_out))
      return state_out
  
  
  def sha1_Init(r): 
      CLIB.sha1_Init(ct.byref(r))
  
  
  def sha1_Init_r(): 
      r = (tt.SHA1_CTX)()
      CLIB.sha1_Init(ct.byref(r))
      return r
  
  
  def sha1_Update(r, a, b): 
      CLIB.sha1_Update(ct.byref(r), a, b)
  
  
  def sha1_Update_r(a, b): 
      r = (tt.SHA1_CTX)()
      CLIB.sha1_Update(ct.byref(r), a, b)
      return r
  
  
  def sha1_Final(r, a): 
      CLIB.sha1_Final(ct.byref(r), a)
  
  
  def sha1_Final_r(): 
      r = (tt.SHA1_CTX)()
      a = (tt.uint8_t * 20)()
      CLIB.sha1_Final(ct.byref(r), a)
      return r, bytes(a)
  
  
  def sha1_End(r, a): 
      return bytes(CLIB.sha1_End(ct.byref(r), a))
  
  
  def sha1_End_r(): 
      r = (tt.SHA1_CTX)()
      a = (ct.c_byte * 41)()
      _res = CLIB.sha1_End(ct.byref(r), a)
      return bytes(_res), r, bytes(a)
  
  
  def sha1_Raw(r, a, b): 
      CLIB.sha1_Raw(r, a, b)
  
  
  def sha1_Raw_r(r, a): 
      b = (tt.uint8_t * 20)()
      CLIB.sha1_Raw(r, a, b)
      return bytes(b)
  
  
  def sha1_Data(r, a, b): 
      return bytes(CLIB.sha1_Data(r, a, b))
  
  
  def sha1_Data_r(r, a): 
      b = (ct.c_byte * 41)()
      _res = CLIB.sha1_Data(r, a, b)
      return bytes(_res), bytes(b)
  
  
  def sha256_Transform(state_in, data, state_out): 
      CLIB.sha256_Transform(ct.byref(state_in), ct.byref(data), ct.byref(state_out))
  
  
  def sha256_Transform_r(state_in, data): 
      state_out = (tt.uint32_t)()
      CLIB.sha256_Transform(ct.byref(state_in), ct.byref(data), ct.byref(state_out))
      return state_out
  
  
  def sha256_Init(r): 
      CLIB.sha256_Init(ct.byref(r))
  
  
  def sha256_Init_r(): 
      r = (tt.SHA256_CTX)()
      CLIB.sha256_Init(ct.byref(r))
      return r
  
  
  def sha256_Update(r, a, b): 
      CLIB.sha256_Update(ct.byref(r), a, b)
  
  
  def sha256_Update_r(a, b): 
      r = (tt.SHA256_CTX)()
      CLIB.sha256_Update(ct.byref(r), a, b)
      return r
  
  
  def sha256_Final(r, a): 
      CLIB.sha256_Final(ct.byref(r), a)
  
  
  def sha256_Final_r(): 
      r = (tt.SHA256_CTX)()
      a = (tt.uint8_t * 32)()
      CLIB.sha256_Final(ct.byref(r), a)
      return r, bytes(a)
  
  
  def sha256_End(r, a): 
      return bytes(CLIB.sha256_End(ct.byref(r), a))
  
  
  def sha256_End_r(): 
      r = (tt.SHA256_CTX)()
      a = (ct.c_byte * 65)()
      _res = CLIB.sha256_End(ct.byref(r), a)
      return bytes(_res), r, bytes(a)
  
  
  def sha256_Raw(r, a, b): 
      CLIB.sha256_Raw(r, a, b)
  
  
  def sha256_Raw_r(r, a): 
      b = (tt.uint8_t * 32)()
      CLIB.sha256_Raw(r, a, b)
      return bytes(b)
  
  
  def sha256_Data(r, a, b): 
      return bytes(CLIB.sha256_Data(r, a, b))
  
  
  def sha256_Data_r(r, a): 
      b = (ct.c_byte * 65)()
      _res = CLIB.sha256_Data(r, a, b)
      return bytes(_res), bytes(b)
  
  
  def sha512_Transform(state_in, data, state_out): 
      CLIB.sha512_Transform(ct.byref(state_in), ct.byref(data), ct.byref(state_out))
  
  
  def sha512_Transform_r(state_in, data): 
      state_out = (tt.uint64_t)()
      CLIB.sha512_Transform(ct.byref(state_in), ct.byref(data), ct.byref(state_out))
      return state_out
  
  
  def sha512_Init(r): 
      CLIB.sha512_Init(ct.byref(r))
  
  
  def sha512_Init_r(): 
      r = (tt.SHA512_CTX)()
      CLIB.sha512_Init(ct.byref(r))
      return r
  
  
  def sha512_Update(r, a, b): 
      CLIB.sha512_Update(ct.byref(r), a, b)
  
  
  def sha512_Update_r(a, b): 
      r = (tt.SHA512_CTX)()
      CLIB.sha512_Update(ct.byref(r), a, b)
      return r
  
  
  def sha512_Final(r, a): 
      CLIB.sha512_Final(ct.byref(r), a)
  
  
  def sha512_Final_r(): 
      r = (tt.SHA512_CTX)()
      a = (tt.uint8_t * 64)()
      CLIB.sha512_Final(ct.byref(r), a)
      return r, bytes(a)
  
  
  def sha512_End(r, a): 
      return bytes(CLIB.sha512_End(ct.byref(r), a))
  
  
  def sha512_End_r(): 
      r = (tt.SHA512_CTX)()
      a = (ct.c_byte * 129)()
      _res = CLIB.sha512_End(ct.byref(r), a)
      return bytes(_res), r, bytes(a)
  
  
  def sha512_Raw(r, a, b): 
      CLIB.sha512_Raw(r, a, b)
  
  
  def sha512_Raw_r(r, a): 
      b = (tt.uint8_t * 64)()
      CLIB.sha512_Raw(r, a, b)
      return bytes(b)
  
  
  def sha512_Data(r, a, b): 
      return bytes(CLIB.sha512_Data(r, a, b))
  
  
  def sha512_Data_r(r, a): 
      b = (ct.c_byte * 129)()
      _res = CLIB.sha512_Data(r, a, b)
      return bytes(_res), bytes(b)
  
  
  def sha3_224_Init(ctx): 
      CLIB.sha3_224_Init(ct.byref(ctx))
  
  
  def sha3_224_Init_r(): 
      ctx = (tt.SHA3_CTX)()
      CLIB.sha3_224_Init(ct.byref(ctx))
      return ctx
  
  
  def sha3_256_Init(ctx): 
      CLIB.sha3_256_Init(ct.byref(ctx))
  
  
  def sha3_256_Init_r(): 
      ctx = (tt.SHA3_CTX)()
      CLIB.sha3_256_Init(ct.byref(ctx))
      return ctx
  
  
  def sha3_384_Init(ctx): 
      CLIB.sha3_384_Init(ct.byref(ctx))
  
  
  def sha3_384_Init_r(): 
      ctx = (tt.SHA3_CTX)()
      CLIB.sha3_384_Init(ct.byref(ctx))
      return ctx
  
  
  def sha3_512_Init(ctx): 
      CLIB.sha3_512_Init(ct.byref(ctx))
  
  
  def sha3_512_Init_r(): 
      ctx = (tt.SHA3_CTX)()
      CLIB.sha3_512_Init(ct.byref(ctx))
      return ctx
  
  
  def sha3_Update(ctx, msg, size): 
      CLIB.sha3_Update(ct.byref(ctx), msg, size)
  
  
  def sha3_Update_r(msg, size): 
      ctx = (tt.SHA3_CTX)()
      CLIB.sha3_Update(ct.byref(ctx), msg, size)
      return ctx
  
  
  def sha3_Final(ctx, result): 
      CLIB.sha3_Final(ct.byref(ctx), result)
  
  
  def sha3_Final_r(): 
      ctx = (tt.SHA3_CTX)()
      result = (ct.c_ubyte)()
      CLIB.sha3_Final(ct.byref(ctx), result)
      return ctx, bytes(result)
  
  
  def keccak_Final(ctx, result): 
      CLIB.keccak_Final(ct.byref(ctx), result)
  
  
  def keccak_Final_r(): 
      ctx = (tt.SHA3_CTX)()
      result = (ct.c_ubyte)()
      CLIB.keccak_Final(ct.byref(ctx), result)
      return ctx, bytes(result)
  
  
  def keccak_256(data, len, digest): 
      CLIB.keccak_256(data, len, digest)
  
  
  def keccak_256_r(data, len): 
      digest = (ct.c_ubyte)()
      CLIB.keccak_256(data, len, digest)
      return bytes(digest)
  
  
  def keccak_512(data, len, digest): 
      CLIB.keccak_512(data, len, digest)
  
  
  def keccak_512_r(data, len): 
      digest = (ct.c_ubyte)()
      CLIB.keccak_512(data, len, digest)
      return bytes(digest)
  
  
  def sha3_256(data, len, digest): 
      CLIB.sha3_256(data, len, digest)
  
  
  def sha3_256_r(data, len): 
      digest = (ct.c_ubyte)()
      CLIB.sha3_256(data, len, digest)
      return bytes(digest)
  
  
  def sha3_512(data, len, digest): 
      CLIB.sha3_512(data, len, digest)
  
  
  def sha3_512_r(data, len): 
      digest = (ct.c_ubyte)()
      CLIB.sha3_512(data, len, digest)
      return bytes(digest)
  
  
  def blake256_Init(r): 
      CLIB.blake256_Init(ct.byref(r))
  
  
  def blake256_Init_r(): 
      r = (tt.BLAKE256_CTX)()
      CLIB.blake256_Init(ct.byref(r))
      return r
  
  
  def blake256_Update(r, a, b): 
      CLIB.blake256_Update(ct.byref(r), a, b)
  
  
  def blake256_Update_r(a, b): 
      r = (tt.BLAKE256_CTX)()
      CLIB.blake256_Update(ct.byref(r), a, b)
      return r
  
  
  def blake256_Final(r, a): 
      CLIB.blake256_Final(ct.byref(r), a)
  
  
  def blake256_Final_r(): 
      r = (tt.BLAKE256_CTX)()
      a = (tt.uint8_t)()
      CLIB.blake256_Final(ct.byref(r), a)
      return r, bytes(a)
  
  
  def blake256(r, a, b): 
      CLIB.blake256(r, a, b)
  
  
  def blake256_r(r, a): 
      b = (tt.uint8_t)()
      CLIB.blake256(r, a, b)
      return bytes(b)
  
  
  def groestl512_Init(cc): 
      CLIB.groestl512_Init(ct.byref(cc))
  
  
  def groestl512_Init_r(): 
      cc = (ct.c_void_p)()
      CLIB.groestl512_Init(ct.byref(cc))
      return cc
  
  
  def groestl512_Update(cc, data, len): 
      CLIB.groestl512_Update(ct.byref(cc), ct.byref(data), len)
  
  
  def groestl512_Update_r(data, len): 
      cc = (ct.c_void_p)()
      CLIB.groestl512_Update(ct.byref(cc), ct.byref(data), len)
      return cc
  
  
  def groestl512_Final(cc, dst): 
      CLIB.groestl512_Final(ct.byref(cc), ct.byref(dst))
  
  
  def groestl512_Final_r(): 
      cc = (ct.c_void_p)()
      dst = (ct.c_void_p)()
      CLIB.groestl512_Final(ct.byref(cc), ct.byref(dst))
      return cc, dst
  
  
  def groestl512_DoubleTrunc(cc, dst): 
      CLIB.groestl512_DoubleTrunc(ct.byref(cc), ct.byref(dst))
  
  
  def groestl512_DoubleTrunc_r(): 
      cc = (ct.c_void_p)()
      dst = (ct.c_void_p)()
      CLIB.groestl512_DoubleTrunc(ct.byref(cc), ct.byref(dst))
      return cc, dst
  
  
  def blake2b_Init(S, outlen): 
      return int(CLIB.blake2b_Init(ct.byref(S), outlen))
  
  
  def blake2b_Init_r(outlen): 
      S = (tt.blake2b_state)()
      _res = CLIB.blake2b_Init(ct.byref(S), outlen)
      return int(_res), S
  
  
  def blake2b_InitKey(S, outlen, key, keylen): 
      return int(CLIB.blake2b_InitKey(ct.byref(S), outlen, ct.byref(key), keylen))
  
  
  def blake2b_InitKey_r(outlen, key, keylen): 
      S = (tt.blake2b_state)()
      _res = CLIB.blake2b_InitKey(ct.byref(S), outlen, ct.byref(key), keylen)
      return int(_res), S
  
  
  def blake2b_InitPersonal(S, outlen, personal, personal_len): 
      return int(CLIB.blake2b_InitPersonal(ct.byref(S), outlen, ct.byref(personal), personal_len))
  
  
  def blake2b_InitPersonal_r(outlen, personal, personal_len): 
      S = (tt.blake2b_state)()
      _res = CLIB.blake2b_InitPersonal(ct.byref(S), outlen, ct.byref(personal), personal_len)
      return int(_res), S
  
  
  def blake2b_Update(S, pin, inlen): 
      return int(CLIB.blake2b_Update(ct.byref(S), ct.byref(pin), inlen))
  
  
  def blake2b_Update_r(pin, inlen): 
      S = (tt.blake2b_state)()
      _res = CLIB.blake2b_Update(ct.byref(S), ct.byref(pin), inlen)
      return int(_res), S
  
  
  def blake2b_Final(S, out, outlen): 
      return int(CLIB.blake2b_Final(ct.byref(S), ct.byref(out), outlen))
  
  
  def blake2b_Final_r(outlen): 
      S = (tt.blake2b_state)()
      out = (ct.c_void_p)()
      _res = CLIB.blake2b_Final(ct.byref(S), ct.byref(out), outlen)
      return int(_res), S, out
  
  
  def blake2b(msg, msg_len, out, outlen): 
      return int(CLIB.blake2b(msg, msg_len, ct.byref(out), outlen))
  
  
  def blake2b_Key(msg, msg_len, key, keylen, out, outlen): 
      return int(CLIB.blake2b_Key(msg, msg_len, ct.byref(key), keylen, ct.byref(out), outlen))
  
  
  def hasher_Init(hasher, type): 
      CLIB.hasher_Init(ct.byref(hasher), type)
  
  
  def hasher_Init_r(): 
      hasher = (tt.Hasher)()
      type = (tt.HasherType)()
      CLIB.hasher_Init(ct.byref(hasher), type)
      return hasher, type
  
  
  def hasher_Reset(hasher): 
      CLIB.hasher_Reset(ct.byref(hasher))
  
  
  def hasher_Reset_r(): 
      hasher = (tt.Hasher)()
      CLIB.hasher_Reset(ct.byref(hasher))
      return hasher
  
  
  def hasher_Update(hasher, data, length): 
      CLIB.hasher_Update(ct.byref(hasher), data, length)
  
  
  def hasher_Update_r(data, length): 
      hasher = (tt.Hasher)()
      CLIB.hasher_Update(ct.byref(hasher), data, length)
      return hasher
  
  
  def hasher_Final(hasher, hash): 
      CLIB.hasher_Final(ct.byref(hasher), hash)
  
  
  def hasher_Final_r(): 
      hasher = (tt.Hasher)()
      hash = (tt.uint8_t * 32)()
      CLIB.hasher_Final(ct.byref(hasher), hash)
      return hasher, bytes(hash)
  
  
  def hasher_Raw(type, data, length, hash): 
      CLIB.hasher_Raw(type, data, length, hash)
  
  
  def hasher_Raw_r(data, length, hash): 
      type = (tt.HasherType)()
      CLIB.hasher_Raw(type, data, length, hash)
      return type
  
  
  def base58_encode_check(data, len, hasher_type, str, strsize): 
      return int(CLIB.base58_encode_check(data, len, hasher_type, str, strsize))
  
  
  def base58_decode_check(str, hasher_type, data, datalen): 
      return int(CLIB.base58_decode_check(str, hasher_type, data, datalen))
  
  
  def b58tobin(bin, binszp, b58): 
      return int(CLIB.b58tobin(ct.byref(bin), ct.byref(binszp), b58))
  
  
  def b58tobin_r(b58): 
      bin = (ct.c_void_p)()
      binszp = (tt.size_t)()
      _res = CLIB.b58tobin(ct.byref(bin), ct.byref(binszp), b58)
      return int(_res), bin, binszp
  
  
  def b58check(bin, binsz, hasher_type, base58str): 
      return int(CLIB.b58check(ct.byref(bin), binsz, hasher_type, base58str))
  
  
  def b58enc(b58, b58sz, data, binsz): 
      return int(CLIB.b58enc(b58, ct.byref(b58sz), ct.byref(data), binsz))
  
  
  def b58enc_r(data, binsz): 
      b58 = (ct.c_byte)()
      b58sz = (tt.size_t)()
      _res = CLIB.b58enc(b58, ct.byref(b58sz), ct.byref(data), binsz)
      return int(_res), bytes(b58), b58sz
  
  
  def random32(): 
      return int(CLIB.random32())
  
  
  def random_buffer(buf, len): 
      CLIB.random_buffer(buf, len)
  
  
  def random_buffer_r(len): 
      buf = (tt.uint8_t)()
      CLIB.random_buffer(buf, len)
      return bytes(buf)
  
  
  def random_uniform(n): 
      return int(CLIB.random_uniform(n))
  
  
  def random_permute(buf, len): 
      CLIB.random_permute(buf, len)
  
  
  def random_permute_r(len): 
      buf = (ct.c_byte)()
      CLIB.random_permute(buf, len)
      return bytes(buf)
  
  
  def random_init(): 
      return int(CLIB.random_init())
  
  
  def hmac_sha256_Init(hctx, key, keylen): 
      CLIB.hmac_sha256_Init(ct.byref(hctx), key, keylen)
  
  
  def hmac_sha256_Init_r(key, keylen): 
      hctx = (tt.HMAC_SHA256_CTX)()
      CLIB.hmac_sha256_Init(ct.byref(hctx), key, keylen)
      return hctx
  
  
  def hmac_sha256_Update(hctx, msg, msglen): 
      CLIB.hmac_sha256_Update(ct.byref(hctx), msg, msglen)
  
  
  def hmac_sha256_Update_r(msg, msglen): 
      hctx = (tt.HMAC_SHA256_CTX)()
      CLIB.hmac_sha256_Update(ct.byref(hctx), msg, msglen)
      return hctx
  
  
  def hmac_sha256_Final(hctx, hmac): 
      CLIB.hmac_sha256_Final(ct.byref(hctx), hmac)
  
  
  def hmac_sha256_Final_r(): 
      hctx = (tt.HMAC_SHA256_CTX)()
      hmac = (tt.uint8_t)()
      CLIB.hmac_sha256_Final(ct.byref(hctx), hmac)
      return hctx, bytes(hmac)
  
  
  def hmac_sha256(key, keylen, msg, msglen, hmac): 
      CLIB.hmac_sha256(key, keylen, msg, msglen, hmac)
  
  
  def hmac_sha256_r(key, keylen, msg, msglen): 
      hmac = (tt.uint8_t)()
      CLIB.hmac_sha256(key, keylen, msg, msglen, hmac)
      return bytes(hmac)
  
  
  def hmac_sha256_prepare(key, keylen, opad_digest, ipad_digest): 
      CLIB.hmac_sha256_prepare(key, keylen, ct.byref(opad_digest), ct.byref(ipad_digest))
  
  
  def hmac_sha256_prepare_r(key, keylen): 
      opad_digest = (tt.uint32_t)()
      ipad_digest = (tt.uint32_t)()
      CLIB.hmac_sha256_prepare(key, keylen, ct.byref(opad_digest), ct.byref(ipad_digest))
      return bytes(opad_digest), int(ipad_digest)
  
  
  def hmac_sha512_Init(hctx, key, keylen): 
      CLIB.hmac_sha512_Init(ct.byref(hctx), key, keylen)
  
  
  def hmac_sha512_Init_r(key, keylen): 
      hctx = (tt.HMAC_SHA512_CTX)()
      CLIB.hmac_sha512_Init(ct.byref(hctx), key, keylen)
      return hctx
  
  
  def hmac_sha512_Update(hctx, msg, msglen): 
      CLIB.hmac_sha512_Update(ct.byref(hctx), msg, msglen)
  
  
  def hmac_sha512_Update_r(msg, msglen): 
      hctx = (tt.HMAC_SHA512_CTX)()
      CLIB.hmac_sha512_Update(ct.byref(hctx), msg, msglen)
      return hctx
  
  
  def hmac_sha512_Final(hctx, hmac): 
      CLIB.hmac_sha512_Final(ct.byref(hctx), hmac)
  
  
  def hmac_sha512_Final_r(): 
      hctx = (tt.HMAC_SHA512_CTX)()
      hmac = (tt.uint8_t)()
      CLIB.hmac_sha512_Final(ct.byref(hctx), hmac)
      return hctx, bytes(hmac)
  
  
  def hmac_sha512(key, keylen, msg, msglen, hmac): 
      CLIB.hmac_sha512(key, keylen, msg, msglen, hmac)
  
  
  def hmac_sha512_r(key, keylen, msg, msglen): 
      hmac = (tt.uint8_t)()
      CLIB.hmac_sha512(key, keylen, msg, msglen, hmac)
      return bytes(hmac)
  
  
  def hmac_sha512_prepare(key, keylen, opad_digest, ipad_digest): 
      CLIB.hmac_sha512_prepare(key, keylen, ct.byref(opad_digest), ct.byref(ipad_digest))
  
  
  def hmac_sha512_prepare_r(key, keylen): 
      opad_digest = (tt.uint64_t)()
      ipad_digest = (tt.uint64_t)()
      CLIB.hmac_sha512_prepare(key, keylen, ct.byref(opad_digest), ct.byref(ipad_digest))
      return bytes(opad_digest), int(ipad_digest)
  
  
  def pbkdf2_hmac_sha256_Init(pctx, pass_, passlen, salt, saltlen): 
      CLIB.pbkdf2_hmac_sha256_Init(ct.byref(pctx), pass_, passlen, salt, saltlen)
  
  
  def pbkdf2_hmac_sha256_Init_r(pass_, passlen, salt, saltlen): 
      pctx = (tt.PBKDF2_HMAC_SHA256_CTX)()
      CLIB.pbkdf2_hmac_sha256_Init(ct.byref(pctx), pass_, passlen, salt, saltlen)
      return pctx
  
  
  def pbkdf2_hmac_sha256_Update(pctx, iterations): 
      CLIB.pbkdf2_hmac_sha256_Update(ct.byref(pctx), iterations)
  
  
  def pbkdf2_hmac_sha256_Update_r(iterations): 
      pctx = (tt.PBKDF2_HMAC_SHA256_CTX)()
      CLIB.pbkdf2_hmac_sha256_Update(ct.byref(pctx), iterations)
      return pctx
  
  
  def pbkdf2_hmac_sha256_Final(pctx, key): 
      CLIB.pbkdf2_hmac_sha256_Final(ct.byref(pctx), key)
  
  
  def pbkdf2_hmac_sha256_Final_r(): 
      pctx = (tt.PBKDF2_HMAC_SHA256_CTX)()
      key = (tt.uint8_t)()
      CLIB.pbkdf2_hmac_sha256_Final(ct.byref(pctx), key)
      return pctx, bytes(key)
  
  
  def pbkdf2_hmac_sha256(pass_, passlen, salt, saltlen, iterations, key): 
      CLIB.pbkdf2_hmac_sha256(pass_, passlen, salt, saltlen, iterations, key)
  
  
  def pbkdf2_hmac_sha256_r(pass_, passlen, salt, saltlen, iterations): 
      key = (tt.uint8_t)()
      CLIB.pbkdf2_hmac_sha256(pass_, passlen, salt, saltlen, iterations, key)
      return bytes(key)
  
  
  def pbkdf2_hmac_sha512_Init(pctx, pass_, passlen, salt, saltlen): 
      CLIB.pbkdf2_hmac_sha512_Init(ct.byref(pctx), pass_, passlen, salt, saltlen)
  
  
  def pbkdf2_hmac_sha512_Init_r(pass_, passlen, salt, saltlen): 
      pctx = (tt.PBKDF2_HMAC_SHA512_CTX)()
      CLIB.pbkdf2_hmac_sha512_Init(ct.byref(pctx), pass_, passlen, salt, saltlen)
      return pctx
  
  
  def pbkdf2_hmac_sha512_Update(pctx, iterations): 
      CLIB.pbkdf2_hmac_sha512_Update(ct.byref(pctx), iterations)
  
  
  def pbkdf2_hmac_sha512_Update_r(iterations): 
      pctx = (tt.PBKDF2_HMAC_SHA512_CTX)()
      CLIB.pbkdf2_hmac_sha512_Update(ct.byref(pctx), iterations)
      return pctx
  
  
  def pbkdf2_hmac_sha512_Final(pctx, key): 
      CLIB.pbkdf2_hmac_sha512_Final(ct.byref(pctx), key)
  
  
  def pbkdf2_hmac_sha512_Final_r(): 
      pctx = (tt.PBKDF2_HMAC_SHA512_CTX)()
      key = (tt.uint8_t)()
      CLIB.pbkdf2_hmac_sha512_Final(ct.byref(pctx), key)
      return pctx, bytes(key)
  
  
  def pbkdf2_hmac_sha512(pass_, passlen, salt, saltlen, iterations, key): 
      CLIB.pbkdf2_hmac_sha512(pass_, passlen, salt, saltlen, iterations, key)
  
  
  def pbkdf2_hmac_sha512_r(pass_, passlen, salt, saltlen, iterations): 
      key = (tt.uint8_t)()
      CLIB.pbkdf2_hmac_sha512(pass_, passlen, salt, saltlen, iterations, key)
      return bytes(key)
  
  
  def read_be(data): 
      return int(CLIB.read_be(data))
  
  
  def write_be(data, x): 
      CLIB.write_be(data, x)
  
  
  def write_be_r(x): 
      data = (tt.uint8_t)()
      CLIB.write_be(data, x)
      return bytes(data)
  
  
  def read_le(data): 
      return int(CLIB.read_le(data))
  
  
  def write_le(data, x): 
      CLIB.write_le(data, x)
  
  
  def write_le_r(x): 
      data = (tt.uint8_t)()
      CLIB.write_le(data, x)
      return bytes(data)
  
  
  def bn_read_be(in_number, out_number): 
      CLIB.bn_read_be(in_number, ct.byref(out_number))
  
  
  def bn_read_be_r(in_number): 
      out_number = (tt.bignum256)()
      CLIB.bn_read_be(in_number, ct.byref(out_number))
      return bytes(out_number)
  
  
  def bn_write_be(in_number, out_number): 
      CLIB.bn_write_be(ct.byref(in_number), out_number)
  
  
  def bn_write_be_r(in_number): 
      out_number = (tt.uint8_t)()
      CLIB.bn_write_be(ct.byref(in_number), out_number)
      return out_number
  
  
  def bn_read_le(in_number, out_number): 
      CLIB.bn_read_le(in_number, ct.byref(out_number))
  
  
  def bn_read_le_r(in_number): 
      out_number = (tt.bignum256)()
      CLIB.bn_read_le(in_number, ct.byref(out_number))
      return bytes(out_number)
  
  
  def bn_write_le(in_number, out_number): 
      CLIB.bn_write_le(ct.byref(in_number), out_number)
  
  
  def bn_write_le_r(in_number): 
      out_number = (tt.uint8_t)()
      CLIB.bn_write_le(ct.byref(in_number), out_number)
      return out_number
  
  
  def bn_read_uint32(in_number, out_number): 
      CLIB.bn_read_uint32(in_number, ct.byref(out_number))
  
  
  def bn_read_uint32_r(in_number): 
      out_number = (tt.bignum256)()
      CLIB.bn_read_uint32(in_number, ct.byref(out_number))
      return int(out_number)
  
  
  def bn_read_uint64(in_number, out_number): 
      CLIB.bn_read_uint64(in_number, ct.byref(out_number))
  
  
  def bn_read_uint64_r(in_number): 
      out_number = (tt.bignum256)()
      CLIB.bn_read_uint64(in_number, ct.byref(out_number))
      return int(out_number)
  
  
  def bn_bitcount(a): 
      return int(CLIB.bn_bitcount(ct.byref(a)))
  
  
  def bn_digitcount(a): 
      return int(CLIB.bn_digitcount(ct.byref(a)))
  
  
  def bn_zero(a): 
      CLIB.bn_zero(ct.byref(a))
  
  
  def bn_zero_r(): 
      a = (tt.bignum256)()
      CLIB.bn_zero(ct.byref(a))
      return a
  
  
  def bn_is_zero(a): 
      return int(CLIB.bn_is_zero(ct.byref(a)))
  
  
  def bn_one(a): 
      CLIB.bn_one(ct.byref(a))
  
  
  def bn_one_r(): 
      a = (tt.bignum256)()
      CLIB.bn_one(ct.byref(a))
      return a
  
  
  def bn_is_less(a, b): 
      return int(CLIB.bn_is_less(ct.byref(a), ct.byref(b)))
  
  
  def bn_is_equal(a, b): 
      return int(CLIB.bn_is_equal(ct.byref(a), ct.byref(b)))
  
  
  def bn_cmov(res, cond, truecase, falsecase): 
      CLIB.bn_cmov(ct.byref(res), cond, ct.byref(truecase), ct.byref(falsecase))
  
  
  def bn_cmov_r(cond, truecase, falsecase): 
      res = (tt.bignum256)()
      CLIB.bn_cmov(ct.byref(res), cond, ct.byref(truecase), ct.byref(falsecase))
      return res
  
  
  def bn_lshift(a): 
      CLIB.bn_lshift(ct.byref(a))
  
  
  def bn_lshift_r(): 
      a = (tt.bignum256)()
      CLIB.bn_lshift(ct.byref(a))
      return a
  
  
  def bn_rshift(a): 
      CLIB.bn_rshift(ct.byref(a))
  
  
  def bn_rshift_r(): 
      a = (tt.bignum256)()
      CLIB.bn_rshift(ct.byref(a))
      return a
  
  
  def bn_setbit(a, bit): 
      CLIB.bn_setbit(ct.byref(a), bit)
  
  
  def bn_setbit_r(): 
      a = (tt.bignum256)()
      bit = (tt.uint8_t)()
      CLIB.bn_setbit(ct.byref(a), bit)
      return a, bit
  
  
  def bn_clearbit(a, bit): 
      CLIB.bn_clearbit(ct.byref(a), bit)
  
  
  def bn_clearbit_r(): 
      a = (tt.bignum256)()
      bit = (tt.uint8_t)()
      CLIB.bn_clearbit(ct.byref(a), bit)
      return a, bit
  
  
  def bn_testbit(a, bit): 
      return int(CLIB.bn_testbit(ct.byref(a), bit))
  
  
  def bn_testbit_r(): 
      a = (tt.bignum256)()
      bit = (tt.uint8_t)()
      _res = CLIB.bn_testbit(ct.byref(a), bit)
      return int(_res), a, bit
  
  
  def bn_xor(a, b, c): 
      CLIB.bn_xor(ct.byref(a), ct.byref(b), ct.byref(c))
  
  
  def bn_xor_r(b, c): 
      a = (tt.bignum256)()
      CLIB.bn_xor(ct.byref(a), ct.byref(b), ct.byref(c))
      return a
  
  
  def bn_mult_half(x, prime): 
      CLIB.bn_mult_half(ct.byref(x), ct.byref(prime))
  
  
  def bn_mult_half_r(prime): 
      x = (tt.bignum256)()
      CLIB.bn_mult_half(ct.byref(x), ct.byref(prime))
      return x
  
  
  def bn_mult_k(x, k, prime): 
      CLIB.bn_mult_k(ct.byref(x), k, ct.byref(prime))
  
  
  def bn_mult_k_r(prime): 
      x = (tt.bignum256)()
      k = (tt.uint8_t)()
      CLIB.bn_mult_k(ct.byref(x), k, ct.byref(prime))
      return x, k
  
  
  def bn_mod(x, prime): 
      CLIB.bn_mod(ct.byref(x), ct.byref(prime))
  
  
  def bn_mod_r(prime): 
      x = (tt.bignum256)()
      CLIB.bn_mod(ct.byref(x), ct.byref(prime))
      return x
  
  
  def bn_multiply(k, x, prime): 
      CLIB.bn_multiply(ct.byref(k), ct.byref(x), ct.byref(prime))
  
  
  def bn_fast_mod(x, prime): 
      CLIB.bn_fast_mod(ct.byref(x), ct.byref(prime))
  
  
  def bn_fast_mod_r(prime): 
      x = (tt.bignum256)()
      CLIB.bn_fast_mod(ct.byref(x), ct.byref(prime))
      return x
  
  
  def bn_sqrt(x, prime): 
      CLIB.bn_sqrt(ct.byref(x), ct.byref(prime))
  
  
  def bn_sqrt_r(prime): 
      x = (tt.bignum256)()
      CLIB.bn_sqrt(ct.byref(x), ct.byref(prime))
      return x
  
  
  def bn_inverse(x, prime): 
      CLIB.bn_inverse(ct.byref(x), ct.byref(prime))
  
  
  def bn_inverse_r(prime): 
      x = (tt.bignum256)()
      CLIB.bn_inverse(ct.byref(x), ct.byref(prime))
      return x
  
  
  def bn_normalize(a): 
      CLIB.bn_normalize(ct.byref(a))
  
  
  def bn_normalize_r(): 
      a = (tt.bignum256)()
      CLIB.bn_normalize(ct.byref(a))
      return a
  
  
  def bn_add(a, b): 
      CLIB.bn_add(ct.byref(a), ct.byref(b))
  
  
  def bn_add_r(b): 
      a = (tt.bignum256)()
      CLIB.bn_add(ct.byref(a), ct.byref(b))
      return a
  
  
  def bn_addmod(a, b, prime): 
      CLIB.bn_addmod(ct.byref(a), ct.byref(b), ct.byref(prime))
  
  
  def bn_addmod_r(b, prime): 
      a = (tt.bignum256)()
      CLIB.bn_addmod(ct.byref(a), ct.byref(b), ct.byref(prime))
      return a
  
  
  def bn_addi(a, b): 
      CLIB.bn_addi(ct.byref(a), b)
  
  
  def bn_addi_r(b): 
      a = (tt.bignum256)()
      CLIB.bn_addi(ct.byref(a), b)
      return a
  
  
  def bn_subi(a, b, prime): 
      CLIB.bn_subi(ct.byref(a), b, ct.byref(prime))
  
  
  def bn_subi_r(b, prime): 
      a = (tt.bignum256)()
      CLIB.bn_subi(ct.byref(a), b, ct.byref(prime))
      return a
  
  
  def bn_subtractmod(a, b, res, prime): 
      CLIB.bn_subtractmod(ct.byref(a), ct.byref(b), ct.byref(res), ct.byref(prime))
  
  
  def bn_subtract(a, b, res): 
      CLIB.bn_subtract(ct.byref(a), ct.byref(b), ct.byref(res))
  
  
  def bn_subtract_r(a, b): 
      res = (tt.bignum256)()
      CLIB.bn_subtract(ct.byref(a), ct.byref(b), ct.byref(res))
      return res
  
  
  def bn_divmod58(a, r): 
      CLIB.bn_divmod58(ct.byref(a), ct.byref(r))
  
  
  def bn_divmod58_r(): 
      a = (tt.bignum256)()
      r = (tt.uint32_t)()
      CLIB.bn_divmod58(ct.byref(a), ct.byref(r))
      return a, r
  
  
  def bn_divmod1000(a, r): 
      CLIB.bn_divmod1000(ct.byref(a), ct.byref(r))
  
  
  def bn_divmod1000_r(): 
      a = (tt.bignum256)()
      r = (tt.uint32_t)()
      CLIB.bn_divmod1000(ct.byref(a), ct.byref(r))
      return a, r
  
  
  def bn_format(amnt, prefix, suffix, decimals, exponent, trailing, out, outlen): 
      return int(CLIB.bn_format(ct.byref(amnt), prefix, suffix, decimals, exponent, trailing, out, outlen))
  
  
  def ECRYPT_init(): 
      CLIB.ECRYPT_init()
  
  
  def ECRYPT_keysetup(ctx, key, keysize, ivsize): 
      CLIB.ECRYPT_keysetup(ct.byref(ctx), ct.byref(key), keysize, ivsize)
  
  
  def ECRYPT_keysetup_r(key, keysize, ivsize): 
      ctx = (tt.ECRYPT_ctx)()
      CLIB.ECRYPT_keysetup(ct.byref(ctx), ct.byref(key), keysize, ivsize)
      return ctx
  
  
  def ECRYPT_ivsetup(ctx, iv): 
      CLIB.ECRYPT_ivsetup(ct.byref(ctx), ct.byref(iv))
  
  
  def ECRYPT_ivsetup_r(iv): 
      ctx = (tt.ECRYPT_ctx)()
      CLIB.ECRYPT_ivsetup(ct.byref(ctx), ct.byref(iv))
      return ctx
  
  
  def ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, msglen): 
      CLIB.ECRYPT_encrypt_bytes(ct.byref(ctx), ct.byref(plaintext), ct.byref(ciphertext), msglen)
  
  
  def ECRYPT_encrypt_bytes_r(plaintext, ciphertext, msglen): 
      ctx = (tt.ECRYPT_ctx)()
      CLIB.ECRYPT_encrypt_bytes(ct.byref(ctx), ct.byref(plaintext), ct.byref(ciphertext), msglen)
      return ctx
  
  
  def ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, msglen): 
      CLIB.ECRYPT_decrypt_bytes(ct.byref(ctx), ct.byref(ciphertext), ct.byref(plaintext), msglen)
  
  
  def ECRYPT_decrypt_bytes_r(ciphertext, plaintext, msglen): 
      ctx = (tt.ECRYPT_ctx)()
      CLIB.ECRYPT_decrypt_bytes(ct.byref(ctx), ct.byref(ciphertext), ct.byref(plaintext), msglen)
      return ctx
  
  
  def ECRYPT_keystream_bytes(ctx, keystream, length): 
      CLIB.ECRYPT_keystream_bytes(ct.byref(ctx), ct.byref(keystream), length)
  
  
  def ECRYPT_keystream_bytes_r(): 
      ctx = (tt.ECRYPT_ctx)()
      keystream = (tt.u8)()
      length = (tt.u32)()
      CLIB.ECRYPT_keystream_bytes(ct.byref(ctx), ct.byref(keystream), length)
      return ctx, keystream, length
  
  
  def poly1305_init(ctx, key): 
      CLIB.poly1305_init(ct.byref(ctx), key)
  
  
  def poly1305_init_r(key): 
      ctx = (tt.poly1305_context)()
      CLIB.poly1305_init(ct.byref(ctx), key)
      return ctx
  
  
  def poly1305_update(ctx, m, bytes): 
      CLIB.poly1305_update(ct.byref(ctx), m, bytes)
  
  
  def poly1305_update_r(m, bytes): 
      ctx = (tt.poly1305_context)()
      CLIB.poly1305_update(ct.byref(ctx), m, bytes)
      return ctx
  
  
  def poly1305_finish(ctx, mac): 
      CLIB.poly1305_finish(ct.byref(ctx), mac)
  
  
  def poly1305_finish_r(): 
      ctx = (tt.poly1305_context)()
      mac = (ct.c_ubyte * 16)()
      CLIB.poly1305_finish(ct.byref(ctx), mac)
      return ctx, bytes(mac)
  
  
  def poly1305_auth(mac, m, bytes, key): 
      CLIB.poly1305_auth(mac, m, bytes, key)
  
  
  def poly1305_auth_r(m, bytes, key): 
      mac = (ct.c_ubyte * 16)()
      CLIB.poly1305_auth(mac, m, bytes, key)
      return bytes(mac)
  
  
  def poly1305_verify(mac1, mac2): 
      return int(CLIB.poly1305_verify(mac1, mac2))
  
  
  def poly1305_power_on_self_test(): 
      return int(CLIB.poly1305_power_on_self_test())
  
  
  def xchacha20poly1305_init(ctx, key, nonce): 
      CLIB.xchacha20poly1305_init(ct.byref(ctx), key, nonce)
  
  
  def xchacha20poly1305_init_r(): 
      ctx = (tt.chacha20poly1305_ctx)()
      key = (tt.uint8_t * 32)()
      nonce = (tt.uint8_t * 24)()
      CLIB.xchacha20poly1305_init(ct.byref(ctx), key, nonce)
      return ctx, bytes(key), bytes(nonce)
  
  
  def chacha20poly1305_encrypt(ctx, in_, out, n): 
      CLIB.chacha20poly1305_encrypt(ct.byref(ctx), in_, out, n)
  
  
  def chacha20poly1305_encrypt_r(n): 
      ctx = (tt.chacha20poly1305_ctx)()
      in_ = (tt.uint8_t)()
      out = (tt.uint8_t)()
      CLIB.chacha20poly1305_encrypt(ct.byref(ctx), in_, out, n)
      return ctx, bytes(in_), bytes(out)
  
  
  def chacha20poly1305_decrypt(ctx, in_, out, n): 
      CLIB.chacha20poly1305_decrypt(ct.byref(ctx), in_, out, n)
  
  
  def chacha20poly1305_decrypt_r(n): 
      ctx = (tt.chacha20poly1305_ctx)()
      in_ = (tt.uint8_t)()
      out = (tt.uint8_t)()
      CLIB.chacha20poly1305_decrypt(ct.byref(ctx), in_, out, n)
      return ctx, bytes(in_), bytes(out)
  
  
  def chacha20poly1305_auth(ctx, in_, n): 
      CLIB.chacha20poly1305_auth(ct.byref(ctx), in_, n)
  
  
  def chacha20poly1305_auth_r(n): 
      ctx = (tt.chacha20poly1305_ctx)()
      in_ = (tt.uint8_t)()
      CLIB.chacha20poly1305_auth(ct.byref(ctx), in_, n)
      return ctx, bytes(in_)
  
  
  def chacha20poly1305_finish(ctx, mac): 
      CLIB.chacha20poly1305_finish(ct.byref(ctx), mac)
  
  
  def chacha20poly1305_finish_r(): 
      ctx = (tt.chacha20poly1305_ctx)()
      mac = (tt.uint8_t * 16)()
      CLIB.chacha20poly1305_finish(ct.byref(ctx), mac)
      return ctx, bytes(mac)
  
  
  def rfc7539_init(ctx, key, nonce): 
      CLIB.rfc7539_init(ct.byref(ctx), key, nonce)
  
  
  def rfc7539_init_r(): 
      ctx = (tt.chacha20poly1305_ctx)()
      key = (tt.uint8_t * 32)()
      nonce = (tt.uint8_t * 12)()
      CLIB.rfc7539_init(ct.byref(ctx), key, nonce)
      return ctx, bytes(key), bytes(nonce)
  
  
  def rfc7539_auth(ctx, in_, n): 
      CLIB.rfc7539_auth(ct.byref(ctx), in_, n)
  
  
  def rfc7539_auth_r(n): 
      ctx = (tt.chacha20poly1305_ctx)()
      in_ = (tt.uint8_t)()
      CLIB.rfc7539_auth(ct.byref(ctx), in_, n)
      return ctx, bytes(in_)
  
  
  def rfc7539_finish(ctx, alen, plen, mac): 
      CLIB.rfc7539_finish(ct.byref(ctx), alen, plen, mac)
  
  
  def rfc7539_finish_r(alen, plen, mac): 
      ctx = (tt.chacha20poly1305_ctx)()
      CLIB.rfc7539_finish(ct.byref(ctx), alen, plen, mac)
      return ctx
  
  
  def xmr_base58_addr_encode_check(tag, data, binsz, b58, b58sz): 
      return int(CLIB.xmr_base58_addr_encode_check(tag, data, binsz, b58, b58sz))
  
  
  def xmr_base58_addr_decode_check(addr, sz, tag, data, datalen): 
      return int(CLIB.xmr_base58_addr_decode_check(addr, sz, ct.byref(tag), ct.byref(data), datalen))
  
  
  def xmr_base58_encode(b58, b58sz, data, binsz): 
      return int(CLIB.xmr_base58_encode(b58, ct.byref(b58sz), ct.byref(data), binsz))
  
  
  def xmr_base58_encode_r(data, binsz): 
      b58 = (ct.c_byte)()
      b58sz = (tt.size_t)()
      _res = CLIB.xmr_base58_encode(b58, ct.byref(b58sz), ct.byref(data), binsz)
      return int(_res), bytes(b58), b58sz
  
  
  def xmr_base58_decode(b58, b58sz, data, binsz): 
      return int(CLIB.xmr_base58_decode(b58, b58sz, ct.byref(data), ct.byref(binsz)))
  
  
  def xmr_base58_decode_r(b58, b58sz): 
      data = (ct.c_void_p)()
      binsz = (tt.size_t)()
      _res = CLIB.xmr_base58_decode(b58, b58sz, ct.byref(data), ct.byref(binsz))
      return int(_res), bytes(data), int(binsz)
  
  
  def xmr_size_varint(num): 
      return int(CLIB.xmr_size_varint(num))
  
  
  def xmr_write_varint(buff, buff_size, num): 
      return int(CLIB.xmr_write_varint(buff, buff_size, num))
  
  
  def xmr_write_varint_r(buff_size, num): 
      buff = (tt.uint8_t)()
      _res = CLIB.xmr_write_varint(buff, buff_size, num)
      return int(_res), bytes(buff)
  
  
  def xmr_read_varint(buff, buff_size, val): 
      return int(CLIB.xmr_read_varint(buff, buff_size, ct.byref(val)))
  
  
  def xmr_read_varint_r(buff_size, val): 
      buff = (tt.uint8_t)()
      _res = CLIB.xmr_read_varint(buff, buff_size, ct.byref(val))
      return int(_res), bytes(buff)
  
  
  def curve25519_copy(out, in_): 
      CLIB.curve25519_copy(out, in_)
  
  
  def curve25519_copy_r(in_): 
      out = (tt.bignum25519)()
      CLIB.curve25519_copy(out, in_)
      return out
  
  
  def curve25519_add(out, a, b): 
      CLIB.curve25519_add(out, a, b)
  
  
  def curve25519_add_r(a, b): 
      out = (tt.bignum25519)()
      CLIB.curve25519_add(out, a, b)
      return out
  
  
  def curve25519_add_after_basic(out, a, b): 
      CLIB.curve25519_add_after_basic(out, a, b)
  
  
  def curve25519_add_after_basic_r(a, b): 
      out = (tt.bignum25519)()
      CLIB.curve25519_add_after_basic(out, a, b)
      return out
  
  
  def curve25519_add_reduce(out, a, b): 
      CLIB.curve25519_add_reduce(out, a, b)
  
  
  def curve25519_add_reduce_r(a, b): 
      out = (tt.bignum25519)()
      CLIB.curve25519_add_reduce(out, a, b)
      return out
  
  
  def curve25519_sub(out, a, b): 
      CLIB.curve25519_sub(out, a, b)
  
  
  def curve25519_sub_r(a, b): 
      out = (tt.bignum25519)()
      CLIB.curve25519_sub(out, a, b)
      return out
  
  
  def curve25519_scalar_product(out, in_, scalar): 
      CLIB.curve25519_scalar_product(out, in_, scalar)
  
  
  def curve25519_scalar_product_r(in_, scalar): 
      out = (tt.bignum25519)()
      CLIB.curve25519_scalar_product(out, in_, scalar)
      return out
  
  
  def curve25519_sub_after_basic(out, a, b): 
      CLIB.curve25519_sub_after_basic(out, a, b)
  
  
  def curve25519_sub_after_basic_r(a, b): 
      out = (tt.bignum25519)()
      CLIB.curve25519_sub_after_basic(out, a, b)
      return out
  
  
  def curve25519_sub_reduce(out, a, b): 
      CLIB.curve25519_sub_reduce(out, a, b)
  
  
  def curve25519_sub_reduce_r(a, b): 
      out = (tt.bignum25519)()
      CLIB.curve25519_sub_reduce(out, a, b)
      return out
  
  
  def curve25519_neg(out, a): 
      CLIB.curve25519_neg(out, a)
  
  
  def curve25519_neg_r(a): 
      out = (tt.bignum25519)()
      CLIB.curve25519_neg(out, a)
      return out
  
  
  def curve25519_mul(out, a, b): 
      CLIB.curve25519_mul(out, a, b)
  
  
  def curve25519_mul_r(a, b): 
      out = (tt.bignum25519)()
      CLIB.curve25519_mul(out, a, b)
      return out
  
  
  def curve25519_square(out, in_): 
      CLIB.curve25519_square(out, in_)
  
  
  def curve25519_square_r(in_): 
      out = (tt.bignum25519)()
      CLIB.curve25519_square(out, in_)
      return out
  
  
  def curve25519_square_times(out, in_, count): 
      CLIB.curve25519_square_times(out, in_, count)
  
  
  def curve25519_square_times_r(in_, count): 
      out = (tt.bignum25519)()
      CLIB.curve25519_square_times(out, in_, count)
      return out
  
  
  def curve25519_expand(out, in_): 
      CLIB.curve25519_expand(out, in_)
  
  
  def curve25519_expand_r(in_): 
      out = (tt.bignum25519)()
      CLIB.curve25519_expand(out, in_)
      return out
  
  
  def curve25519_contract(out, in_): 
      CLIB.curve25519_contract(out, in_)
  
  
  def curve25519_contract_r(in_): 
      out = (ct.c_ubyte * 32)()
      CLIB.curve25519_contract(out, in_)
      return bytes(out)
  
  
  def curve25519_swap_conditional(a, b, iswap): 
      CLIB.curve25519_swap_conditional(a, b, iswap)
  
  
  def curve25519_swap_conditional_r(iswap): 
      a = (tt.bignum25519)()
      b = (tt.bignum25519)()
      CLIB.curve25519_swap_conditional(a, b, iswap)
      return a, b
  
  
  def curve25519_pow_two5mtwo0_two250mtwo0(b): 
      CLIB.curve25519_pow_two5mtwo0_two250mtwo0(b)
  
  
  def curve25519_pow_two5mtwo0_two250mtwo0_r(): 
      b = (tt.bignum25519)()
      CLIB.curve25519_pow_two5mtwo0_two250mtwo0(b)
      return b
  
  
  def curve25519_recip(out, z): 
      CLIB.curve25519_recip(out, z)
  
  
  def curve25519_recip_r(z): 
      out = (tt.bignum25519)()
      CLIB.curve25519_recip(out, z)
      return out
  
  
  def curve25519_pow_two252m3(two252m3, z): 
      CLIB.curve25519_pow_two252m3(two252m3, z)
  
  
  def curve25519_pow_two252m3_r(z): 
      two252m3 = (tt.bignum25519)()
      CLIB.curve25519_pow_two252m3(two252m3, z)
      return two252m3
  
  
  def reduce256_modm(r): 
      CLIB.reduce256_modm(r)
  
  
  def reduce256_modm_r(): 
      r = (tt.bignum256modm)()
      CLIB.reduce256_modm(r)
      return r
  
  
  def barrett_reduce256_modm(r, q1, r1): 
      CLIB.barrett_reduce256_modm(r, q1, r1)
  
  
  def barrett_reduce256_modm_r(q1, r1): 
      r = (tt.bignum256modm)()
      CLIB.barrett_reduce256_modm(r, q1, r1)
      return r
  
  
  def add256_modm(r, x, y): 
      CLIB.add256_modm(r, x, y)
  
  
  def add256_modm_r(x, y): 
      r = (tt.bignum256modm)()
      CLIB.add256_modm(r, x, y)
      return r
  
  
  def neg256_modm(r, x): 
      CLIB.neg256_modm(r, x)
  
  
  def neg256_modm_r(x): 
      r = (tt.bignum256modm)()
      CLIB.neg256_modm(r, x)
      return r
  
  
  def sub256_modm(r, x, y): 
      CLIB.sub256_modm(r, x, y)
  
  
  def sub256_modm_r(x, y): 
      r = (tt.bignum256modm)()
      CLIB.sub256_modm(r, x, y)
      return r
  
  
  def mul256_modm(r, x, y): 
      CLIB.mul256_modm(r, x, y)
  
  
  def mul256_modm_r(x, y): 
      r = (tt.bignum256modm)()
      CLIB.mul256_modm(r, x, y)
      return r
  
  
  def expand_raw256_modm(out, in_): 
      CLIB.expand_raw256_modm(out, in_)
  
  
  def expand_raw256_modm_r(in_): 
      out = (tt.bignum256modm)()
      CLIB.expand_raw256_modm(out, in_)
      return out
  
  
  def is_reduced256_modm(in_): 
      return int(CLIB.is_reduced256_modm(in_))
  
  
  def contract256_modm(out, in_): 
      CLIB.contract256_modm(out, in_)
  
  
  def contract256_modm_r(in_): 
      out = (ct.c_ubyte * 32)()
      CLIB.contract256_modm(out, in_)
      return bytes(out)
  
  
  def contract256_window4_modm(r, in_): 
      CLIB.contract256_window4_modm(r, in_)
  
  
  def contract256_window4_modm_r(in_): 
      r = (ct.c_byte * 64)()
      CLIB.contract256_window4_modm(r, in_)
      return bytes(r)
  
  
  def contract256_slidingwindow_modm(r, s, windowsize): 
      CLIB.contract256_slidingwindow_modm(r, s, windowsize)
  
  
  def contract256_slidingwindow_modm_r(s, windowsize): 
      r = (ct.c_byte * 256)()
      CLIB.contract256_slidingwindow_modm(r, s, windowsize)
      return bytes(r)
  
  
  def set256_modm(r, v): 
      CLIB.set256_modm(r, v)
  
  
  def set256_modm_r(v): 
      r = (tt.bignum256modm)()
      CLIB.set256_modm(r, v)
      return r
  
  
  def get256_modm(v, r): 
      return int(CLIB.get256_modm(ct.byref(v), r))
  
  
  def eq256_modm(x, y): 
      return int(CLIB.eq256_modm(x, y))
  
  
  def cmp256_modm(x, y): 
      return int(CLIB.cmp256_modm(x, y))
  
  
  def iszero256_modm(x): 
      return int(CLIB.iszero256_modm(x))
  
  
  def copy256_modm(r, x): 
      CLIB.copy256_modm(r, x)
  
  
  def copy256_modm_r(x): 
      r = (tt.bignum256modm)()
      CLIB.copy256_modm(r, x)
      return r
  
  
  def check256_modm(x): 
      return int(CLIB.check256_modm(x))
  
  
  def mulsub256_modm(r, a, b, c): 
      CLIB.mulsub256_modm(r, a, b, c)
  
  
  def mulsub256_modm_r(a, b, c): 
      r = (tt.bignum256modm)()
      CLIB.mulsub256_modm(r, a, b, c)
      return r
  
  
  def muladd256_modm(r, a, b, c): 
      CLIB.muladd256_modm(r, a, b, c)
  
  
  def muladd256_modm_r(a, b, c): 
      r = (tt.bignum256modm)()
      CLIB.muladd256_modm(r, a, b, c)
      return r
  
  
  def ed25519_verify(x, y, len): 
      return int(CLIB.ed25519_verify(x, y, len))
  
  
  def ge25519_p1p1_to_partial(r, p): 
      CLIB.ge25519_p1p1_to_partial(ct.byref(r), ct.byref(p))
  
  
  def ge25519_p1p1_to_partial_r(p): 
      r = (tt.ge25519)()
      CLIB.ge25519_p1p1_to_partial(ct.byref(r), ct.byref(p))
      return r
  
  
  def ge25519_p1p1_to_full(r, p): 
      CLIB.ge25519_p1p1_to_full(ct.byref(r), ct.byref(p))
  
  
  def ge25519_p1p1_to_full_r(p): 
      r = (tt.ge25519)()
      CLIB.ge25519_p1p1_to_full(ct.byref(r), ct.byref(p))
      return r
  
  
  def ge25519_full_to_pniels(p, r): 
      CLIB.ge25519_full_to_pniels(ct.byref(p), ct.byref(r))
  
  
  def ge25519_full_to_pniels_r(r): 
      p = (tt.ge25519_pniels)()
      CLIB.ge25519_full_to_pniels(ct.byref(p), ct.byref(r))
      return p
  
  
  def ge25519_double_p1p1(r, p): 
      CLIB.ge25519_double_p1p1(ct.byref(r), ct.byref(p))
  
  
  def ge25519_double_p1p1_r(p): 
      r = (tt.ge25519_p1p1)()
      CLIB.ge25519_double_p1p1(ct.byref(r), ct.byref(p))
      return r
  
  
  def ge25519_nielsadd2_p1p1(r, p, q, signbit): 
      CLIB.ge25519_nielsadd2_p1p1(ct.byref(r), ct.byref(p), ct.byref(q), signbit)
  
  
  def ge25519_nielsadd2_p1p1_r(p, q, signbit): 
      r = (tt.ge25519_p1p1)()
      CLIB.ge25519_nielsadd2_p1p1(ct.byref(r), ct.byref(p), ct.byref(q), signbit)
      return r
  
  
  def ge25519_pnielsadd_p1p1(r, p, q, signbit): 
      CLIB.ge25519_pnielsadd_p1p1(ct.byref(r), ct.byref(p), ct.byref(q), signbit)
  
  
  def ge25519_pnielsadd_p1p1_r(p, q, signbit): 
      r = (tt.ge25519_p1p1)()
      CLIB.ge25519_pnielsadd_p1p1(ct.byref(r), ct.byref(p), ct.byref(q), signbit)
      return r
  
  
  def ge25519_double_partial(r, p): 
      CLIB.ge25519_double_partial(ct.byref(r), ct.byref(p))
  
  
  def ge25519_double_partial_r(p): 
      r = (tt.ge25519)()
      CLIB.ge25519_double_partial(ct.byref(r), ct.byref(p))
      return r
  
  
  def ge25519_double(r, p): 
      CLIB.ge25519_double(ct.byref(r), ct.byref(p))
  
  
  def ge25519_double_r(p): 
      r = (tt.ge25519)()
      CLIB.ge25519_double(ct.byref(r), ct.byref(p))
      return r
  
  
  def ge25519_nielsadd2(r, q): 
      CLIB.ge25519_nielsadd2(ct.byref(r), ct.byref(q))
  
  
  def ge25519_nielsadd2_r(q): 
      r = (tt.ge25519)()
      CLIB.ge25519_nielsadd2(ct.byref(r), ct.byref(q))
      return r
  
  
  def ge25519_pnielsadd(r, p, q): 
      CLIB.ge25519_pnielsadd(ct.byref(r), ct.byref(p), ct.byref(q))
  
  
  def ge25519_pnielsadd_r(p, q): 
      r = (tt.ge25519_pniels)()
      CLIB.ge25519_pnielsadd(ct.byref(r), ct.byref(p), ct.byref(q))
      return r
  
  
  def ge25519_pack(r, p): 
      CLIB.ge25519_pack(r, ct.byref(p))
  
  
  def ge25519_pack_r(p): 
      r = (ct.c_ubyte * 32)()
      CLIB.ge25519_pack(r, ct.byref(p))
      return bytes(r)
  
  
  def ge25519_unpack_negative_vartime(r, p): 
      return int(CLIB.ge25519_unpack_negative_vartime(ct.byref(r), p))
  
  
  def ge25519_unpack_negative_vartime_r(p): 
      r = (tt.ge25519)()
      _res = CLIB.ge25519_unpack_negative_vartime(ct.byref(r), p)
      return int(_res), r
  
  
  def ge25519_set_neutral(r): 
      CLIB.ge25519_set_neutral(ct.byref(r))
  
  
  def ge25519_set_neutral_r(): 
      r = (tt.ge25519)()
      CLIB.ge25519_set_neutral(ct.byref(r))
      return r
  
  
  def ge25519_double_scalarmult_vartime(r, p1, s1, s2): 
      CLIB.ge25519_double_scalarmult_vartime(ct.byref(r), ct.byref(p1), s1, s2)
  
  
  def ge25519_double_scalarmult_vartime_r(p1, s1, s2): 
      r = (tt.ge25519)()
      CLIB.ge25519_double_scalarmult_vartime(ct.byref(r), ct.byref(p1), s1, s2)
      return r
  
  
  def ge25519_double_scalarmult_vartime2(r, p1, s1, p2, s2): 
      CLIB.ge25519_double_scalarmult_vartime2(ct.byref(r), ct.byref(p1), s1, ct.byref(p2), s2)
  
  
  def ge25519_double_scalarmult_vartime2_r(p1, s1, p2, s2): 
      r = (tt.ge25519)()
      CLIB.ge25519_double_scalarmult_vartime2(ct.byref(r), ct.byref(p1), s1, ct.byref(p2), s2)
      return r
  
  
  def ge25519_scalarmult(r, p1, s1): 
      CLIB.ge25519_scalarmult(ct.byref(r), ct.byref(p1), s1)
  
  
  def ge25519_scalarmult_r(p1, s1): 
      r = (tt.ge25519)()
      CLIB.ge25519_scalarmult(ct.byref(r), ct.byref(p1), s1)
      return r
  
  
  def curve25519_set(r, x): 
      CLIB.curve25519_set(r, x)
  
  
  def curve25519_set_r(x): 
      r = (tt.bignum25519)()
      CLIB.curve25519_set(r, x)
      return r
  
  
  def curve25519_set_d(r): 
      CLIB.curve25519_set_d(r)
  
  
  def curve25519_set_d_r(): 
      r = (tt.bignum25519)()
      CLIB.curve25519_set_d(r)
      return r
  
  
  def curve25519_set_2d(r): 
      CLIB.curve25519_set_2d(r)
  
  
  def curve25519_set_2d_r(): 
      r = (tt.bignum25519)()
      CLIB.curve25519_set_2d(r)
      return r
  
  
  def curve25519_set_sqrtneg1(r): 
      CLIB.curve25519_set_sqrtneg1(r)
  
  
  def curve25519_set_sqrtneg1_r(): 
      r = (tt.bignum25519)()
      CLIB.curve25519_set_sqrtneg1(r)
      return r
  
  
  def curve25519_isnegative(f): 
      return int(CLIB.curve25519_isnegative(f))
  
  
  def curve25519_isnonzero(f): 
      return int(CLIB.curve25519_isnonzero(f))
  
  
  def curve25519_reduce(r, in_): 
      CLIB.curve25519_reduce(r, in_)
  
  
  def curve25519_reduce_r(in_): 
      r = (tt.bignum25519)()
      CLIB.curve25519_reduce(r, in_)
      return r
  
  
  def curve25519_expand_reduce(out, in_): 
      CLIB.curve25519_expand_reduce(out, in_)
  
  
  def curve25519_expand_reduce_r(in_): 
      out = (tt.bignum25519)()
      CLIB.curve25519_expand_reduce(out, in_)
      return out
  
  
  def ge25519_check(r): 
      return int(CLIB.ge25519_check(ct.byref(r)))
  
  
  def ge25519_eq(a, b): 
      return int(CLIB.ge25519_eq(ct.byref(a), ct.byref(b)))
  
  
  def ge25519_copy(dst, src): 
      CLIB.ge25519_copy(ct.byref(dst), ct.byref(src))
  
  
  def ge25519_copy_r(src): 
      dst = (tt.ge25519)()
      CLIB.ge25519_copy(ct.byref(dst), ct.byref(src))
      return dst
  
  
  def ge25519_set_base(r): 
      CLIB.ge25519_set_base(ct.byref(r))
  
  
  def ge25519_set_base_r(): 
      r = (tt.ge25519)()
      CLIB.ge25519_set_base(ct.byref(r))
      return r
  
  
  def ge25519_mul8(r, t): 
      CLIB.ge25519_mul8(ct.byref(r), ct.byref(t))
  
  
  def ge25519_mul8_r(t): 
      r = (tt.ge25519)()
      CLIB.ge25519_mul8(ct.byref(r), ct.byref(t))
      return r
  
  
  def ge25519_neg_partial(r): 
      CLIB.ge25519_neg_partial(ct.byref(r))
  
  
  def ge25519_neg_partial_r(): 
      r = (tt.ge25519)()
      CLIB.ge25519_neg_partial(ct.byref(r))
      return r
  
  
  def ge25519_neg_full(r): 
      CLIB.ge25519_neg_full(ct.byref(r))
  
  
  def ge25519_neg_full_r(): 
      r = (tt.ge25519)()
      CLIB.ge25519_neg_full(ct.byref(r))
      return r
  
  
  def ge25519_reduce(r, t): 
      CLIB.ge25519_reduce(ct.byref(r), ct.byref(t))
  
  
  def ge25519_reduce_r(t): 
      r = (tt.ge25519)()
      CLIB.ge25519_reduce(ct.byref(r), ct.byref(t))
      return r
  
  
  def ge25519_norm(r, t): 
      CLIB.ge25519_norm(ct.byref(r), ct.byref(t))
  
  
  def ge25519_norm_r(t): 
      r = (tt.ge25519)()
      CLIB.ge25519_norm(ct.byref(r), ct.byref(t))
      return r
  
  
  def ge25519_add(r, a, b, signbit): 
      CLIB.ge25519_add(ct.byref(r), ct.byref(a), ct.byref(b), signbit)
  
  
  def ge25519_add_r(a, b, signbit): 
      r = (tt.ge25519)()
      CLIB.ge25519_add(ct.byref(r), ct.byref(a), ct.byref(b), signbit)
      return r
  
  
  def ge25519_fromfe_frombytes_vartime(r, s): 
      CLIB.ge25519_fromfe_frombytes_vartime(ct.byref(r), s)
  
  
  def ge25519_fromfe_frombytes_vartime_r(s): 
      r = (tt.ge25519)()
      CLIB.ge25519_fromfe_frombytes_vartime(ct.byref(r), s)
      return r
  
  
  def ge25519_scalarmult_base_wrapper(r, s): 
      CLIB.ge25519_scalarmult_base_wrapper(ct.byref(r), s)
  
  
  def ge25519_scalarmult_base_wrapper_r(s): 
      r = (tt.ge25519)()
      CLIB.ge25519_scalarmult_base_wrapper(ct.byref(r), s)
      return r
  
  
  def ge25519_set_xmr_h(r): 
      CLIB.ge25519_set_xmr_h(ct.byref(r))
  
  
  def ge25519_set_xmr_h_r(): 
      r = (tt.ge25519)()
      CLIB.ge25519_set_xmr_h(ct.byref(r))
      return r
  
  
  def xmr_random_scalar(m): 
      CLIB.xmr_random_scalar(m)
  
  
  def xmr_random_scalar_r(): 
      m = (tt.bignum256modm)()
      CLIB.xmr_random_scalar(m)
      return m
  
  
  def xmr_fast_hash(hash, data, length): 
      CLIB.xmr_fast_hash(hash, ct.byref(data), length)
  
  
  def xmr_hasher_init(hasher): 
      CLIB.xmr_hasher_init(ct.byref(hasher))
  
  
  def xmr_hasher_init_r(): 
      hasher = (tt.Hasher)()
      CLIB.xmr_hasher_init(ct.byref(hasher))
      return hasher
  
  
  def xmr_hasher_final(hasher, hash): 
      CLIB.xmr_hasher_final(ct.byref(hasher), hash)
  
  
  def xmr_hasher_final_r(hasher): 
      hash = tt.KEY_BUFF()
      CLIB.xmr_hasher_final(ct.byref(hasher), hash)
      return bytes(hash)
  
  def xmr_hasher_copy(dst, src): 
      CLIB.xmr_hasher_copy(ct.byref(dst), ct.byref(src))
  
  
  def xmr_hasher_copy_r(src): 
      dst = (tt.Hasher)()
      CLIB.xmr_hasher_copy(ct.byref(dst), ct.byref(src))
      return dst
  
  
  def xmr_derivation_to_scalar(s, p, output_index): 
      CLIB.xmr_derivation_to_scalar(s, ct.byref(p), output_index)
  
  
  def xmr_derivation_to_scalar_r(p, output_index): 
      s = (tt.bignum256modm)()
      CLIB.xmr_derivation_to_scalar(s, ct.byref(p), output_index)
      return s
  
  
  def xmr_generate_key_derivation(r, A, b): 
      CLIB.xmr_generate_key_derivation(ct.byref(r), ct.byref(A), b)
  
  
  def xmr_generate_key_derivation_r(A, b): 
      r = (tt.ge25519)()
      CLIB.xmr_generate_key_derivation(ct.byref(r), ct.byref(A), b)
      return r
  
  
  def xmr_derive_private_key(s, deriv, idx, base): 
      CLIB.xmr_derive_private_key(s, ct.byref(deriv), idx, base)
  
  
  def xmr_derive_private_key_r(deriv, idx, base): 
      s = (tt.bignum256modm)()
      CLIB.xmr_derive_private_key(s, ct.byref(deriv), idx, base)
      return s
  
  
  def xmr_derive_public_key(r, deriv, idx, base): 
      CLIB.xmr_derive_public_key(ct.byref(r), ct.byref(deriv), idx, ct.byref(base))
  
  
  def xmr_derive_public_key_r(deriv, idx, base): 
      r = (tt.ge25519)()
      CLIB.xmr_derive_public_key(ct.byref(r), ct.byref(deriv), idx, ct.byref(base))
      return r
  
  
  def xmr_add_keys2(r, a, b, B): 
      CLIB.xmr_add_keys2(ct.byref(r), a, b, ct.byref(B))
  
  
  def xmr_add_keys2_r(a, b, B): 
      r = (tt.ge25519)()
      CLIB.xmr_add_keys2(ct.byref(r), a, b, ct.byref(B))
      return r
  
  
  def xmr_add_keys2_vartime(r, a, b, B): 
      CLIB.xmr_add_keys2_vartime(ct.byref(r), a, b, ct.byref(B))
  
  
  def xmr_add_keys2_vartime_r(a, b, B): 
      r = (tt.ge25519)()
      CLIB.xmr_add_keys2_vartime(ct.byref(r), a, b, ct.byref(B))
      return r
  
  
  def xmr_add_keys3(r, a, A, b, B): 
      CLIB.xmr_add_keys3(ct.byref(r), a, ct.byref(A), b, ct.byref(B))
  
  
  def xmr_add_keys3_r(a, A, b, B): 
      r = (tt.ge25519)()
      CLIB.xmr_add_keys3(ct.byref(r), a, ct.byref(A), b, ct.byref(B))
      return r
  
  
  def xmr_add_keys3_vartime(r, a, A, b, B): 
      CLIB.xmr_add_keys3_vartime(ct.byref(r), a, ct.byref(A), b, ct.byref(B))
  
  
  def xmr_add_keys3_vartime_r(a, A, b, B): 
      r = (tt.ge25519)()
      CLIB.xmr_add_keys3_vartime(ct.byref(r), a, ct.byref(A), b, ct.byref(B))
      return r
  
  
  def xmr_get_subaddress_secret_key(r, major, minor, m): 
      CLIB.xmr_get_subaddress_secret_key(r, major, minor, m)
  
  
  def xmr_get_subaddress_secret_key_r(major, minor, m): 
      r = (tt.bignum256modm)()
      CLIB.xmr_get_subaddress_secret_key(r, major, minor, m)
      return r
  
  
  def xmr_gen_c(r, a, amount): 
      CLIB.xmr_gen_c(ct.byref(r), a, amount)
  
  
  def xmr_gen_c_r(a, amount): 
      r = (tt.ge25519)()
      CLIB.xmr_gen_c(ct.byref(r), a, amount)
      return r
  
  
  def xmr_gen_range_sig(sig, C, mask, amount, last_mask): 
      CLIB.xmr_gen_range_sig(ct.byref(sig), ct.byref(C), mask, amount, ct.byref(last_mask))
  
  
  def xmr_gen_range_sig_r(amount, last_mask): 
      sig = (tt.xmr_range_sig_t)()
      C = (tt.ge25519)()
      mask = (tt.bignum256modm)()
      CLIB.xmr_gen_range_sig(ct.byref(sig), ct.byref(C), mask, amount, ct.byref(last_mask))
      return sig, C, mask
  
  
  def xmr_gen_range_sig_ex(sig, C, mask, amount, last_mask, ai, alpha): 
      CLIB.xmr_gen_range_sig_ex(ct.byref(sig), ct.byref(C), mask, amount, ct.byref(last_mask), ai, alpha)
  
  
  
  
  