skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

surf.c (1366B)


      1 /* ISC license. */
      2 
      3 #include <string.h>
      4 #include <stdint.h>
      5 
      6 #include <skalibs/uint32.h>
      7 #include <skalibs/surf.h>
      8 
      9 #define ROTATE(x, b) (((x) << (b)) | ((x) >> (32 - (b))))
     10 #define MUSH(i, b) x = t[i] += (((x ^ ctx->seed[i]) + sum) ^ ROTATE(x, b))
     11 
     12 static void surfit (SURFSchedule *ctx)
     13 {
     14   uint32_t t[12] ;
     15   uint32_t z[8] ;
     16   uint32_t x ;
     17   uint32_t sum = 0 ;
     18   uint32_t i = 0, loop = 0 ; ;
     19 
     20   if (!++ctx->in[0] && !++ctx->in[1] && !++ctx->in[2]) ++ctx->in[3] ;
     21   for (; i < 12 ; i++) t[i] = ctx->in[i] ^ ctx->seed[12+i] ;
     22   for (i = 0 ; i < 8 ; i++) z[i] = ctx->seed[24+i] ;
     23   x = t[11] ;
     24   for (; loop < 2 ; loop++)
     25   {
     26     for (i = 0 ; i < 16 ; i++)
     27     {
     28       sum += 0x9e3779b9 ;
     29       MUSH(0, 5) ; MUSH(1, 7) ; MUSH(2, 9) ;  MUSH(3, 13) ;
     30       MUSH(4, 5) ; MUSH(5, 7) ; MUSH(6, 9) ;  MUSH(7, 13) ;
     31       MUSH(8, 5) ; MUSH(9, 7) ; MUSH(10, 9) ; MUSH(11, 13) ;
     32     }
     33     for (i = 0 ; i < 8 ; i++) z[i] ^= t[i+4] ;
     34   }
     35   for (i = 0 ; i < 8 ; i++) uint32_pack(ctx->out + (i<<2), z[i]) ;
     36 }
     37 
     38 void surf (SURFSchedule *ctx, char *s, size_t n)
     39 {
     40   {
     41     size_t i = 32 - ctx->pos ;
     42     if (n < i) i = n ;
     43     memcpy(s, ctx->out + ctx->pos, i) ;
     44     s += i ; n -= i ; ctx->pos += i ;
     45   }
     46   while (n > 32)
     47   {
     48     surfit(ctx) ;
     49     memcpy(s, ctx->out, 32) ;
     50     s += 32 ; n -= 32 ;
     51   }
     52   if (!n) return ;
     53   surfit(ctx) ;
     54   memcpy(s, ctx->out, n) ;
     55   ctx->pos = n ;
     56 }