+/** @brief Multiple v by m and add a
+ * @param v Pointer to bigendian bignum
+ * @param nwords Length of bignum
+ * @param m Value to multiply by
+ * @param a Value to add
+ * @return 0 on success, non-0 on overflow
+ *
+ * Does v = m * v + a.
+ */
+static int mla(uint32_t *v, int nwords, uint32_t m, uint32_t a) {
+ int n = nwords - 1;
+ uint32_t carry = a;
+
+ while(n >= 0) {
+ const uint64_t p = (uint64_t)v[n] * m + carry;
+ carry = (uint32_t)(p >> 32);
+ v[n] = (uint32_t)p;
+ --n;
+ }
+ /* If there is still a carry then we overflowed */
+ return !!carry;
+}
+
+static const char basen_chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+/** @brief Convert v to a chosen base
+ * @param v Pointer to bigendian bignum (modified!)
+ * @param nwords Length of bignum
+ * @param buffer Output buffer
+ * @param bufsize Size of output buffer
+ * @param base Number base (2..62)
+ * @return 0 on success, -1 if the buffer is too small
+ *
+ * Converts @p v to a string in the given base using decimal digits, lower case
+ * letters and upper case letters as digits.
+ *
+ * The inverse of nesab().
+ */
+int basen(uint32_t *v,