Skip to content

Commit c1a3e64

Browse files
author
tb
committed
Refactor and fix bn_mod_exp test
The amount of copy-paste in this test led to a few bugs and it was hard to spot them since things were done in random order. Use a different approach: compute the result of a^b (mod m) according to BN_mod_exp_simple(), then compare the results of all the other *_mod_exp* functions to that. Reuse the test structure from bn_mod_exp_zero.c to loop over the list of functions. This way we test more functions and don't forget to check some crucial bits.
1 parent 58884ff commit c1a3e64

File tree

1 file changed

+86
-80
lines changed

1 file changed

+86
-80
lines changed

src/regress/lib/libcrypto/bn/bn_mod_exp.c

Lines changed: 86 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: bn_mod_exp.c,v 1.7 2022/12/03 08:21:38 tb Exp $ */
1+
/* $OpenBSD: bn_mod_exp.c,v 1.8 2022/12/03 09:37:02 tb Exp $ */
22
/* Copyright (C) 1995-1998 Eric Young ([email protected])
33
* All rights reserved.
44
*
@@ -67,14 +67,88 @@
6767

6868
#define NUM_BITS (BN_BITS*2)
6969

70+
#define INIT_MOD_EXP_FN(f) { .name = #f, .mod_exp_fn = (f), }
71+
#define INIT_MOD_EXP_MONT_FN(f) { .name = #f, .mod_exp_mont_fn = (f), }
72+
73+
static const struct mod_exp_test {
74+
const char *name;
75+
int (*mod_exp_fn)(BIGNUM *,const BIGNUM *, const BIGNUM *,
76+
const BIGNUM *, BN_CTX *);
77+
int (*mod_exp_mont_fn)(BIGNUM *,const BIGNUM *, const BIGNUM *,
78+
const BIGNUM *, BN_CTX *, BN_MONT_CTX *);
79+
} mod_exp_fn[] = {
80+
INIT_MOD_EXP_FN(BN_mod_exp),
81+
INIT_MOD_EXP_FN(BN_mod_exp_ct),
82+
INIT_MOD_EXP_FN(BN_mod_exp_nonct),
83+
INIT_MOD_EXP_FN(BN_mod_exp_recp),
84+
INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont),
85+
INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_ct),
86+
INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_consttime),
87+
INIT_MOD_EXP_MONT_FN(BN_mod_exp_mont_nonct),
88+
};
89+
90+
#define N_MOD_EXP_FN (sizeof(mod_exp_fn) / sizeof(mod_exp_fn[0]))
91+
92+
static int
93+
test_mod_exp(const BIGNUM *result_simple, const BIGNUM *a, const BIGNUM *b,
94+
const BIGNUM *m, BN_CTX *ctx, const struct mod_exp_test *test)
95+
{
96+
BIGNUM *result;
97+
int ret = 0;
98+
99+
BN_CTX_start(ctx);
100+
101+
if ((result = BN_CTX_get(ctx)) == NULL)
102+
goto err;
103+
104+
if (test->mod_exp_fn != NULL) {
105+
if (!test->mod_exp_fn(result, a, b, m, ctx)) {
106+
fprintf(stderr, "%s problems\n", test->name);
107+
ERR_print_errors_fp(stderr);
108+
goto err;
109+
}
110+
} else {
111+
if (!test->mod_exp_mont_fn(result, a, b, m, ctx, NULL)) {
112+
fprintf(stderr, "%s problems\n", test->name);
113+
ERR_print_errors_fp(stderr);
114+
goto err;
115+
}
116+
}
117+
118+
if (BN_cmp(result_simple, result) != 0) {
119+
printf("\nResults from BN_mod_exp_simple and %s differ\n",
120+
test->name);
121+
122+
printf("a (%3d) = ", BN_num_bits(a));
123+
BN_print_fp(stdout, a);
124+
printf("\nb (%3d) = ", BN_num_bits(b));
125+
BN_print_fp(stdout, b);
126+
printf("\nm (%3d) = ", BN_num_bits(m));
127+
BN_print_fp(stdout, m);
128+
printf("\nsimple = ");
129+
BN_print_fp(stdout, result_simple);
130+
printf("\nresult = ");
131+
BN_print_fp(stdout, result);
132+
printf("\n");
133+
134+
goto err;
135+
}
136+
137+
ret = 1;
138+
139+
err:
140+
BN_CTX_end(ctx);
141+
142+
return ret;
143+
}
144+
70145
int
71146
main(int argc, char *argv[])
72147
{
73-
BIGNUM *r_mont, *r_mont_const, *r_recp, *r_simple;
74-
BIGNUM *r_mont_ct, *r_mont_nonct, *a, *b, *m;
148+
BIGNUM *result_simple, *a, *b, *m;
75149
BN_CTX *ctx;
76-
int c;
77-
int i, ret;
150+
int c, i;
151+
size_t j;
78152

79153
ERR_load_BN_strings();
80154

@@ -83,24 +157,14 @@ main(int argc, char *argv[])
83157

84158
BN_CTX_start(ctx);
85159

86-
if ((r_mont = BN_CTX_get(ctx)) == NULL)
87-
goto err;
88-
if ((r_mont_const = BN_CTX_get(ctx)) == NULL)
89-
goto err;
90-
if ((r_mont_ct = BN_CTX_get(ctx)) == NULL)
91-
goto err;
92-
if ((r_mont_nonct = BN_CTX_get(ctx)) == NULL)
93-
goto err;
94-
if ((r_recp = BN_CTX_get(ctx)) == NULL)
95-
goto err;
96-
if ((r_simple = BN_CTX_get(ctx)) == NULL)
97-
goto err;
98160
if ((a = BN_CTX_get(ctx)) == NULL)
99161
goto err;
100162
if ((b = BN_CTX_get(ctx)) == NULL)
101163
goto err;
102164
if ((m = BN_CTX_get(ctx)) == NULL)
103165
goto err;
166+
if ((result_simple = BN_CTX_get(ctx)) == NULL)
167+
goto err;
104168

105169
for (i = 0; i < 200; i++) {
106170
c = (arc4random() % BN_BITS) - BN_BITS2;
@@ -120,74 +184,16 @@ main(int argc, char *argv[])
120184
if (!BN_mod(b, b, m, ctx))
121185
goto err;
122186

123-
ret = BN_mod_exp_mont(r_mont, a, b, m, ctx, NULL);
124-
if (ret <= 0) {
125-
printf("BN_mod_exp_mont() problems\n");
126-
goto err;
127-
}
128-
129-
ret = BN_mod_exp_mont_ct(r_mont_ct, a, b, m, ctx, NULL);
130-
if (ret <= 0) {
131-
printf("BN_mod_exp_mont_ct() problems\n");
132-
goto err;
133-
}
134-
135-
ret = BN_mod_exp_mont_nonct(r_mont_nonct, a, b, m, ctx, NULL);
136-
if (ret <= 0) {
137-
printf("BN_mod_exp_mont_nonct() problems\n");
138-
goto err;
139-
}
140-
141-
ret = BN_mod_exp_recp(r_recp, a, b, m, ctx);
142-
if (ret <= 0) {
143-
printf("BN_mod_exp_recp() problems\n");
144-
goto err;
145-
}
146-
147-
ret = BN_mod_exp_simple(r_simple, a, b, m, ctx);
148-
if (ret <= 0) {
187+
if ((BN_mod_exp_simple(result_simple, a, b, m, ctx)) <= 0) {
149188
printf("BN_mod_exp_simple() problems\n");
150189
goto err;
151190
}
152191

153-
ret = BN_mod_exp_mont_consttime(r_mont_const, a, b, m, ctx, NULL);
154-
if (ret <= 0) {
155-
printf("BN_mod_exp_mont_consttime() problems\n");
156-
goto err;
157-
}
192+
for (j = 0; j < N_MOD_EXP_FN; j++) {
193+
const struct mod_exp_test *test = &mod_exp_fn[j];
158194

159-
if (BN_cmp(r_simple, r_mont) != 0 ||
160-
BN_cmp(r_simple, r_mont_const) ||
161-
BN_cmp(r_simple, r_recp) != 0 ||
162-
BN_cmp(r_simple, r_mont_ct) != 0 ||
163-
BN_cmp(r_simple, r_mont_nonct) != 0) {
164-
if (BN_cmp(r_simple, r_mont) != 0)
165-
printf("\nsimple and mont results differ\n");
166-
if (BN_cmp(r_simple, r_mont_const) != 0)
167-
printf("\nsimple and mont const time results differ\n");
168-
if (BN_cmp(r_simple, r_recp) != 0)
169-
printf("\nsimple and recp results differ\n");
170-
if (BN_cmp(r_simple, r_mont_ct) != 0)
171-
printf("\nsimple and mont results differ\n");
172-
if (BN_cmp(r_simple, r_mont_nonct) != 0)
173-
printf("\nsimple and mont_nonct results differ\n");
174-
175-
printf("a (%3d) = ", BN_num_bits(a));
176-
BN_print_fp(stdout, a);
177-
printf("\nb (%3d) = ", BN_num_bits(b));
178-
BN_print_fp(stdout, b);
179-
printf("\nm (%3d) = ", BN_num_bits(m));
180-
BN_print_fp(stdout, m);
181-
printf("\nsimple =");
182-
BN_print_fp(stdout, r_simple);
183-
printf("\nrecp =");
184-
BN_print_fp(stdout, r_recp);
185-
printf("\nmont =");
186-
BN_print_fp(stdout, r_mont);
187-
printf("\nmont_ct =");
188-
BN_print_fp(stdout, r_mont_const);
189-
printf("\n");
190-
exit(1);
195+
if (!test_mod_exp(result_simple, a, b, m, ctx, test))
196+
goto err;
191197
}
192198
}
193199

0 commit comments

Comments
 (0)