1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/* Copyright 2016 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "dcrypto.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <openssl/bn.h>
static int test_bn_modinv_helper(const BIGNUM *E, BN_CTX *ctx)
{
int i;
BIGNUM *MOD = BN_CTX_get(ctx);
for (i = 0; i < 1000; i++) {
uint32_t m_buf[64];
uint32_t d_buf[64];
uint32_t e_buf[32];
int has_inverse;
int test_inverse;
struct LITE_BIGNUM m;
struct LITE_BIGNUM e;
struct LITE_BIGNUM d;
BIGNUM *r = BN_CTX_get(ctx);
memset(e_buf, 0, sizeof(e_buf));
/* Top bit set, bottom bit clear. */
BN_rand(MOD, 2048, 1, 0);
if (BN_mod_inverse(r, E, MOD, ctx))
has_inverse = 1;
else
has_inverse = 0;
DCRYPTO_bn_wrap(&m, m_buf, sizeof(m_buf));
memcpy(m_buf, MOD->d, sizeof(m_buf));
assert(BN_num_bytes(E) <= sizeof(e_buf));
memcpy(e_buf, E->d, BN_num_bytes(E));
DCRYPTO_bn_wrap(&e, e_buf, sizeof(e_buf));
bn_init(&d, d_buf, sizeof(d_buf));
test_inverse = bn_modinv_vartime(&d, &e, &m);
if (test_inverse != has_inverse) {
fprintf(stderr,
"ossl inverse: %d, dcrypto inverse: %d\n",
has_inverse, test_inverse);
fprintf(stderr, "d : ");
BN_print_fp(stderr, r);
fprintf(stderr, "\n");
fprintf(stderr, "e : ");
BN_print_fp(stderr, E);
fprintf(stderr, "\n");
fprintf(stderr, "M : ");
BN_print_fp(stderr, MOD);
fprintf(stderr, "\n");
return 1;
}
if (has_inverse) {
if (memcmp(d.d, r->d, BN_num_bytes(r)) != 0) {
fprintf(stderr, "memcmp fail\n");
return 1;
}
}
BN_free(r);
}
return 0;
}
static int test_bn_modinv(void)
{
int result = 1;
BN_CTX *ctx = BN_CTX_new();
BN_CTX_start(ctx);
BIGNUM *E = BN_CTX_get(ctx);
BN_rand(E, 1024, 1, 1);
if (test_bn_modinv_helper(E, ctx))
goto fail;
BN_rand(E, 1024, 1, 0);
if (test_bn_modinv_helper(E, ctx))
goto fail;
BN_set_word(E, 3);
if (test_bn_modinv_helper(E, ctx))
goto fail;
BN_set_word(E, 65537);
if (test_bn_modinv_helper(E, ctx))
goto fail;
result = 0;
fail:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
return result;
}
int main(void)
{
assert(test_bn_modinv() == 0);
fprintf(stderr, "PASS\n");
return 0;
}
|