def crypto_pwhash_str_alg(passwd, opslimit, memlimit, alg): """ Derive a cryptographic key using the ``passwd`` given as input and a random ``salt``, returning a string representation which includes the salt, the tuning parameters and the used algorithm. :param passwd: The input password :type passwd: bytes :param opslimit: computational cost :type opslimit: int :param memlimit: memory cost :type memlimit: int :param alg: The algorithm to use :type alg: int :return: serialized derived key and parameters :rtype: bytes """ ensure(isinstance(opslimit, integer_types), raising=TypeError) ensure(isinstance(memlimit, integer_types), raising=TypeError) ensure(isinstance(passwd, bytes), raising=TypeError) _check_argon2_limits_alg(opslimit, memlimit, alg) outbuf = ffi.new("char[]", 128) ret = lib.crypto_pwhash_str_alg(outbuf, passwd, len(passwd), opslimit, memlimit, alg) ensure(ret == 0, 'Unexpected failure in key derivation', raising=exc.RuntimeError) return ffi.string(outbuf)