diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_recp.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_recp.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/src/lib/libcrypto/bn/bn_recp.c b/src/lib/libcrypto/bn/bn_recp.c index d019941d6b..ef5fdd4708 100644 --- a/src/lib/libcrypto/bn/bn_recp.c +++ b/src/lib/libcrypto/bn/bn_recp.c | |||
@@ -93,18 +93,19 @@ void BN_RECP_CTX_free(BN_RECP_CTX *recp) | |||
93 | 93 | ||
94 | int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) | 94 | int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) |
95 | { | 95 | { |
96 | BN_copy(&(recp->N),d); | 96 | if (!BN_copy(&(recp->N),d)) return 0; |
97 | BN_zero(&(recp->Nr)); | 97 | if (!BN_zero(&(recp->Nr))) return 0; |
98 | recp->num_bits=BN_num_bits(d); | 98 | recp->num_bits=BN_num_bits(d); |
99 | recp->shift=0; | 99 | recp->shift=0; |
100 | return(1); | 100 | return(1); |
101 | } | 101 | } |
102 | 102 | ||
103 | int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp, | 103 | int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, |
104 | BN_CTX *ctx) | 104 | BN_RECP_CTX *recp, BN_CTX *ctx) |
105 | { | 105 | { |
106 | int ret=0; | 106 | int ret=0; |
107 | BIGNUM *a; | 107 | BIGNUM *a; |
108 | const BIGNUM *ca; | ||
108 | 109 | ||
109 | BN_CTX_start(ctx); | 110 | BN_CTX_start(ctx); |
110 | if ((a = BN_CTX_get(ctx)) == NULL) goto err; | 111 | if ((a = BN_CTX_get(ctx)) == NULL) goto err; |
@@ -114,19 +115,19 @@ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp, | |||
114 | { if (!BN_sqr(a,x,ctx)) goto err; } | 115 | { if (!BN_sqr(a,x,ctx)) goto err; } |
115 | else | 116 | else |
116 | { if (!BN_mul(a,x,y,ctx)) goto err; } | 117 | { if (!BN_mul(a,x,y,ctx)) goto err; } |
118 | ca = a; | ||
117 | } | 119 | } |
118 | else | 120 | else |
119 | a=x; /* Just do the mod */ | 121 | ca=x; /* Just do the mod */ |
120 | 122 | ||
121 | BN_div_recp(NULL,r,a,recp,ctx); | 123 | ret = BN_div_recp(NULL,r,ca,recp,ctx); |
122 | ret=1; | ||
123 | err: | 124 | err: |
124 | BN_CTX_end(ctx); | 125 | BN_CTX_end(ctx); |
125 | return(ret); | 126 | return(ret); |
126 | } | 127 | } |
127 | 128 | ||
128 | int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp, | 129 | int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, |
129 | BN_CTX *ctx) | 130 | BN_RECP_CTX *recp, BN_CTX *ctx) |
130 | { | 131 | { |
131 | int i,j,ret=0; | 132 | int i,j,ret=0; |
132 | BIGNUM *a,*b,*d,*r; | 133 | BIGNUM *a,*b,*d,*r; |
@@ -146,8 +147,8 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp, | |||
146 | 147 | ||
147 | if (BN_ucmp(m,&(recp->N)) < 0) | 148 | if (BN_ucmp(m,&(recp->N)) < 0) |
148 | { | 149 | { |
149 | BN_zero(d); | 150 | if (!BN_zero(d)) return 0; |
150 | BN_copy(r,m); | 151 | if (!BN_copy(r,m)) return 0; |
151 | BN_CTX_end(ctx); | 152 | BN_CTX_end(ctx); |
152 | return(1); | 153 | return(1); |
153 | } | 154 | } |
@@ -157,20 +158,28 @@ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp, | |||
157 | * we need multiply ABCDEF by 3 digests of the reciprocal of ab | 158 | * we need multiply ABCDEF by 3 digests of the reciprocal of ab |
158 | * | 159 | * |
159 | */ | 160 | */ |
160 | i=BN_num_bits(m); | ||
161 | 161 | ||
162 | /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */ | ||
163 | i=BN_num_bits(m); | ||
162 | j=recp->num_bits<<1; | 164 | j=recp->num_bits<<1; |
163 | if (j>i) i=j; | 165 | if (j>i) i=j; |
164 | j>>=1; | ||
165 | 166 | ||
167 | /* Nr := round(2^i / N) */ | ||
166 | if (i != recp->shift) | 168 | if (i != recp->shift) |
167 | recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N), | 169 | recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N), |
168 | i,ctx); | 170 | i,ctx); /* BN_reciprocal returns i, or -1 for an error */ |
171 | if (recp->shift == -1) goto err; | ||
169 | 172 | ||
170 | if (!BN_rshift(a,m,j)) goto err; | 173 | /* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))| |
174 | * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))| | ||
175 | * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)| | ||
176 | * = |m/N| | ||
177 | */ | ||
178 | if (!BN_rshift(a,m,recp->num_bits)) goto err; | ||
171 | if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err; | 179 | if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err; |
172 | if (!BN_rshift(d,b,i-j)) goto err; | 180 | if (!BN_rshift(d,b,i-recp->num_bits)) goto err; |
173 | d->neg=0; | 181 | d->neg=0; |
182 | |||
174 | if (!BN_mul(b,&(recp->N),d,ctx)) goto err; | 183 | if (!BN_mul(b,&(recp->N),d,ctx)) goto err; |
175 | if (!BN_usub(r,m,b)) goto err; | 184 | if (!BN_usub(r,m,b)) goto err; |
176 | r->neg=0; | 185 | r->neg=0; |
@@ -201,20 +210,21 @@ err: | |||
201 | * We actually calculate with an extra word of precision, so | 210 | * We actually calculate with an extra word of precision, so |
202 | * we can do faster division if the remainder is not required. | 211 | * we can do faster division if the remainder is not required. |
203 | */ | 212 | */ |
204 | int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx) | 213 | /* r := 2^len / m */ |
214 | int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) | ||
205 | { | 215 | { |
206 | int ret= -1; | 216 | int ret= -1; |
207 | BIGNUM t; | 217 | BIGNUM t; |
208 | 218 | ||
209 | BN_init(&t); | 219 | BN_init(&t); |
210 | 220 | ||
211 | BN_zero(&t); | 221 | if (!BN_zero(&t)) goto err; |
212 | if (!BN_set_bit(&t,len)) goto err; | 222 | if (!BN_set_bit(&t,len)) goto err; |
213 | 223 | ||
214 | if (!BN_div(r,NULL,&t,m,ctx)) goto err; | 224 | if (!BN_div(r,NULL,&t,m,ctx)) goto err; |
225 | |||
215 | ret=len; | 226 | ret=len; |
216 | err: | 227 | err: |
217 | BN_free(&t); | 228 | BN_free(&t); |
218 | return(ret); | 229 | return(ret); |
219 | } | 230 | } |
220 | |||