1 /* crypto/bn/bn_knuth.c */
7 /* This is just a test implementation, it has not been modified for
8 * speed and it still has memory leaks. */
10 int BN_mask_bits(BIGNUM *a,int n);
15 /* r must be different to a and b
16 * Toom-Cook multiplication algorithm, taken from
17 * The Art Of Computer Programming, Volume 2, Donald Knuth
20 #define CODE1 ((BIGNUM *)0x01)
21 #define CODE2 ((BIGNUM *)0x02)
22 #define CODE3 ((BIGNUM *)0x03)
37 int max=0,max_total=0;
39 BIGNUM *LBN_new(void );
40 BIGNUM *LBN_dup(BIGNUM *a);
41 void LBN_free(BIGNUM *a);
43 int BN_mul_knuth(w, a, b)
50 BIGNUM *U[MAXK],*V[MAXK],*T[MAXK];
51 BIGNUM *C[(MAXK*2*3)];
52 BIGNUM *W[(MAXK*2)],*t1,*t2,*t3,*t4;
53 int Utos,Vtos,Ctos,Wtos,Ttos;
60 Utos=Vtos=Ctos=Wtos=Ttos=0;
67 if (!bn_expand(w,BN_BITS2*2)) goto err;
71 while ((q[k-1]+q[k]) < n)
82 for (i=0; i<=k; i++) printf("%7d",i);
84 for (i=0; i<=k; i++) printf("%7d",q[i]);
86 for (i=0; i<=k; i++) printf("%7d",r[i]);
92 if ((t1=LBN_dup(a)) == NULL) goto err;
94 if ((t1=LBN_dup(b)) == NULL) goto err;
101 printf("state=C%d, Ctos=%d Wtos=%d\n",state,Ctos,Wtos);
113 printf("Ctos=%d poped %d\n",Ctos,2);
115 if ((t2->top == 0) || (t1->top == 0))
120 LBN_free(t1); /* FREE */
121 LBN_free(t2); /* FREE */
133 for (z=0; z<2; z++) /* do for u and v */
135 /* break the item at C[Ctos-1]
136 * into lr+1 parts of lq bits each
137 * for j=0; j<=2r; j++
139 t1=C[--Ctos]; /* pop off u */
141 printf("Ctos=%d poped %d\n",Ctos,1);
143 if ((t2=LBN_dup(t1)) == NULL) goto err;
147 printf("C4 r=0 bits=%d\n",BN_num_bits(t2));
149 for (i=1; i<=lr; i++)
151 if (!BN_rshift(t1,t1,lq)) goto err;
152 if ((t2=LBN_dup(t1)) == NULL) goto err;
156 printf("C4 r=%d bits=%d\n",i,
162 if ((t2=LBN_new()) == NULL) goto err;
163 if ((t3=LBN_new()) == NULL) goto err;
164 for (j=0; j<=2*lr; j++)
166 if ((t1=LBN_new()) == NULL) goto err;
168 if (!BN_set_word(t3,j)) goto err;
169 for (i=lr; i>=0; i--)
171 if (!BN_mul(t2,t1,t3)) goto err;
172 if (!BN_add(t1,t2,T[i])) goto err;
182 while (Ttos) LBN_free(T[--Ttos]);
185 for (i=0; i<Utos; i++)
186 printf("U[%2d]=%4d bits\n",i,BN_num_bits(U[i]));
187 for (i=0; i<Vtos; i++)
188 printf("V[%2d]=%4d bits\n",i,BN_num_bits(V[i]));
192 printf("PUSH CODE2 and %d CODE3 onto stack\n",2*lr);
195 for (i=2*lr; i>0; i--)
204 printf("Ctos=%d pushed %d\n",Ctos,2*lr*3+3);
210 if ((t1=LBN_dup(w)) == NULL) goto err;
213 printf("put %d bit number onto w\n",BN_num_bits(t1));
222 for (j=1; j<=2*lr; j++)
224 for (i=2*lr; i>=j; i--)
226 if (!BN_sub(W[z+i],W[z+i],W[z+i-1])) goto err;
227 BN_div_word(W[z+i],j);
234 if ((t1=LBN_new()) == NULL) goto err;
235 if ((t3=LBN_new()) == NULL) goto err;
239 if (!BN_set_word(t3,j)) goto err;
242 if (!BN_mul(t1,W[z+i+1],t3)) goto err;
243 if (!BN_sub(W[z+i],W[z+i],t1)) goto err;
253 printf("lq=%d\n",lq);
255 for (i=lr*2; i>=0; i--)
260 for (i=0; i<=lr*2; i++)
268 printf("Ctos=%d poped %d\n",Ctos,1);
269 printf("code= CODE%d\n",t1);
273 else if (t1 == CODE2)
275 if ((t2=LBN_dup(w)) == NULL) goto err;
279 else if (t1 == CODE1)
285 printf("BAD ERROR\n");
290 printf("bad state\n");
294 if (state == DONE) break;
298 if (ret == 0) printf("ERROR\n");
308 if ((a=LBN_new()) == NULL) goto err;
309 if ((b=LBN_new()) == NULL) goto err;
310 if ((r=LBN_new()) == NULL) goto err;
312 if (!BN_rand(a,1024*2,0,0)) goto err;
313 if (!BN_rand(b,1024*2,0,0)) goto err;
317 if (!BN_mul_knuth(r,a,b)) goto err; /**/
318 /*if (!BN_mul(r,a,b)) goto err; /**/
320 BN_print(stdout,a); printf(" * ");
321 BN_print(stdout,b); printf(" =\n");
322 BN_print(stdout,r); printf("\n");
324 printf("BN_new() =%d\nBN_free()=%d max=%d\n",new_total,Free_total,max);
329 ERR_load_crypto_strings();
330 ERR_print_errors(stderr);
335 int BN_mask_bits(a,n)
343 if (w >= a->top) return(0);
349 a->d[w]&= ~(BN_MASK2<<b);
359 if (max_total > max) max=max_total;
367 if (max_total > max) max=max_total;
375 if (max_total > max) max=max_total;