tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

ge_double_scalarmult.c (2371B)


      1 #include "ge.h"
      2 
      3 static void slide(signed char *r,const unsigned char *a)
      4 {
      5  int i;
      6  int b;
      7  int k;
      8 
      9  for (i = 0;i < 256;++i)
     10    r[i] = 1 & (a[i >> 3] >> (i & 7));
     11 
     12  for (i = 0;i < 256;++i)
     13    if (r[i]) {
     14      for (b = 1;b <= 6 && i + b < 256;++b) {
     15        if (r[i + b]) {
     16          if (r[i] + (r[i + b] << b) <= 15) {
     17            r[i] += r[i + b] << b; r[i + b] = 0;
     18          } else if (r[i] - (r[i + b] << b) >= -15) {
     19            r[i] -= r[i + b] << b;
     20            for (k = i + b;k < 256;++k) {
     21              if (!r[k]) {
     22                r[k] = 1;
     23                break;
     24              }
     25              r[k] = 0;
     26            }
     27          } else
     28            break;
     29        }
     30      }
     31    }
     32 
     33 }
     34 
     35 static ge_precomp Bi[8] = {
     36 #include "base2.h"
     37 } ;
     38 
     39 /*
     40 r = a * A + b * B
     41 where a = a[0]+256*a[1]+...+256^31 a[31].
     42 and b = b[0]+256*b[1]+...+256^31 b[31].
     43 B is the Ed25519 base point (x,4/5) with x positive.
     44 */
     45 
     46 void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b)
     47 {
     48  signed char aslide[256];
     49  signed char bslide[256];
     50  ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
     51  ge_p1p1 t;
     52  ge_p3 u;
     53  ge_p3 A2;
     54  int i;
     55 
     56  slide(aslide,a);
     57  slide(bslide,b);
     58 
     59  ge_p3_to_cached(&Ai[0],A);
     60  ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);
     61  ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);
     62  ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);
     63  ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);
     64  ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);
     65  ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);
     66  ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);
     67  ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);
     68 
     69  ge_p2_0(r);
     70 
     71  for (i = 255;i >= 0;--i) {
     72    if (aslide[i] || bslide[i]) break;
     73  }
     74 
     75  for (;i >= 0;--i) {
     76    ge_p2_dbl(&t,r);
     77 
     78    if (aslide[i] > 0) {
     79      ge_p1p1_to_p3(&u,&t);
     80      ge_add(&t,&u,&Ai[aslide[i]/2]);
     81    } else if (aslide[i] < 0) {
     82      ge_p1p1_to_p3(&u,&t);
     83      ge_sub(&t,&u,&Ai[(-aslide[i])/2]);
     84    }
     85 
     86    if (bslide[i] > 0) {
     87      ge_p1p1_to_p3(&u,&t);
     88      ge_madd(&t,&u,&Bi[bslide[i]/2]);
     89    } else if (bslide[i] < 0) {
     90      ge_p1p1_to_p3(&u,&t);
     91      ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
     92    }
     93 
     94    ge_p1p1_to_p2(r,&t);
     95  }
     96 }