progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / symm / seal.c
index da9d084..070550d 100644 (file)
@@ -62,35 +62,37 @@ static void sealgamma(uint32 *p, size_t sz, const void *k, unsigned i)
 {
   uint32 buf[80] = { 0 };
   const octet *kk = k;
-  uint32 aa = LOAD32(kk);
-  uint32 bb = LOAD32(kk + 4);
-  uint32 cc = LOAD32(kk + 8);
-  uint32 dd = LOAD32(kk + 12);
-  uint32 ee = LOAD32(kk + 16);
+  uint32 a, aa = LOAD32(kk);
+  uint32 b, bb = LOAD32(kk + 4);
+  uint32 c, cc = LOAD32(kk + 8);
+  uint32 d, dd = LOAD32(kk + 12);
+  uint32 e, ee = LOAD32(kk + 16);
+
+  unsigned skip = i%5;
+  uint32 x;
+  int j;
 
-  unsigned skip = i % 5;
   i /= 5;
 
   /* --- While there's hashing to do, do hashing --- */
 
   while (sz) {
-    uint32 a = aa, b = bb, c = cc, d = dd, e = ee;
-    int j;
+    a = aa, b = bb, c = cc, d = dd, e = ee;
 
     /* --- Initialize and expand the buffer --- */
 
     buf[0] = i++;
 
     for (j = 16; j < 80; j++) {
-      uint32 x = buf[j - 3] ^ buf[j - 8] ^ buf[j - 14] ^ buf[j - 16];
+      x = buf[j - 3] ^ buf[j - 8] ^ buf[j - 14] ^ buf[j - 16];
       buf[j] = ROL32(x, 1);
     }
 
     /* --- Definitions for round functions --- */
 
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define F(x, y, z) (((x)&(y)) | (~(x)&(z)))
 #define G(x, y, z) ((x) ^ (y) ^ (z))
-#define H(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) (((x)&(y)) | ((x)&(z)) | ((y)&(z)))
 
 #define T(v, w, x, y, z, i, f, k) do {                                 \
   uint32 _x;                                                           \
@@ -109,14 +111,10 @@ static void sealgamma(uint32 *p, size_t sz, const void *k, unsigned i)
      * Since this isn't doing bulk hashing, do it the easy way.
      */
 
-    for (j = 0; j < 20; j++)
-      FF(a, b, c, d, e, j);
-    for (j = 20; j < 40; j++)
-      GG(a, b, c, d, e, j);
-    for (j = 40; j < 60; j++)
-      HH(a, b, c, d, e, j);
-    for (j = 60; j < 80; j++)
-      II(a, b, c, d, e, j);
+    for (j =  0; j < 20; j++) FF(a, b, c, d, e, j);
+    for (j = 20; j < 40; j++) GG(a, b, c, d, e, j);
+    for (j = 40; j < 60; j++) HH(a, b, c, d, e, j);
+    for (j = 60; j < 80; j++) II(a, b, c, d, e, j);
 
     /* --- Do the chaining at the end --- */
 
@@ -125,17 +123,12 @@ static void sealgamma(uint32 *p, size_t sz, const void *k, unsigned i)
     /* --- Write to the output buffer --- */
 
     switch (skip) {
-      case 0:
-       if (sz) { *p++ = a; sz--; }
-      case 1:
-       if (sz) { *p++ = b; sz--; }
-      case 2:
-       if (sz) { *p++ = c; sz--; }
-      case 3:
-       if (sz) { *p++ = d; sz--; }
-      case 4:
-       if (sz) { *p++ = e; sz--; }
-       skip = 0;
+      case 0: if (sz) { *p++ = a; sz--; }
+      case 1: if (sz) { *p++ = b; sz--; }
+      case 2: if (sz) { *p++ = c; sz--; }
+      case 3: if (sz) { *p++ = d; sz--; }
+      case 4: if (sz) { *p++ = e; sz--; }
+      skip = 0;
     }
   }
 }
