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 }