unsigned long sober128_read(unsigned char *buf, unsigned long nbytes, sober128_prng *c) { ulong32 t, tlen; tlen = nbytes; /* handle any previously buffered bytes */ while (c->nbuf != 0 && nbytes != 0) { *buf++ ^= c->sbuf & 0xFF; c->sbuf >>= 8; c->nbuf -= 8; --nbytes; } #ifndef SMALL_CODE /* do lots at a time, if there's enough to do */ while (nbytes >= N*4) { SROUND(0); SROUND(1); SROUND(2); SROUND(3); SROUND(4); SROUND(5); SROUND(6); SROUND(7); SROUND(8); SROUND(9); SROUND(10); SROUND(11); SROUND(12); SROUND(13); SROUND(14); SROUND(15); SROUND(16); buf += 4*N; nbytes -= 4*N; } #endif /* do small or odd size buffers the slow way */ while (4 <= nbytes) { cycle(c->R); t = nltap(c); XORWORD(t, buf); buf += 4; nbytes -= 4; } /* handle any trailing bytes */ if (nbytes != 0) { cycle(c->R); c->sbuf = nltap(c); c->nbuf = 32; while (c->nbuf != 0 && nbytes != 0) { *buf++ ^= c->sbuf & 0xFF; c->sbuf >>= 8; c->nbuf -= 8; --nbytes; } }
void s128_stream(s128_ctx *c, UCHAR *buf, int nbytes) { UCHAR *endbuf; WORD t = 0; if ((nbytes & 3) != 0) abort(); endbuf = &buf[nbytes]; /* do small or odd size buffers the slow way, at least at first */ while ((nbytes % (N*4)) != 0) { cycle(c->R); t = nltap(c); XORWORD(t, buf); buf += 4; nbytes -= 4; } /* now do lots at a time, if there's any left */ while (buf < endbuf) { SROUND(0); SROUND(1); SROUND(2); SROUND(3); SROUND(4); SROUND(5); SROUND(6); SROUND(7); SROUND(8); SROUND(9); SROUND(10); SROUND(11); SROUND(12); SROUND(13); SROUND(14); SROUND(15); SROUND(16); buf += 4*17; } }
/** Read from the PRNG @param out Destination @param outlen Length of output @param prng The active PRNG to read from @return Number of octets read */ unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng) { struct sober128_prng *c; ulong32 t, tlen; LTC_ARGCHK(out != NULL); LTC_ARGCHK(prng != NULL); #ifdef LTC_VALGRIND zeromem(out, outlen); #endif c = &(prng->sober128); t = 0; tlen = outlen; /* handle any previously buffered bytes */ while (c->nbuf != 0 && outlen != 0) { *out++ ^= c->sbuf & 0xFF; c->sbuf >>= 8; c->nbuf -= 8; --outlen; } #ifndef LTC_SMALL_CODE /* do lots at a time, if there's enough to do */ while (outlen >= N*4) { SROUND(0); SROUND(1); SROUND(2); SROUND(3); SROUND(4); SROUND(5); SROUND(6); SROUND(7); SROUND(8); SROUND(9); SROUND(10); SROUND(11); SROUND(12); SROUND(13); SROUND(14); SROUND(15); SROUND(16); out += 4*N; outlen -= 4*N; } #endif /* do small or odd size buffers the slow way */ while (4 <= outlen) { cycle(c->R); t = nltap(c); XORWORD(t, out); out += 4; outlen -= 4; } /* handle any trailing bytes */ if (outlen != 0) { cycle(c->R); c->sbuf = nltap(c); c->nbuf = 32; while (c->nbuf != 0 && outlen != 0) { *out++ ^= c->sbuf & 0xFF; c->sbuf >>= 8; c->nbuf -= 8; --outlen; } }
/** Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128 @param c The Sober128 state @param in The plaintext (or ciphertext) @param inlen The length of the input (octets) @param out [out] The ciphertext (or plaintext), length inlen @return CRYPT_OK if successful */ int sober128_stream_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out) { ulong32 t; if (inlen == 0) return CRYPT_OK; /* nothing to do */ LTC_ARGCHK(out != NULL); LTC_ARGCHK(c != NULL); /* handle any previously buffered bytes */ while (c->nbuf != 0 && inlen != 0) { *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF); c->sbuf >>= 8; c->nbuf -= 8; --inlen; } #ifndef LTC_SMALL_CODE /* do lots at a time, if there's enough to do */ while (inlen >= N*4) { SROUND(0); SROUND(1); SROUND(2); SROUND(3); SROUND(4); SROUND(5); SROUND(6); SROUND(7); SROUND(8); SROUND(9); SROUND(10); SROUND(11); SROUND(12); SROUND(13); SROUND(14); SROUND(15); SROUND(16); out += 4*N; in += 4*N; inlen -= 4*N; } #endif /* do small or odd size buffers the slow way */ while (4 <= inlen) { cycle(c->R); t = nltap(c); XORWORD(t, in, out); out += 4; in += 4; inlen -= 4; } /* handle any trailing bytes */ if (inlen != 0) { cycle(c->R); c->sbuf = nltap(c); c->nbuf = 32; while (c->nbuf != 0 && inlen != 0) { *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF); c->sbuf >>= 8; c->nbuf -= 8; --inlen; } }