@@ -155,16 +148,12 @@ static void sealgamma(uint32 *p, size_t sz, const void *k, unsigned i)
 
 void seal_initkey(seal_key *k, const void *buf, size_t sz)
 {
+  sha_ctx h;
+
   /* --- Hash the key if it's the wrong size --- */
 
-  if (sz == SHA_HASHSZ)
-    memcpy(k->k, buf, sizeof(k->k));
-  else {
-    sha_ctx c;
-    sha_init(&c);
-    sha_hash(&c, buf, sz);
-    sha_done(&c, k->k);
-  }
+  if (sz == SHA_HASHSZ) memcpy(k->k, buf, sizeof(k->k));
+  else { sha_init(&h); sha_hash(&h, buf, sz); sha_done(&h, k->k); }
 
   /* --- Expand the key to fit the various tables --- */
 
@@ -208,14 +197,14 @@ static void seal_reset(seal_ctx *c)
 
   /* --- Ensure that everything is sufficiently diffused --- */
 
-  p = A & 0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9);
-  p = B & 0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9);
-  p = C & 0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9);
-  p = D & 0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9);
-  p = A & 0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9);
-  p = B & 0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9);
-  p = C & 0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9);
-  p = D & 0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9);
+  p = A&0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9);
+  p = B&0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9);
+  p = C&0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9);
+  p = D&0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9);
+  p = A&0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9);
+  p = B&0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9);
+  p = C&0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9);
+  p = D&0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9);
 
   /* --- Write out some context --- */
 
@@ -223,10 +212,10 @@ static void seal_reset(seal_ctx *c)
 
   /* --- Diffuse some more --- */
 
-  p = A & 0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9);
-  p = B & 0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9);
-  p = C & 0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9);
-  p = D & 0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9);
+  p = A&0x7fc; B += k->t[p >> 2]; A = ROR32(A, 9);
+  p = B&0x7fc; C += k->t[p >> 2]; B = ROR32(B, 9);
+  p = C&0x7fc; D += k->t[p >> 2]; C = ROR32(C, 9);
+  p = D&0x7fc; A += k->t[p >> 2]; D = ROR32(D, 9);
 
   /* --- Write out the magic numbers --- */
 
@@ -253,7 +242,7 @@ void seal_initctx(seal_ctx *c, seal_key *k, uint32 n)
   c->l = 0;
   c->r = k->r;
   c->ri = 0x2000 + SEAL_R;
-  c->qsz = 0;
+  c->off = 16;
   seal_reset(c);
 }
 
