1 
2 /***************************************************************************
3                                                                            *
4 Copyright 2012 CertiVox IOM Ltd.                                           *
5                                                                            *
6 This file is part of CertiVox MIRACL Crypto SDK.                           *
7                                                                            *
8 The CertiVox MIRACL Crypto SDK provides developers with an                 *
9 extensive and efficient set of cryptographic functions.                    *
10 For further information about its features and functionalities please      *
11 refer to http://www.certivox.com                                           *
12                                                                            *
13 * The CertiVox MIRACL Crypto SDK is free software: you can                 *
14   redistribute it and/or modify it under the terms of the                  *
15   GNU Affero General Public License as published by the                    *
16   Free Software Foundation, either version 3 of the License,               *
17   or (at your option) any later version.                                   *
18                                                                            *
19 * The CertiVox MIRACL Crypto SDK is distributed in the hope                *
20   that it will be useful, but WITHOUT ANY WARRANTY; without even the       *
21   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
22   See the GNU Affero General Public License for more details.              *
23                                                                            *
24 * You should have received a copy of the GNU Affero General Public         *
25   License along with CertiVox MIRACL Crypto SDK.                           *
26   If not, see <http://www.gnu.org/licenses/>.                              *
27                                                                            *
28 You can be released from the requirements of the license by purchasing     *
29 a commercial license. Buying such a license is mandatory as soon as you    *
30 develop commercial activities involving the CertiVox MIRACL Crypto SDK     *
31 without disclosing the source code of your own applications, or shipping   *
32 the CertiVox MIRACL Crypto SDK with a closed source product.               *
33                                                                            *
34 ***************************************************************************/
35 /*
36  *   Benchmarking program for PK implementations
37  *
38  */
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <time.h>
43 #include "miracl.h"
44 
45 /* define minimum duration of each timing, and min. number of iterations */
46 
47 #define MIN_TIME 10.0
48 #define MIN_ITERS 20
49 
50 /* define fixed precomputation window size */
51 
52 #define WINDOW 8
53 
54 /* random "safe" primes - (p-1)/2 is also prime */
55 
56 char p512[]="A89BmxRFLAnMTGV1EofBF3t9vxHwLw3upSiJQqGrSSJanNwAWm4qeIpR0QZos81Cb0T3GSB8Vvioo2ShdHeocZl";
57 char p1024[]="33pn5XYfRZ6oa1SgeSZ0gLXbIHYKsAL2vf2hMPp4BShBUUwVqJSaZMHBtYRr2C8CtD2ql3cKco8tsbol9KiiW0kmgYdmX2OYuDirwVHBXU6iarsuWLsFI8f9IcXF5mQUhhIfNL1UgB9iOopI4DZJdaAkweMrr0L7H6DTcJCv4uOG8l";
58 char p2048[]="9JhODtckdgHoisG3BF7icLO1W2kQN8uERdD45ta8ECK2pSl74xmjtptZhoFRXLCn8SHJtmwXTuf6aUbUUGsT6dE8GMWSkdg3qN4owcJE6wuCUiKKDOrsUEaFA6GCaSoHrHd6upEOTFJrSt5JZvvPUmZExbgTtVkZaM3EHVO5hhmaOglEXNmWbQlSZR57EPH4VS5nYPHsj3YEqtQjBxOg509VY3Efa3WCBXSILEksrBCdxBFeboPQ2ImO8gt52UX68ClTq4hUO7HltCJ8DEXT0QitGp5G39H3EGlBM7a1Pto1XRctShgDCJkKtedRvCTHJ81IaLUM2QRgVvY2oAUfU6DpqPl";
59 
60 
61 /* 160-bit Elliptic Curve A= -3 (1,y) is of prime order r wrt prime p */
62 
63 char b160[]="547961736808018748879088091015409822321903727720";
64 char y160[]="1184021062507719516935416374276431034553065993786";
65 char p160[]="1243254415344564576487568858887587143562341624873";
66 char r160[]="1243254415344564576487570064860738948886682236669";
67 
68 
69 /* 192-bit Elliptic Curve A= -3 (1,y) is of prime order r wrt prime p */
70 
71 char b192[]="4061049254666112630970447728594959377821841236338949398359";
72 char y192[]="939373580274738592696031201994651073677369517020051213856";
73 char p192[]="4361274637164371634176431764172114141371368173651736587859";
74 char r192[]="4361274637164371634176431764042976768701814568420333347189";
75 
76 /* 224-bit Elliptic Curve A= -3 (1,y) is of prime order r wrt prime p */
77 
78 char b224[]="17383927112623192126321700675122043803151281370446907580591543997888";
79 char y224[]="6566202929975094781252846334642707436688198986599754639429350077046";
80 char p224[]="26237462376427386428736423786423764364625346524653462546544347644653";
81 char r224[]="26237462376427386428736423786423773752689811507809031319417547459991";
82 
83 /* 256-bit Elliptic Curve A= -3 (1,y) is of prime order r wrt prime p */
84 
85 char b256[]="25389140340672155341527372976612393184553582461816899055687141548002290977046";
86 char y256[]="51289739734510562976895380525256763300476168821636300126346201758371757118206";
87 char p256[]="115324781748134865946503563657643838352352623747656242345890742746828256867467";
88 char r256[]="115324781748134865946503563657643838352221626521810006206950260876359658535911";
89 
90 #ifndef MR_FP
91 
92 /* Elliptic Curve wrt GF(2^163). This is NIST standard Curve */
93 
94 int  A163=1;
95 char B163[]="20A601907B8C953CA1481EB10512F78744A3205FD";
96 char x163[]="3F0EBA16286A2D57EA0991168D4994637E8343E36";
97 char y163[]="D51FBC6C71A0094FA2CDD545B11C5C0C797324F1";
98 int  m163=163;
99 int  a163=7;
100 int  b163=6;
101 int  c163=3;
102 char r163[]="5846006549323611672814742442876390689256843201587";
103 int cf163=2;
104 
105 /* Elliptic Curve wrt GF(2^163). NIST Koblitz Curve */
106 
107 int KA163=1;
108 char KB163[]="1";
109 char Kx163[]="396C30B475EF87A2B37CA911D272DE90E109CA80F";
110 char Ky163[]="3947D0E4C8BB41DC3BABB142D2923A253D6E76391";
111 
112 /* Elliptic Curve wrt GF(2^233). This is NIST standard Curve */
113 
114 int  A233=1;
115 char B233[]="66647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD";
116 char x233[]="FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B";
117 char y233[]="1006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052";
118 int  m233=233;
119 int  a233=74;
120 int  b233=0;
121 int  c233=0;
122 char r233[]="6901746346790563787434755862277025555839812737345013555379383634485463";
123 int cf233=2;
124 
125 /* Elliptic Curve wrt GF(2^233). This is NIST Koblitz Curve */
126 
127 int  KA233=0;
128 char KB233[]="1";
129 char Kx233[]="17232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126";
130 char Ky233[]="1db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3";
131 
132 /* Elliptic Curve wrt GF(2^283). This is NIST standard Curve */
133 
134 int  A283=1;
135 char B283[]="27B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5";
136 char x283[]="5F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053";
137 char y283[]="3676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4";
138 int  m283=283;
139 int  a283=12;/* 119; these are faster.. */
140 int  b283=7; /* 97; */
141 int  c283=5; /* 93; */
142 char r283[]="7770675568902916283677847627294075626569625924376904889109196526770044277787378692871";
143 int cf283=2;
144 
145 /* Elliptic Curve wrt GF(2^283). This is NIST Koblitz Curve */
146 
147 int  KA283=0;
148 char KB283[]="1";
149 char Kx283[]="503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836";
150 char Ky283[]="1ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259";
151 
152 /* Elliptic Curve wrt GF(2^571). This is NIST standard Curve */
153 
154 int  A571=1;
155 char B571[]="02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A";
156 char x571[]="0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19";
157 char y571[]="037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B";
158 int  m571=571;
159 int  a571=10;
160 int  b571=5;
161 int  c571=2;
162 int  cf571=2;
163 
164 /* Elliptic Curve wrt GF(2^571). This is NIST Koblitz Curve */
165 
166 int  KA571=0;
167 char KB571[]="1";
168 char Kx571[]="026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972";
169 char Ky571[]="0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3";
170 
171 #endif
172 
primemod(int bits,big p)173 void primemod(int bits,big p)
174 {
175     do {
176         printf("%d bit prime.....\n",bits);
177         bigbits(bits,p);
178         nxprime(p,p);
179     } while (logb2(p)!=bits);
180 }
181 
powers(int gb,int eb,big p)182 double powers(int gb,int eb,big p)
183 {
184     int iterations=0;
185     big g,e,w;
186     clock_t start;
187     double elapsed;
188     char *mem;
189 
190     mem=(char *)memalloc(3);
191     g=mirvar_mem(mem,0);
192     e=mirvar_mem(mem,1);
193     w=mirvar_mem(mem,2);
194 
195     bigbits(gb,g);
196     bigbits(eb,e);
197     start=clock();
198 
199     do {
200        powmod(g,e,p,w);
201        iterations++;
202        elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
203     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
204 
205     elapsed=1000.0*elapsed/iterations;
206     printf("R - %8d iterations of %4d/%4d ",iterations,gb,eb);
207     printf(" %8.2lf ms per iteration\n",elapsed);
208 
209     memkill(mem,3);
210 
211     return elapsed;
212 }
213 
mults(int eb,epoint * g)214 double mults(int eb,epoint *g)
215 {
216     big e;
217     int iterations=0;
218     clock_t start;
219     double elapsed;
220     epoint *w,*r;
221     char *mem1;
222     char *mem2;
223 
224     mem1=(char *)memalloc(1);
225     mem2=(char *)ecp_memalloc(2);
226 
227     e=mirvar_mem(mem1,0);
228     w=epoint_init_mem(mem2,0);
229     r=epoint_init_mem(mem2,1);
230 
231     bigbits(eb,e);
232     ecurve_mult(e,g,r);   /* generate a random point on the curve */
233     bigbits(eb,e);
234     start=clock();
235 
236     do {
237        ecurve_mult(e,r,w);
238        iterations++;
239        elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
240     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
241 
242     elapsed=1000.0*elapsed/iterations;
243     printf("ER - %8d iterations             ",iterations);
244     printf(" %8.2lf ms per iteration\n",elapsed);
245 
246     memkill(mem1,1);
247     ecp_memkill(mem2,2);
248     return elapsed;
249 }
250 
251 #ifndef MR_FP
252 
mults2(int eb,epoint * g)253 double mults2(int eb,epoint *g)
254 {
255     big e;
256     int iterations=0;
257     clock_t start;
258     double elapsed;
259     epoint *w;
260     epoint *r;
261     char *mem1;
262     char *mem2;
263 
264     mem1=(char *)memalloc(1);
265     mem2=(char *)ecp_memalloc(2);
266 
267     e=mirvar_mem(mem1,0);
268     w=epoint_init_mem(mem2,0);
269     r=epoint_init_mem(mem2,1);
270 
271     bigbits(eb,e);
272     ecurve2_mult(e,g,r);   /* generate a random point on the curve */
273     bigbits(eb,e);
274     start=clock();
275 
276     do {
277        ecurve2_mult(e,r,w);
278        iterations++;
279        elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
280     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
281 
282     elapsed=1000.0*elapsed/iterations;
283     printf("ER - %8d iterations             ",iterations);
284     printf(" %8.2lf ms per iteration\n",elapsed);
285 
286     memkill(mem1,1);
287     ecp_memkill(mem2,2);
288 
289     return elapsed;
290 }
291 
292 #endif
293 
powers_small_base(int g,int eb,big p)294 double powers_small_base(int g,int eb,big p)
295 {
296     int iterations=0;
297     big e,w;
298     clock_t start;
299     double elapsed;
300     char *mem;
301 
302     mem=(char *)memalloc(2);
303 
304     e=mirvar_mem(mem,0);
305     w=mirvar_mem(mem,1);
306     bigbits(eb,e);
307     start=clock();
308 
309     do {
310         powltr(g,e,p,w);
311         iterations++;
312         elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
313     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
314 
315     elapsed=1000.0*elapsed/iterations;
316     printf("S - %8d iterations of  g=%d/%4d ",iterations,g,eb);
317     printf(" %8.2lf ms per iteration\n",elapsed);
318 
319     memkill(mem,2);
320     return elapsed;
321 }
322 
powers_double(int gb,int eb,big p)323 double powers_double(int gb,int eb,big p)
324 {
325     int iterations=0;
326     clock_t start;
327     double elapsed;
328     big g1,e1,g2,e2,w;
329     char *mem;
330 
331     mem=(char *)memalloc(5);
332     g1=mirvar_mem(mem,0);
333     e1=mirvar_mem(mem,1);
334     g2=mirvar_mem(mem,2);
335     e2=mirvar_mem(mem,3);
336     w=mirvar_mem(mem,4);
337     bigbits(gb,g1);
338     bigbits(gb,g2);
339     bigbits(eb,e1);
340     bigbits(eb,e2);
341     start=clock();
342     do {
343         powmod2(g1,e1,g2,e2,p,w);
344         iterations++;
345         elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
346     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
347 
348     elapsed=1000.0*elapsed/iterations;
349     printf("D - %8d iterations of %4d/%4d ",iterations,gb,eb);
350     printf(" %8.2lf ms per iteration\n",elapsed);
351 
352     memkill(mem,4);
353 
354     return elapsed;
355 }
356 
mult_double(int eb,epoint * g)357 double mult_double(int eb,epoint *g)
358 {
359     big e1,e2;
360     int iterations=0;
361     clock_t start;
362     double elapsed;
363     char *mem1;
364     char *mem2;
365     epoint *w;
366     epoint *r1;
367     epoint *r2;
368 
369     mem1=(char *)memalloc(2);
370     mem2=(char *)ecp_memalloc(3);
371 
372     e1=mirvar_mem(mem1,0);
373     e2=mirvar_mem(mem1,1);
374     w=epoint_init_mem(mem2,0);
375     r1=epoint_init_mem(mem2,1);
376     r2=epoint_init_mem(mem2,2);
377 
378     bigbits(eb,e1);
379     ecurve_mult(e1,g,r1);   /* generate a random point on the curve */
380     bigbits(eb,e2);
381     ecurve_mult(e2,g,r2);   /* generate a random point on the curve */
382     bigbits(eb,e1);
383     bigbits(eb,e2);
384     start=clock();
385 
386     do {
387        ecurve_mult2(e1,r1,e2,r2,w);
388        iterations++;
389        elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
390     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
391 
392     elapsed=1000.0*elapsed/iterations;
393     printf("ED - %8d iterations             ",iterations);
394     printf(" %8.2lf ms per iteration\n",elapsed);
395 
396     ecp_memkill(mem2,3);
397     memkill(mem1,2);
398 
399     return elapsed;
400 }
401 
402 #ifndef MR_FP
403 
mult2_double(int eb,epoint * g)404 double mult2_double(int eb,epoint *g)
405 {
406     big e1,e2;
407     int iterations=0;
408     clock_t start;
409     double elapsed;
410     char *mem1;
411     char *mem2;
412     epoint *w;
413     epoint *r1;
414     epoint *r2;
415 
416     mem1=(char *)memalloc(2);
417     mem2=(char *)ecp_memalloc(3);
418 
419     e1=mirvar_mem(mem1,0);
420     e2=mirvar_mem(mem1,1);
421     w=epoint_init_mem(mem2,0);
422     r1=epoint_init_mem(mem2,1);
423     r2=epoint_init_mem(mem2,2);
424 
425     bigbits(eb,e1);
426     ecurve2_mult(e1,g,r1);   /* generate a random point on the curve */
427     bigbits(eb,e2);
428     ecurve2_mult(e2,g,r2);   /* generate a random point on the curve */
429     bigbits(eb,e1);
430     bigbits(eb,e2);
431     start=clock();
432 
433     do {
434        ecurve2_mult2(e1,r1,e2,r2,w);
435        iterations++;
436        elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
437     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
438 
439     elapsed=1000.0*elapsed/iterations;
440     printf("ED - %8d iterations             ",iterations);
441     printf(" %8.2lf ms per iteration\n",elapsed);
442 
443     ecp_memkill(mem2,3);
444     memkill(mem1,2);
445 
446     return elapsed;
447 }
448 
449 #endif
450 
powers_precomp(int gb,int eb,big p)451 double powers_precomp(int gb,int eb,big p)
452 {
453     int iterations=0;
454     clock_t start;
455     double elapsed;
456     brick binst;
457     big g,e,w;
458     char *mem;
459 
460     mem=(char *)memalloc(3);
461     g=mirvar_mem(mem,0);
462     e=mirvar_mem(mem,1);
463     w=mirvar_mem(mem,2);
464     bigbits(gb,g);
465 
466     brick_init(&binst,g,p,WINDOW,eb);
467 
468     bigbits(eb,e);
469 
470     start=clock();
471     do {
472         pow_brick(&binst,e,w);
473         iterations++;
474         elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
475     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
476 
477     elapsed=1000.0*elapsed/iterations;
478     printf("P - %8d iterations of %4d/%4d ",iterations,gb,eb);
479     printf(" %8.2lf ms per iteration\n",elapsed);
480 
481     brick_end(&binst);
482 
483     memkill(mem,3);
484 
485     return elapsed;
486 }
487 
mult_precomp(int eb,big x,big y,big a,big b,big p)488 double mult_precomp(int eb,big x,big y,big a,big b,big p)
489 {
490     big e,c,d;
491     int iterations=0;
492     ebrick binst;
493     clock_t start;
494     double elapsed;
495     char *mem;
496 
497     mem=(char *)memalloc(3);
498     e=mirvar_mem(mem,0);
499     c=mirvar_mem(mem,1);
500     d=mirvar_mem(mem,2);
501     ebrick_init(&binst,x,y,a,b,p,WINDOW,eb);
502     bigbits(eb,e);
503     start=clock();
504 
505     do {
506        mul_brick(&binst,e,c,d);
507        iterations++;
508        elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
509     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
510 
511     elapsed=1000.0*elapsed/iterations;
512     printf("EP - %8d iterations             ",iterations);
513     printf(" %8.2lf ms per iteration\n",elapsed);
514 
515     ebrick_end(&binst);
516     memkill(mem,3);
517 
518     return elapsed;
519 }
520 
521 #ifndef MR_FP
522 
mult2_precomp(int eb,big x,big y,big a2,big a6,int M,int A,int B,int C)523 double mult2_precomp(int eb,big x,big y,big a2,big a6,int M,int A,int B,int C)
524 {
525     big e,c,d;
526     int iterations=0;
527     ebrick2 binst;
528     clock_t start;
529     double elapsed;
530     char *mem;
531 
532     mem=(char *)memalloc(3);
533     e=mirvar_mem(mem,0);
534     c=mirvar_mem(mem,1);
535     d=mirvar_mem(mem,2);
536     ebrick2_init(&binst,x,y,a2,a6,M,A,B,C,WINDOW,eb);
537     bigbits(eb,e);
538     start=clock();
539 
540     do {
541        mul2_brick(&binst,e,c,d);
542        iterations++;
543        elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
544     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
545 
546     elapsed=1000.0*elapsed/iterations;
547     printf("EP - %8d iterations             ",iterations);
548     printf(" %8.2lf ms per iteration\n",elapsed);
549 
550     ebrick2_end(&binst);
551     memkill(mem,3);
552 
553     return elapsed;
554 }
555 
556 #endif
557 
powers_small_exp(int gb,long ex,big p)558 double powers_small_exp(int gb,long ex,big p)
559 {
560     int iterations=0;
561     big g,e,w;
562     clock_t start;
563     double elapsed;
564     char *mem;
565 
566     mem=(char *)memalloc(3);
567     g=mirvar_mem(mem,0);
568     e=mirvar_mem(mem,1);
569     w=mirvar_mem(mem,2);
570     bigbits(gb,g);
571     start=clock();
572     lgconv(ex,e);
573     do {
574        power(g,ex,p,w);
575        iterations++;
576        elapsed=(clock()-start)/(double)CLOCKS_PER_SEC;
577     } while (elapsed<MIN_TIME || iterations<MIN_ITERS);
578 
579     elapsed=1000.0*elapsed/iterations;
580     if (ex==257L)
581         printf("V - %8d iterations of %4d/e=F3 ",iterations,gb);
582     if (ex==65537L)
583         printf("V - %8d iterations of %4d/e=F4 ",iterations,gb);
584     if (ex!=257L && ex!=65537L)
585         printf("V - %8d iterations of %4d/e=%2ld ",iterations,gb,ex);
586     printf(" %8.2lf ms per iteration\n",elapsed);
587     memkill(mem,3);
588 
589     return elapsed;
590 }
591 
main()592 int main()
593 {
594     int j,k;
595     big a,b,x,y,p,A2;
596     time_t seed;
597     epoint *g;
598     double tr1,tr2,ts,tv1,tv2,tp,td;
599 #ifndef MR_NOFULLWIDTH
600     miracl *mip=mirsys(300,0);
601 #else
602     miracl *mip=mirsys(300,MAXBASE);
603 #endif
604     p=mirvar(0);
605     a=mirvar(-3);
606     b=mirvar(0);
607     x=mirvar(1);
608     y=mirvar(0);
609     A2=mirvar(0);
610     mip->IOBASE=60;
611 
612     time(&seed);
613     irand((long)seed);
614 
615     printf("MIRACL - %d bit version\n",MIRACL);
616 #ifdef MR_LITTLE_ENDIAN
617     printf("Little Endian processor\n");
618 #endif
619 #ifdef MR_BIG_ENDIAN
620     printf("Big Endian processor\n");
621 #endif
622 #ifdef MR_NOASM
623     printf("C-Only Version of MIRACL\n");
624 #else
625     printf("Using some assembly language\n");
626 #endif
627 #ifdef MR_STRIPPED_DOWN
628     printf("Stripped down version of MIRACL - no error messages\n");
629 #endif
630 #ifdef MR_KCM
631     k=MR_KCM*MIRACL;
632     printf("Using KCM method \n");
633     printf("Optimized for %d, %d, %d, %d...etc. bit moduli\n",k,k*2,k*4,k*8);
634 #endif
635 #ifdef MR_COMBA
636     k=MR_COMBA*MIRACL;
637     printf("Using COMBA method \n");
638     printf("Optimized for %d bit moduli\n",k);
639 #endif
640 #ifdef MR_PENTIUM
641     printf("Floating-point co-processor arithmetic used for Pentium\n");
642 #endif
643 #ifndef MR_KCM
644 #ifndef MR_COMBA
645 #ifndef MR_PENTIUM
646     printf("No special optimizations\n");
647 #endif
648 #endif
649 #endif
650     printf("Precomputation uses fixed Window size = %d\n",WINDOW);
651     printf("So %d values are precomputed and stored\n",(1<<WINDOW));
652 #ifdef MR_NOFULLWIDTH
653     printf("No Fullwidth base possible\n");
654 #else
655     printf("NOTE: No optimizations/assembly language apply to GF(2^m) Elliptic Curves\n");
656 #endif
657 
658     printf("NOTE: times are elapsed real-times - so make sure nothing else is running!\n\n");
659     printf("Modular exponentiation benchmarks - calculating g^e mod p\n");
660     printf("From these figures it should be possible to roughly estimate the time\n");
661     printf("required for your favourite PK algorithm, RSA, DSA, DH, etc.\n");
662     printf("Key R - random base bits/random exponent bits \n");
663     printf("    V - random base bits/(small exponent e)   \n");
664     printf("    S - (small base g)  /random exponent bits \n");
665     printf("    P - exponentiation with precomputation (fixed base g)\n");
666     printf("    D - double exponentiation g^e.a^b mod p\n");
667 
668     printf("F3 = 257, F4 = 65537\n");
669     printf("RSA - Rivest-Shamir-Adleman\n");
670     printf("DH  - Diffie Hellman Key exchange\n");
671     printf("DSA - Digital Signature Algorithm\n");
672 
673     printf("\n512 bit prime....\n");
674     cinstr(p,p512);
675 
676     k=512;
677     j=160;
678 
679     tr1=powers(k,j,p);
680     td=powers_double(k,j,p);
681     tr2=powers(k,k,p);
682     ts=powers_small_base(3,j,p);
683     tp=powers_precomp(k,j,p);
684 
685     printf("\n");
686     printf("%4d bit RSA decryption               %8.2lf ms \n",2*k,2*tr2);
687     printf("%4d bit DH %d bit exponent:-\n",k,j);
688     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
689     printf("         offline, small base          %8.2lf ms \n",ts);
690     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
691     printf("         online                       %8.2lf ms \n",tr1);
692     printf("%4d bit DSA %d bit exponent:-\n",k,j);
693     printf("         signature no precomputation  %8.2lf ms \n",tr1);
694     printf("         signature w. precomputation  %8.2lf ms \n",tp);
695     printf("         verification                 %8.2lf ms \n",td);
696 
697     printf("\n1024 bit prime....\n");
698     cinstr(p,p1024);
699 
700     k=1024; j=160;
701     tr1=powers(k,j,p);
702     td=powers_double(k,j,p);
703     tr2=powers(k,k,p);
704     tv1=powers_small_exp(k,3,p);
705     tv2=powers_small_exp(k,65537L,p);
706     ts=powers_small_base(3,j,p);
707     tp=powers_precomp(k,j,p);
708 
709     printf("\n");
710     printf("%4d bit RSA decryption               %8.2lf ms \n",2*k,2*tr2);
711     printf("%4d bit RSA encryption e=3           %8.2lf ms \n",k,tv1);
712     printf("%4d bit RSA encryption e=65537       %8.2lf ms \n",k,tv2);
713     printf("%4d bit DH %d bit exponent:-\n",k,j);
714     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
715     printf("         offline, small base          %8.2lf ms \n",ts);
716     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
717     printf("         online                       %8.2lf ms \n",tr1);
718     printf("%4d bit DSA %d bit exponent:-\n",k,j);
719     printf("         signature no precomputation  %8.2lf ms \n",tr1);
720     printf("         signature w. precomputation  %8.2lf ms \n",tp);
721     printf("         verification                 %8.2lf ms \n",td);
722 
723     printf("\n2048 bit prime....\n");
724     cinstr(p,p2048);
725 
726     k=2048; j=256;
727 
728     tr1=powers(k,j,p);
729     td=powers_double(k,j,p);
730     powers(k,k,p);
731     tv1=powers_small_exp(k,3,p);
732     tv2=powers_small_exp(k,65537L,p);
733     ts=powers_small_base(3,j,p);
734     tp=powers_precomp(k,j,p);
735 
736     printf("\n");
737     printf("%4d bit RSA encryption e=3           %8.2lf ms \n",k,tv1);
738     printf("%4d bit RSA encryption e=65537       %8.2lf ms \n",k,tv2);
739     printf("%4d bit DH %d bit exponent:-\n",k,j);
740     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
741     printf("         offline, small base          %8.2lf ms \n",ts);
742     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
743     printf("         online                       %8.2lf ms \n",tr1);
744     printf("%4d bit DSA %d bit exponent:-\n",k,j);
745     printf("         signature no precomputation  %8.2lf ms \n",tr1);
746     printf("         signature w. precomputation  %8.2lf ms \n",tp);
747     printf("         verification                 %8.2lf ms \n",td);
748 
749     printf("\n");
750     printf("Elliptic Curve point multiplication benchmarks - calculating r.P\n");
751     printf("From these figures it should be possible to roughly estimate the time\n");
752     printf("required for your favourite EC PK algorithm, ECDSA, ECDH, etc.\n");
753     printf("Key - ER - Elliptic Curve point multiplication r.P\n");
754     printf("      ED - Elliptic Curve double multiplication r.P + s.Q\n");
755     printf("      EP - Elliptic Curve multiplication with precomputation\n");
756     printf("EC    - Elliptic curve GF(p) - p of no special form \n");
757     printf("ECDH  - Diffie Hellman Key exchange\n");
758     printf("ECDSA - Digital Signature Algorithm\n");
759 
760     mip->IOBASE=10;
761 
762     printf("\n160 bit GF(p) Elliptic Curve....\n");
763     k=160;
764     cinstr(p,p160);
765     cinstr(b,b160);
766     cinstr(y,y160);
767 
768     ecurve_init(a,b,p,MR_PROJECTIVE);
769     g=epoint_init();
770     if (!epoint_set(x,y,0,g))
771     {
772         printf("This is not a point on the curve!\n");
773         exit(0);
774     }
775 
776     tr1=mults(k,g);
777     td=mult_double(k,g);
778     tp=mult_precomp(k,x,y,a,b,p);
779 
780     printf("\n");
781     printf("%4d bit ECDH :-\n",k);
782     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
783     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
784     printf("         online                       %8.2lf ms \n",tr1);
785     printf("%4d bit ECDSA :-\n",k);
786     printf("         signature no precomputation  %8.2lf ms \n",tr1);
787     printf("         signature w. precomputation  %8.2lf ms \n",tp);
788     printf("         verification                 %8.2lf ms \n",td);
789 
790     printf("\n192 bit GF(p) Elliptic Curve....\n");
791     k=192;
792     cinstr(p,p192);
793     cinstr(b,b192);
794     cinstr(y,y192);
795 
796     ecurve_init(a,b,p,MR_PROJECTIVE);
797     g=epoint_init();
798     if (!epoint_set(x,y,0,g))
799     {
800         printf("This is not a point on the curve!\n");
801         exit(0);
802     }
803 
804 
805     tr1=mults(k,g);
806     td=mult_double(k,g);
807     tp=mult_precomp(k,x,y,a,b,p);
808 
809     printf("\n");
810     printf("%4d bit ECDH :-\n",k);
811     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
812     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
813     printf("         online                       %8.2lf ms \n",tr1);
814     printf("%4d bit ECDSA :-\n",k);
815     printf("         signature no precomputation  %8.2lf ms \n",tr1);
816     printf("         signature w. precomputation  %8.2lf ms \n",tp);
817     printf("         verification                 %8.2lf ms \n",td);
818 
819     printf("\n224 bit GF(p) Elliptic Curve....\n");
820     k=224;
821     cinstr(p,p224);
822     cinstr(b,b224);
823     cinstr(y,y224);
824 
825     ecurve_init(a,b,p,MR_PROJECTIVE);
826     g=epoint_init();
827     if (!epoint_set(x,y,0,g))
828     {
829         printf("This is not a point on the curve!\n");
830         exit(0);
831     }
832 
833     tr1=mults(k,g);
834     td=mult_double(k,g);
835     tp=mult_precomp(k,x,y,a,b,p);
836 
837     printf("\n");
838     printf("%4d bit ECDH :-\n",k);
839     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
840     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
841     printf("         online                       %8.2lf ms \n",tr1);
842     printf("%4d bit ECDSA :-\n",k);
843     printf("         signature no precomputation  %8.2lf ms \n",tr1);
844     printf("         signature w. precomputation  %8.2lf ms \n",tp);
845     printf("         verification                 %8.2lf ms \n",td);
846 
847     printf("\n256 bit GF(p) Elliptic Curve....\n");
848     k=256;
849     cinstr(p,p256);
850     cinstr(b,b256);
851     cinstr(y,y256);
852 
853     ecurve_init(a,b,p,MR_PROJECTIVE);
854     g=epoint_init();
855     if (!epoint_set(x,y,0,g))
856     {
857         printf("This is not a point on the curve!\n");
858         exit(0);
859     }
860 
861     tr1=mults(k,g);
862     td=mult_double(k,g);
863     tp=mult_precomp(k,x,y,a,b,p);
864 
865     printf("\n");
866     printf("%4d bit ECDH :-\n",k);
867     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
868     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
869     printf("         online                       %8.2lf ms \n",tr1);
870     printf("%4d bit ECDSA :-\n",k);
871     printf("         signature no precomputation  %8.2lf ms \n",tr1);
872     printf("         signature w. precomputation  %8.2lf ms \n",tp);
873     printf("         verification                 %8.2lf ms \n",td);
874 
875 #ifndef MR_FP
876 
877     printf("\n163 bit GF(2^m) Elliptic Curve....\n");
878     k=163;
879     mip->IOBASE=16;
880     cinstr(b,B163);
881     cinstr(x,x163);
882     cinstr(y,y163);
883     mip->IOBASE=10;
884     convert(A163,A2);
885     ecurve2_init(m163,a163,b163,c163,A2,b,FALSE,MR_PROJECTIVE);
886     g=epoint_init();
887     if (!epoint2_set(x,y,0,g))
888     {
889         printf("This is not a point on the curve!\n");
890         exit(0);
891     }
892 
893     tr1=mults2(k,g);
894     td=mult2_double(k,g);
895     tp=mult2_precomp(k,x,y,A2,b,m163,a163,b163,c163);
896 
897     printf("\n");
898     printf("%4d bit ECDH :-\n",k);
899     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
900     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
901     printf("         online                       %8.2lf ms \n",tr1);
902     printf("%4d bit ECDSA :-\n",k);
903     printf("         signature no precomputation  %8.2lf ms \n",tr1);
904     printf("         signature w. precomputation  %8.2lf ms \n",tp);
905     printf("         verification                 %8.2lf ms \n",td);
906 
907     printf("\n163 bit GF(2^m) Koblitz Elliptic Curve....\n");
908     k=163;
909     mip->IOBASE=16;
910     cinstr(b,KB163);
911     cinstr(x,Kx163);
912     cinstr(y,Ky163);
913     mip->IOBASE=10;
914     convert(KA163,A2);
915     ecurve2_init(m163,a163,b163,c163,A2,b,FALSE,MR_PROJECTIVE);
916     g=epoint_init();
917     if (!epoint2_set(x,y,0,g))
918     {
919         printf("This is not a point on the curve!\n");
920         exit(0);
921     }
922 
923     tr1=mults2(k,g);
924     td=mult2_double(k,g);
925     tp=mult2_precomp(k,x,y,A2,b,m163,a163,b163,c163);
926 
927     printf("\n");
928     printf("%4d bit ECDH :-\n",k);
929     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
930     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
931     printf("         online                       %8.2lf ms \n",tr1);
932     printf("%4d bit ECDSA :-\n",k);
933     printf("         signature no precomputation  %8.2lf ms \n",tr1);
934     printf("         signature w. precomputation  %8.2lf ms \n",tp);
935     printf("         verification                 %8.2lf ms \n",td);
936 
937     printf("\n233 bit GF(2^m) Elliptic Curve....\n");
938     k=233;
939     mip->IOBASE=16;
940     cinstr(b,B233);
941     cinstr(x,x233);
942     cinstr(y,y233);
943     mip->IOBASE=10;
944     convert(A233,A2);
945     ecurve2_init(m233,a233,b233,c233,A2,b,FALSE,MR_PROJECTIVE);
946     g=epoint_init();
947     if (!epoint2_set(x,y,0,g))
948     {
949         printf("This is not a point on the curve!\n");
950         exit(0);
951     }
952 
953     tr1=mults2(k,g);
954     td=mult2_double(k,g);
955     tp=mult2_precomp(k,x,y,A2,b,m233,a233,b233,c233);
956 
957     printf("\n");
958     printf("%4d bit ECDH :-\n",k);
959     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
960     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
961     printf("         online                       %8.2lf ms \n",tr1);
962     printf("%4d bit ECDSA :-\n",k);
963     printf("         signature no precomputation  %8.2lf ms \n",tr1);
964     printf("         signature w. precomputation  %8.2lf ms \n",tp);
965     printf("         verification                 %8.2lf ms \n",td);
966 
967     printf("\n233 bit GF(2^m) Koblitz Elliptic Curve....\n");
968     k=233;
969     mip->IOBASE=16;
970     cinstr(b,KB233);
971     cinstr(x,Kx233);
972     cinstr(y,Ky233);
973     mip->IOBASE=10;
974     convert(KA233,A2);
975     ecurve2_init(m233,a233,b233,c233,A2,b,FALSE,MR_PROJECTIVE);
976     g=epoint_init();
977     if (!epoint2_set(x,y,0,g))
978     {
979         printf("This is not a point on the curve!\n");
980         exit(0);
981     }
982 
983     tr1=mults2(k,g);
984     td=mult2_double(k,g);
985     tp=mult2_precomp(k,x,y,A2,b,m233,a233,b233,c233);
986 
987     printf("\n");
988     printf("%4d bit ECDH :-\n",k);
989     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
990     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
991     printf("         online                       %8.2lf ms \n",tr1);
992     printf("%4d bit ECDSA :-\n",k);
993     printf("         signature no precomputation  %8.2lf ms \n",tr1);
994     printf("         signature w. precomputation  %8.2lf ms \n",tp);
995     printf("         verification                 %8.2lf ms \n",td);
996 
997 
998     printf("\n283 bit GF(2^m) Elliptic Curve....\n");
999     k=283;
1000     mip->IOBASE=16;
1001     cinstr(b,B283);
1002     cinstr(x,x283);
1003     cinstr(y,y283);
1004     mip->IOBASE=10;
1005 
1006     convert(A283,A2);
1007     ecurve2_init(m283,a283,b283,c283,A2,b,FALSE,MR_PROJECTIVE);
1008     g=epoint_init();
1009     if (!epoint2_set(x,y,0,g))
1010     {
1011         printf("This is not a point on the curve!\n");
1012         exit(0);
1013     }
1014 
1015     tr1=mults2(k,g);
1016     td=mult2_double(k,g);
1017     tp=mult2_precomp(k,x,y,A2,b,m283,a283,b283,c283);
1018 
1019     printf("\n");
1020     printf("%4d bit ECDH :-\n",k);
1021     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
1022     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
1023     printf("         online                       %8.2lf ms \n",tr1);
1024     printf("%4d bit ECDSA :-\n",k);
1025     printf("         signature no precomputation  %8.2lf ms \n",tr1);
1026     printf("         signature w. precomputation  %8.2lf ms \n",tp);
1027     printf("         verification                 %8.2lf ms \n",td);
1028 
1029     printf("\n283 bit GF(2^m) Koblitz Elliptic Curve....\n");
1030     k=283;
1031     mip->IOBASE=16;
1032     cinstr(b,KB283);
1033     cinstr(x,Kx283);
1034     cinstr(y,Ky283);
1035     mip->IOBASE=10;
1036 
1037     convert(KA283,A2);
1038     ecurve2_init(m283,a283,b283,c283,A2,b,FALSE,MR_PROJECTIVE);
1039     g=epoint_init();
1040     if (!epoint2_set(x,y,0,g))
1041     {
1042         printf("This is not a point on the curve!\n");
1043         exit(0);
1044     }
1045 
1046     tr1=mults2(k,g);
1047     td=mult2_double(k,g);
1048     tp=mult2_precomp(k,x,y,A2,b,m283,a283,b283,c283);
1049 
1050     printf("\n");
1051     printf("%4d bit ECDH :-\n",k);
1052     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
1053     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
1054     printf("         online                       %8.2lf ms \n",tr1);
1055     printf("%4d bit ECDSA :-\n",k);
1056     printf("         signature no precomputation  %8.2lf ms \n",tr1);
1057     printf("         signature w. precomputation  %8.2lf ms \n",tp);
1058     printf("         verification                 %8.2lf ms \n",td);
1059 
1060     printf("\n571 bit GF(2^m) Elliptic Curve....\n");
1061     k=571;
1062     mip->IOBASE=16;
1063     cinstr(b,B571);
1064     cinstr(x,x571);
1065     cinstr(y,y571);
1066     mip->IOBASE=10;
1067 
1068     convert(A571,A2);
1069     ecurve2_init(m571,a571,b571,c571,A2,b,FALSE,MR_PROJECTIVE);
1070     g=epoint_init();
1071     if (!epoint2_set(x,y,0,g))
1072     {
1073         printf("This is not a point on the curve!\n");
1074         exit(0);
1075     }
1076 
1077     tr1=mults2(k,g);
1078     td=mult2_double(k,g);
1079     tp=mult2_precomp(k,x,y,A2,b,m571,a571,b571,c571);
1080 
1081     printf("\n");
1082     printf("%4d bit ECDH :-\n",k);
1083     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
1084     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
1085     printf("         online                       %8.2lf ms \n",tr1);
1086     printf("%4d bit ECDSA :-\n",k);
1087     printf("         signature no precomputation  %8.2lf ms \n",tr1);
1088     printf("         signature w. precomputation  %8.2lf ms \n",tp);
1089     printf("         verification                 %8.2lf ms \n",td);
1090 
1091     printf("\n571 bit GF(2^m) Koblitz Elliptic Curve....\n");
1092     k=571;
1093     mip->IOBASE=16;
1094     cinstr(b,KB571);
1095     cinstr(x,Kx571);
1096     cinstr(y,Ky571);
1097     mip->IOBASE=10;
1098 
1099     convert(KA571,A2);
1100     ecurve2_init(m571,a571,b571,c571,A2,b,FALSE,MR_PROJECTIVE);
1101     g=epoint_init();
1102     if (!epoint2_set(x,y,0,g))
1103     {
1104         printf("This is not a point on the curve!\n");
1105         exit(0);
1106     }
1107 
1108     tr1=mults2(k,g);
1109     td=mult2_double(k,g);
1110     tp=mult2_precomp(k,x,y,A2,b,m571,a571,b571,c571);
1111 
1112     printf("\n");
1113     printf("%4d bit ECDH :-\n",k);
1114     printf("         offline, no precomputation   %8.2lf ms \n",tr1);
1115     printf("         offline, w. precomputation   %8.2lf ms \n",tp);
1116     printf("         online                       %8.2lf ms \n",tr1);
1117     printf("%4d bit ECDSA :-\n",k);
1118     printf("         signature no precomputation  %8.2lf ms \n",tr1);
1119     printf("         signature w. precomputation  %8.2lf ms \n",tp);
1120     printf("         verification                 %8.2lf ms \n",td);
1121 
1122 #endif
1123     return 0;
1124 }
1125 
1126