The rk pointer in struct aes_ctx always pointed to the context's buffer and served no purpose whatsoever, but the compiler had no way of knowing that and could therefore not optimize away assignments to and from it.
Note that the removal of rk breaks the ABI, since it changes the size of struct aes_ctx, but we allow ourselves that because neither the API nor the ABI have been fixed yet.
If its operands were identical, cryb_mpi_add_abs() would leave the target untouched. Explicitly call mpi_zero() before returning. While there, extend the “identical operands” shortcut to also cover equality.
Both cryb_mpi_add_abs() and cryb_mpi_sub_abs() would leave the target's negative flag untouched. Explicitly clear it before returning.
These tests reveal that both functions assume that the target is initially positive zero if it is not identical with one of the operands, and fail in various ways if it is not, or if it is uninitialized.
Unlike assert(3), which uses abort(3), this has no other side effects (before raising SIGABRT) than an fprintf() call. The test framework will catch the SIGABRT, report that the test case failed, and proceed with the next case.
It is reasonable to assume that a SIGABRT originates from a call to abort(3), either directly or via assert(3). Both the C standard and POSIX give the implementation great latitude with regard to abort(3)'s behavior, and both explicitly mention that it may close all streams before raising SIGABRT. This means that we cannot safely proceed after a call to abort(3). One could argue that we can't safely proceed after a SIGBUS or SIGSEGV either, but in practice, the damage is usually quite limited.
It does not seem that gcc accepts casting to void as an alternative to actually checking the result. The only recourse we have is to disable the warning.
All further instances of asprintf() or vasprintf() in our codebase are either in libcryb-test or in individual unit tests, and in all cases, the only consequence of a failed call is that the result will say "no description" instead of either a description of the test or an explanation of how it failed. Therefore, we can simply ignore the problem and cast the call to void to satisfy gcc.
This is actually redundant, because we already check the pointer, which is NULL if and only if asprintf() fails and returns < 0, but the version of gcc used by Travis CI insists. I have not been able to reproduce the issue on any other platform available to me.