summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_recp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_recp.c')
-rw-r--r--src/lib/libcrypto/bn/bn_recp.c48
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
94int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) 94int 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
103int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp, 103int 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;
123err: 124err:
124 BN_CTX_end(ctx); 125 BN_CTX_end(ctx);
125 return(ret); 126 return(ret);
126 } 127 }
127 128
128int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp, 129int 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 */
204int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx) 213/* r := 2^len / m */
214int 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;
216err: 227err:
217 BN_free(&t); 228 BN_free(&t);
218 return(ret); 229 return(ret);
219 } 230 }
220