#include "inner.h"
+/*
+ * As a strict minimum, we need four buffers that can hold a
+ * modular integer.
+ */
+#define TLEN (4 * (2 + ((BR_MAX_RSA_SIZE + 30) / 31)))
+
/* see bearssl_rsa.h */
uint32_t
br_rsa_i31_public(unsigned char *x, size_t xlen,
{
const unsigned char *n;
size_t nlen;
- uint32_t m[1 + ((BR_MAX_RSA_SIZE + 30) / 31)];
- uint32_t a[1 + ((BR_MAX_RSA_SIZE + 30) / 31)];
- uint32_t t1[1 + ((BR_MAX_RSA_SIZE + 30) / 31)];
- uint32_t t2[1 + ((BR_MAX_RSA_SIZE + 30) / 31)];
+ uint32_t tmp[1 + TLEN];
+ uint32_t *m, *a, *t;
+ size_t fwlen;
+ long z;
uint32_t m0i, r;
/*
if (nlen == 0 || nlen > (BR_MAX_RSA_SIZE >> 3) || xlen != nlen) {
return 0;
}
+ z = (long)nlen << 3;
+ fwlen = 1;
+ while (z > 0) {
+ z -= 31;
+ fwlen ++;
+ }
+ /*
+ * Round up length to an even number.
+ */
+ fwlen += (fwlen & 1);
+
+ /*
+ * The modulus gets decoded into m[].
+ * The value to exponentiate goes into a[].
+ * The temporaries for modular exponentiation are in t[].
+ */
+ m = tmp;
+ a = m + fwlen;
+ t = m + 2 * fwlen;
+
+ /*
+ * Decode the modulus.
+ */
br_i31_decode(m, n, nlen);
m0i = br_i31_ninv31(m[1]);
/*
* Compute the modular exponentiation.
*/
- br_i31_modpow(a, pk->e, pk->elen, m, m0i, t1, t2);
+ br_i31_modpow_opt(a, pk->e, pk->elen, m, m0i, t, TLEN - 2 * fwlen);
/*
* Encode the result.