@@ -274,34 +263,32 @@ void seal_initctx(seal_ctx *c, seal_key *k, uint32 n)
 
 void seal_encrypt(seal_ctx *c, const void *src, void *dest, size_t sz)
 {
+  seal_key *k = c->k;
   const octet *s = src;
-  octet *d = dest;
+  octet *d = dest, *p;
+  uint32 A = c->a, B = c->b, C = c->c, D = c->d;
+  uint32 n1 = c->n1, n2 = c->n2, n3 = c->n3, n4 = c->n4;
+  uint32 aa, bb, cc, dd;
+  unsigned i, j;
+  unsigned P, Q;
 
   /* --- Expect a big dollop of bytes --- */
 
-  if (sz > c->qsz) {
-    seal_key *k = c->k;
-    uint32 A = c->a, B = c->b, C = c->c, D = c->d;
-    uint32 n1 = c->n1, n2 = c->n2, n3 = c->n3, n4 = c->n4;
-    uint32 aa, bb, cc, dd;
-    unsigned j = c->i;
-
-    /* --- Empty the queue first --- */
-
-    if (c->qsz) {
-      if (d) {
-       unsigned i;
-       octet *p = c->q + sizeof(c->q) - c->qsz;
-       for (i = 0; i < c->qsz; i++)
-         *d++ = (s ? *s++ ^ *p++ : *p++);
-      }
-      sz -= c->qsz;
+  if (sz > 16 - c->off) {
+    j = c->i;
+
+    /* --- Drain the buffer first --- */
+
+    if (c->off < 16) {
+      p = c->buf + c->off; sz -= 16 - c->off;
+      if (!d) /* nothing to do* */;
+      else if (!s) memcpy(d, p, 16 - c->off);
+      else for (i = c->off; i < 16; i++) *d++ = *s++ ^ *p++;
     }
 
     /* --- Main sequence --- */
 
     for (;;) {
-      unsigned P, Q;
 
       /* --- Reset if we've run out of steam on this iteration --- */
 
@@ -314,74 +301,63 @@ void seal_encrypt(seal_ctx *c, const void *src, void *dest, size_t sz)
 
       /* --- Make some new numbers --- */
 
-      P = A & 0x7fc; B += k->t[P >> 2]; A = ROR32(A, 9); B ^= A;
-      Q = B & 0x7fc; C ^= k->t[Q >> 2]; B = ROR32(B, 9); C += B;
-      P = (P + C) & 0x7fc; D += k->t[P >> 2]; C = ROR32(C, 9); D ^= C;
-      Q = (Q + D) & 0x7fc; A ^= k->t[Q >> 2]; D = ROR32(D, 9); A += D;
-      P = (P + A) & 0x7fc; B ^= k->t[P >> 2]; A = ROR32(A, 9);
-      Q = (Q + B) & 0x7fc; C += k->t[Q >> 2]; B = ROR32(B, 9);
-      P = (P + C) & 0x7fc; D ^= k->t[P >> 2]; C = ROR32(C, 9);
-      Q = (Q + D) & 0x7fc; A += k->t[Q >> 2]; D = ROR32(D, 9);
+      P =       A&0x7fc; B += k->t[P >> 2]; A = ROR32(A, 9); B ^= A;
+      Q =       B&0x7fc; C ^= k->t[Q >> 2]; B = ROR32(B, 9); C += B;
+      P = (P + C)&0x7fc; D += k->t[P >> 2]; C = ROR32(C, 9); D ^= C;
+      Q = (Q + D)&0x7fc; A ^= k->t[Q >> 2]; D = ROR32(D, 9); A += D;
+      P = (P + A)&0x7fc; B ^= k->t[P >> 2]; A = ROR32(A, 9);
+      Q = (Q + B)&0x7fc; C += k->t[Q >> 2]; B = ROR32(B, 9);
+      P = (P + C)&0x7fc; D ^= k->t[P >> 2]; C = ROR32(C, 9);
+      Q = (Q + D)&0x7fc; A += k->t[Q >> 2]; D = ROR32(D, 9);
 
       /* --- Remember the output and set up the next round --- */
 
-      aa = B + k->s[j + 0];
-      bb = C ^ k->s[j + 1];
-      cc = D + k->s[j + 2];
-      dd = A ^ k->s[j + 3];
+      aa = B + k->s[j + 0]; bb = C ^ k->s[j + 1];
+      cc = D + k->s[j + 2]; dd = A ^ k->s[j + 3];
       j += 4;
 
-      if (j & 4)
-       A += n1, B += n2, C ^= n1, D ^= n2;
-      else
-       A += n3, B += n4, C ^= n3, D ^= n4;
+      if (j&4) { A += n1; B += n2; C ^= n1; D ^= n2; }
+      else     { A += n3; B += n4; C ^= n3; D ^= n4; }
 
       /* --- Bail out here if we need to do buffering --- */
 
-      if (sz < 16)
-       break;
+      if (sz < 16) break;
 
       /* --- Write the next 16 bytes --- */
 
-      if (d) {
+      if (!d) /* nothing to do */;
+      else {
        if (s) {
-         aa ^= LOAD32_L(s + 0);
-         bb ^= LOAD32_L(s + 4);
-         cc ^= LOAD32_L(s + 8);
-         dd ^= LOAD32_L(s + 12);
+         aa ^= LOAD32_L(s +  0); bb ^= LOAD32_L(s +  4);
+         cc ^= LOAD32_L(s +  8); dd ^= LOAD32_L(s + 12);
          s += 16;
        }
-       STORE32_L(d + 0, aa);
-       STORE32_L(d + 4, bb);
-       STORE32_L(d + 8, cc);
-       STORE32_L(d + 12, dd);
+       STORE32_L(d +  0, aa); STORE32_L(d +  4, bb);
+       STORE32_L(d +  8, cc); STORE32_L(d + 12, dd);
        d += 16;
       }
       sz -= 16;
     }
 
-    /* --- Write the new queue --- */
+    /* --- Write the new buffer --- */
 
-    STORE32_L(c->q + 0, aa);
-    STORE32_L(c->q + 4, bb);
-    STORE32_L(c->q + 8, cc);
-    STORE32_L(c->q + 12, dd);
-    c->qsz = 16;
+    STORE32_L(c->buf +  0, aa);
+    STORE32_L(c->buf +  4, bb);
+    STORE32_L(c->buf +  8, cc);
+    STORE32_L(c->buf + 12, dd);
+    c->off = 0;
 
     c->a = A; c->b = B; c->c = C; c->d = D;
     c->i = j;
   }
 
-  /* --- Deal with the rest from the queue --- */
+  /* --- Deal with the rest from the buffer --- */
 
   if (sz) {
-    unsigned i;
-    octet *p = c->q + sizeof(c->q) - c->qsz;
-    if (d) {
-      for (i = 0; i < sz; i++)
-       *d++ = (s ? *s++ ^ *p++ : *p++);
-    }
-    c->qsz -= sz;
+    p = c->buf + c->off; c->off += sz;
+    if (!d) /* nothing to do* */;
+    else if (!s) memcpy(d, p, sz);
+    else for (i = 0; i < sz; i++) *d++ = *s++ ^ *p++;
   }
 }
 
@@ -405,24 +381,17 @@ static gcipher *ginit(const void *k, size_t sz)
 }
 
 static void gencrypt(gcipher *c, const void *s, void *t, size_t sz)
-{
-  gctx *g = (gctx *)c;
-  seal_encrypt(&g->cc, s, t, sz);
-}
+  { gctx *g = (gctx *)c; seal_encrypt(&g->cc, s, t, sz); }
 
 static void gsetiv(gcipher *c, const void *iv)
 {
   gctx *g = (gctx *)c;
-  uint32 n = *(const uint32 *)iv;
-  seal_initctx(&g->cc, &g->k, n);
+  const octet *ivp = iv;
+  seal_initctx(&g->cc, &g->k, LOAD32(ivp));
 }
 
 static void gdestroy(gcipher *c)
-{
-  gctx *g = (gctx *)c;
-  BURN(*g);
-  S_DESTROY(g);
-}
+  { gctx *g = (gctx *)c; BURN(*g); S_DESTROY(g); }
 
 static const gcipher_ops gops = {
   &seal,
@@ -430,7 +399,7 @@ static const gcipher_ops gops = {
 };
 
 const gccipher seal = {
-  "seal", seal_keysz, 0,
+  "seal", seal_keysz, 4,
   ginit
 };
 
@@ -443,11 +412,7 @@ typedef struct grctx {
 } grctx;
 
 static void grdestroy(grand *r)
-{
-  grctx *g = (grctx *)r;
-  BURN(*g);
-  S_DESTROY(g);
-}
+  { grctx *g = (grctx *)r; BURN(*g); S_DESTROY(g); }
 
 static int grmisc(grand *r, unsigned op, ...)
 {
@@ -520,16 +485,13 @@ static uint32 grword(grand *r)
 }
 
 static void grfill(grand *r, void *p, size_t sz)
-{
-  grctx *g = (grctx *)r;
-  seal_encrypt(&g->cc, 0, p, sz);
-}
+  { grctx *g = (grctx *)r; seal_encrypt(&g->cc, 0, p, sz); }
 
 static const grand_ops grops = {
   "seal",
   GRAND_CRYPTO, 0,
   grmisc, grdestroy,
-  grword, grbyte, grword, grand_range, grfill
+  grword, grbyte, grword, grand_defaultrange, grfill
 };
 
 /* --- @seal_rand@ --- *
@@ -559,6 +521,7 @@ grand *seal_rand(const void *k, size_t sz, uint32 n)
 
 #include <string.h>
 
+#include <mLib/macros.h>
 #include <mLib/testrig.h>
 
 static int verify(dstr *v)
@@ -581,7 +544,7 @@ static int verify(dstr *v)
     seal_initctx(&c, &k, n);
     seal_encrypt(&c, 0, d.buf, i);
     seal_encrypt(&c, z.buf, d.buf + i, d.len - i);
-    if (memcmp(d.buf, v[2].buf, d.len) != 0) {
+    if (MEMCMP(d.buf, !=, v[2].buf, d.len)) {
       ok = 0;
       printf("*** seal failure\n");
       printf("*** k = "); type_hex.dump(&v[0], stdout); putchar('\n');