[BACK]Return to smult_curve25519_ref.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/smult_curve25519_ref.c, Revision 1.2

1.2     ! markus      1: /* $OpenBSD: myproposal.h,v 1.33 2013/11/02 21:59:15 markus Exp $ */
1.1       markus      2: /*
                      3: version 20081011
                      4: Matthew Dempsky
                      5: Public domain.
                      6: Derived from public domain code by D. J. Bernstein.
                      7: */
                      8:
                      9: int crypto_scalarmult_curve25519(unsigned char *, const unsigned char *, const unsigned char *);
                     10:
                     11: static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
                     12: {
                     13:   unsigned int j;
                     14:   unsigned int u;
                     15:   u = 0;
                     16:   for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; }
                     17:   u += a[31] + b[31]; out[31] = u;
                     18: }
                     19:
                     20: static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
                     21: {
                     22:   unsigned int j;
                     23:   unsigned int u;
                     24:   u = 218;
                     25:   for (j = 0;j < 31;++j) {
                     26:     u += a[j] + 65280 - b[j];
                     27:     out[j] = u & 255;
                     28:     u >>= 8;
                     29:   }
                     30:   u += a[31] - b[31];
                     31:   out[31] = u;
                     32: }
                     33:
                     34: static void squeeze(unsigned int a[32])
                     35: {
                     36:   unsigned int j;
                     37:   unsigned int u;
                     38:   u = 0;
                     39:   for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; }
                     40:   u += a[31]; a[31] = u & 127;
                     41:   u = 19 * (u >> 7);
                     42:   for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; }
                     43:   u += a[31]; a[31] = u;
                     44: }
                     45:
                     46: static const unsigned int minusp[32] = {
                     47:  19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128
                     48: } ;
                     49:
                     50: static void freeze(unsigned int a[32])
                     51: {
                     52:   unsigned int aorig[32];
                     53:   unsigned int j;
                     54:   unsigned int negative;
                     55:
                     56:   for (j = 0;j < 32;++j) aorig[j] = a[j];
                     57:   add(a,a,minusp);
                     58:   negative = -((a[31] >> 7) & 1);
                     59:   for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]);
                     60: }
                     61:
                     62: static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32])
                     63: {
                     64:   unsigned int i;
                     65:   unsigned int j;
                     66:   unsigned int u;
                     67:
                     68:   for (i = 0;i < 32;++i) {
                     69:     u = 0;
                     70:     for (j = 0;j <= i;++j) u += a[j] * b[i - j];
                     71:     for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j];
                     72:     out[i] = u;
                     73:   }
                     74:   squeeze(out);
                     75: }
                     76:
                     77: static void mult121665(unsigned int out[32],const unsigned int a[32])
                     78: {
                     79:   unsigned int j;
                     80:   unsigned int u;
                     81:
                     82:   u = 0;
                     83:   for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; }
                     84:   u += 121665 * a[31]; out[31] = u & 127;
                     85:   u = 19 * (u >> 7);
                     86:   for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; }
                     87:   u += out[j]; out[j] = u;
                     88: }
                     89:
                     90: static void square(unsigned int out[32],const unsigned int a[32])
                     91: {
                     92:   unsigned int i;
                     93:   unsigned int j;
                     94:   unsigned int u;
                     95:
                     96:   for (i = 0;i < 32;++i) {
                     97:     u = 0;
                     98:     for (j = 0;j < i - j;++j) u += a[j] * a[i - j];
                     99:     for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j];
                    100:     u *= 2;
                    101:     if ((i & 1) == 0) {
                    102:       u += a[i / 2] * a[i / 2];
                    103:       u += 38 * a[i / 2 + 16] * a[i / 2 + 16];
                    104:     }
                    105:     out[i] = u;
                    106:   }
                    107:   squeeze(out);
                    108: }
                    109:
                    110: static void select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b)
                    111: {
                    112:   unsigned int j;
                    113:   unsigned int t;
                    114:   unsigned int bminus1;
                    115:
                    116:   bminus1 = b - 1;
                    117:   for (j = 0;j < 64;++j) {
                    118:     t = bminus1 & (r[j] ^ s[j]);
                    119:     p[j] = s[j] ^ t;
                    120:     q[j] = r[j] ^ t;
                    121:   }
                    122: }
                    123:
                    124: static void mainloop(unsigned int work[64],const unsigned char e[32])
                    125: {
                    126:   unsigned int xzm1[64];
                    127:   unsigned int xzm[64];
                    128:   unsigned int xzmb[64];
                    129:   unsigned int xzm1b[64];
                    130:   unsigned int xznb[64];
                    131:   unsigned int xzn1b[64];
                    132:   unsigned int a0[64];
                    133:   unsigned int a1[64];
                    134:   unsigned int b0[64];
                    135:   unsigned int b1[64];
                    136:   unsigned int c1[64];
                    137:   unsigned int r[32];
                    138:   unsigned int s[32];
                    139:   unsigned int t[32];
                    140:   unsigned int u[32];
                    141:   unsigned int j;
                    142:   unsigned int b;
                    143:   int pos;
                    144:
                    145:   for (j = 0;j < 32;++j) xzm1[j] = work[j];
                    146:   xzm1[32] = 1;
                    147:   for (j = 33;j < 64;++j) xzm1[j] = 0;
                    148:
                    149:   xzm[0] = 1;
                    150:   for (j = 1;j < 64;++j) xzm[j] = 0;
                    151:
                    152:   for (pos = 254;pos >= 0;--pos) {
                    153:     b = e[pos / 8] >> (pos & 7);
                    154:     b &= 1;
                    155:     select(xzmb,xzm1b,xzm,xzm1,b);
                    156:     add(a0,xzmb,xzmb + 32);
                    157:     sub(a0 + 32,xzmb,xzmb + 32);
                    158:     add(a1,xzm1b,xzm1b + 32);
                    159:     sub(a1 + 32,xzm1b,xzm1b + 32);
                    160:     square(b0,a0);
                    161:     square(b0 + 32,a0 + 32);
                    162:     mult(b1,a1,a0 + 32);
                    163:     mult(b1 + 32,a1 + 32,a0);
                    164:     add(c1,b1,b1 + 32);
                    165:     sub(c1 + 32,b1,b1 + 32);
                    166:     square(r,c1 + 32);
                    167:     sub(s,b0,b0 + 32);
                    168:     mult121665(t,s);
                    169:     add(u,t,b0);
                    170:     mult(xznb,b0,b0 + 32);
                    171:     mult(xznb + 32,s,u);
                    172:     square(xzn1b,c1);
                    173:     mult(xzn1b + 32,r,work);
                    174:     select(xzm,xzm1,xznb,xzn1b,b);
                    175:   }
                    176:
                    177:   for (j = 0;j < 64;++j) work[j] = xzm[j];
                    178: }
                    179:
                    180: static void recip(unsigned int out[32],const unsigned int z[32])
                    181: {
                    182:   unsigned int z2[32];
                    183:   unsigned int z9[32];
                    184:   unsigned int z11[32];
                    185:   unsigned int z2_5_0[32];
                    186:   unsigned int z2_10_0[32];
                    187:   unsigned int z2_20_0[32];
                    188:   unsigned int z2_50_0[32];
                    189:   unsigned int z2_100_0[32];
                    190:   unsigned int t0[32];
                    191:   unsigned int t1[32];
                    192:   int i;
                    193:
                    194:   /* 2 */ square(z2,z);
                    195:   /* 4 */ square(t1,z2);
                    196:   /* 8 */ square(t0,t1);
                    197:   /* 9 */ mult(z9,t0,z);
                    198:   /* 11 */ mult(z11,z9,z2);
                    199:   /* 22 */ square(t0,z11);
                    200:   /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9);
                    201:
                    202:   /* 2^6 - 2^1 */ square(t0,z2_5_0);
                    203:   /* 2^7 - 2^2 */ square(t1,t0);
                    204:   /* 2^8 - 2^3 */ square(t0,t1);
                    205:   /* 2^9 - 2^4 */ square(t1,t0);
                    206:   /* 2^10 - 2^5 */ square(t0,t1);
                    207:   /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0);
                    208:
                    209:   /* 2^11 - 2^1 */ square(t0,z2_10_0);
                    210:   /* 2^12 - 2^2 */ square(t1,t0);
                    211:   /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); }
                    212:   /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0);
                    213:
                    214:   /* 2^21 - 2^1 */ square(t0,z2_20_0);
                    215:   /* 2^22 - 2^2 */ square(t1,t0);
                    216:   /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); }
                    217:   /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0);
                    218:
                    219:   /* 2^41 - 2^1 */ square(t1,t0);
                    220:   /* 2^42 - 2^2 */ square(t0,t1);
                    221:   /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); }
                    222:   /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0);
                    223:
                    224:   /* 2^51 - 2^1 */ square(t0,z2_50_0);
                    225:   /* 2^52 - 2^2 */ square(t1,t0);
                    226:   /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }
                    227:   /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0);
                    228:
                    229:   /* 2^101 - 2^1 */ square(t1,z2_100_0);
                    230:   /* 2^102 - 2^2 */ square(t0,t1);
                    231:   /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); }
                    232:   /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0);
                    233:
                    234:   /* 2^201 - 2^1 */ square(t0,t1);
                    235:   /* 2^202 - 2^2 */ square(t1,t0);
                    236:   /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); }
                    237:   /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0);
                    238:
                    239:   /* 2^251 - 2^1 */ square(t1,t0);
                    240:   /* 2^252 - 2^2 */ square(t0,t1);
                    241:   /* 2^253 - 2^3 */ square(t1,t0);
                    242:   /* 2^254 - 2^4 */ square(t0,t1);
                    243:   /* 2^255 - 2^5 */ square(t1,t0);
                    244:   /* 2^255 - 21 */ mult(out,t1,z11);
                    245: }
                    246:
                    247: int crypto_scalarmult_curve25519(unsigned char *q,
                    248:   const unsigned char *n,
                    249:   const unsigned char *p)
                    250: {
                    251:   unsigned int work[96];
                    252:   unsigned char e[32];
                    253:   unsigned int i;
                    254:   for (i = 0;i < 32;++i) e[i] = n[i];
                    255:   e[0] &= 248;
                    256:   e[31] &= 127;
                    257:   e[31] |= 64;
                    258:   for (i = 0;i < 32;++i) work[i] = p[i];
                    259:   mainloop(work,e);
                    260:   recip(work + 32,work + 32);
                    261:   mult(work + 64,work,work + 32);
                    262:   freeze(work + 64);
                    263:   for (i = 0;i < 32;++i) q[i] = work[64 + i];
                    264:   return 0;
                    265: }