Handle negative modulus with negative exponent in exptmod

This commit is contained in:
Sean Parkinson
2019-11-21 14:55:13 +10:00
parent 88fb7efb8c
commit f56a74b6b7

View File

@@ -2194,26 +2194,31 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ #ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */
int err; int err;
#ifndef WOLFSSL_SMALL_STACK #ifndef WOLFSSL_SMALL_STACK
fp_int tmp[1]; fp_int tmp[2];
#else #else
fp_int *tmp; fp_int *tmp;
#endif #endif
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT); tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);
if (tmp == NULL) if (tmp == NULL)
return FP_MEM; return FP_MEM;
#endif #endif
/* yes, copy G and invmod it */ /* yes, copy G and invmod it */
fp_init_copy(tmp, G); fp_init_copy(&tmp[0], G);
err = fp_invmod(tmp, P, tmp); fp_init_copy(&tmp[1], P);
tmp[1].sign = FP_ZPOS;
err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]);
if (err == FP_OKAY) { if (err == FP_OKAY) {
X->sign = FP_ZPOS; X->sign = FP_ZPOS;
err = _fp_exptmod(tmp, X, X->used, P, Y); err = _fp_exptmod(&tmp[0], X, X->used, P, Y);
if (X != Y) { if (X != Y) {
X->sign = FP_NEG; X->sign = FP_NEG;
} }
if (P->sign == FP_NEG) {
fp_add(Y, P, Y);
}
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
@@ -2256,26 +2261,31 @@ int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y)
#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ #ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */
int err; int err;
#ifndef WOLFSSL_SMALL_STACK #ifndef WOLFSSL_SMALL_STACK
fp_int tmp[1]; fp_int tmp[2];
#else #else
fp_int *tmp; fp_int *tmp;
#endif #endif
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER); tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (tmp == NULL) if (tmp == NULL)
return FP_MEM; return FP_MEM;
#endif #endif
/* yes, copy G and invmod it */ /* yes, copy G and invmod it */
fp_init_copy(tmp, G); fp_init_copy(&tmp[0], G);
err = fp_invmod(tmp, P, tmp); fp_init_copy(&tmp[1], P);
tmp[1].sign = FP_ZPOS;
err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]);
if (err == FP_OKAY) { if (err == FP_OKAY) {
X->sign = FP_ZPOS; X->sign = FP_ZPOS;
err = _fp_exptmod(tmp, X, digits, P, Y); err = _fp_exptmod(&tmp[0], X, digits, P, Y);
if (X != Y) { if (X != Y) {
X->sign = FP_NEG; X->sign = FP_NEG;
} }
if (P->sign == FP_NEG) {
fp_add(Y, P, Y);
}
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT); XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);