1 #include "crypto_scalarmult.h"
2 
3 #define mult crypto_scalarmult_curve25519_athlon_mult
4 #define square crypto_scalarmult_curve25519_athlon_square
5 
crypto_scalarmult_curve25519_athlon_recip(double out[10],const double z[10])6 void crypto_scalarmult_curve25519_athlon_recip(double out[10],const double z[10])
7 {
8   double z2[10];
9   double z9[10];
10   double z11[10];
11   double z2_5_0[10];
12   double z2_10_0[10];
13   double z2_20_0[10];
14   double z2_50_0[10];
15   double z2_100_0[10];
16   double t0[10];
17   double t1[10];
18   int i;
19 
20   /* 2 */ square(z2,z);
21   /* 4 */ square(t1,z2);
22   /* 8 */ square(t0,t1);
23   /* 9 */ mult(z9,t0,z);
24   /* 11 */ mult(z11,z9,z2);
25   /* 22 */ square(t0,z11);
26   /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9);
27 
28   /* 2^6 - 2^1 */ square(t0,z2_5_0);
29   /* 2^7 - 2^2 */ square(t1,t0);
30   /* 2^8 - 2^3 */ square(t0,t1);
31   /* 2^9 - 2^4 */ square(t1,t0);
32   /* 2^10 - 2^5 */ square(t0,t1);
33   /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0);
34 
35   /* 2^11 - 2^1 */ square(t0,z2_10_0);
36   /* 2^12 - 2^2 */ square(t1,t0);
37   /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); }
38   /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0);
39 
40   /* 2^21 - 2^1 */ square(t0,z2_20_0);
41   /* 2^22 - 2^2 */ square(t1,t0);
42   /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); }
43   /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0);
44 
45   /* 2^41 - 2^1 */ square(t1,t0);
46   /* 2^42 - 2^2 */ square(t0,t1);
47   /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); }
48   /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0);
49 
50   /* 2^51 - 2^1 */ square(t0,z2_50_0);
51   /* 2^52 - 2^2 */ square(t1,t0);
52   /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }
53   /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0);
54 
55   /* 2^101 - 2^1 */ square(t1,z2_100_0);
56   /* 2^102 - 2^2 */ square(t0,t1);
57   /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); }
58   /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0);
59 
60   /* 2^201 - 2^1 */ square(t0,t1);
61   /* 2^202 - 2^2 */ square(t1,t0);
62   /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }
63   /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0);
64 
65   /* 2^251 - 2^1 */ square(t1,t0);
66   /* 2^252 - 2^2 */ square(t0,t1);
67   /* 2^253 - 2^3 */ square(t1,t0);
68   /* 2^254 - 2^4 */ square(t0,t1);
69   /* 2^255 - 2^5 */ square(t1,t0);
70   /* 2^255 - 21 */ mult(out,t1,z11);
71 }
72 
crypto_scalarmult(unsigned char * q,const unsigned char * n,const unsigned char * p)73 int crypto_scalarmult(unsigned char *q,
74   const unsigned char *n,
75   const unsigned char *p)
76 {
77   double work[30];
78   unsigned char e[32];
79   int i;
80   for (i = 0;i < 32;++i) e[i] = n[i];
81   e[0] &= 248;
82   e[31] &= 127;
83   e[31] |= 64;
84   crypto_scalarmult_curve25519_athlon_init();
85   crypto_scalarmult_curve25519_athlon_todouble(work,p);
86   crypto_scalarmult_curve25519_athlon_mainloop(work,e);
87   crypto_scalarmult_curve25519_athlon_recip(work + 10,work + 10);
88   mult(work + 20,work,work + 10);
89   crypto_scalarmult_curve25519_athlon_fromdouble(q,work + 20);
90   return 0;
91 }
92