/** Add entropy to the PRNG state @param in The data to add @param inlen Length of the data to add @param prng PRNG state to update @return CRYPT_OK if successful */ int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) { struct sober128_prng *c; ulong32 i, k; LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); c = &(prng->sober128); if (c->flag == 1) { /* this is the first call to the add_entropy so this input is the key */ /* inlen must be multiple of 4 bytes */ if ((inlen & 3) != 0) { return CRYPT_INVALID_KEYSIZE; } for (i = 0; i < inlen; i += 4) { k = BYTE2WORD((unsigned char *)&in[i]); ADDKEY(k); cycle(c->R); XORNL(nltap(c)); } /* also fold in the length of the key */ ADDKEY(inlen); /* now diffuse */ s128_diffuse(c); s128_genkonst(c); s128_savestate(c); c->nbuf = 0; c->flag = 0; c->set = 1; } else { /* ok we are adding an IV then... */ s128_reloadstate(c); /* inlen must be multiple of 4 bytes */ if ((inlen & 3) != 0) { return CRYPT_INVALID_KEYSIZE; } for (i = 0; i < inlen; i += 4) { k = BYTE2WORD((unsigned char *)&in[i]); ADDKEY(k); cycle(c->R); XORNL(nltap(c)); } /* also fold in the length of the key */ ADDKEY(inlen); /* now diffuse */ s128_diffuse(c); c->nbuf = 0; } return CRYPT_OK; }
/* Published "key" interface */ void s128_key(s128_ctx *c, UCHAR key[], int keylen) { s128_initstate(c); s128_loadkey(c, key, keylen); s128_genkonst(c); s128_savestate(c); }
int sober128_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) { struct sober128_prng *c; ulong32 i, k; c = &(prng->sober128); if (c->flag == 1) { /* this is the first call to the add_entropy so this input is the key */ /* len must be multiple of 4 bytes */ assert ((len & 3) == 0); for (i = 0; i < len; i += 4) { k = BYTE2WORD(&buf[i]); ADDKEY(k); cycle(c->R); XORNL(nltap(c)); } /* also fold in the length of the key */ ADDKEY(len); /* now diffuse */ s128_diffuse(c); s128_genkonst(c); s128_savestate(c); c->nbuf = 0; c->flag = 0; c->set = 1; } else { /* ok we are adding an IV then... */ s128_reloadstate(c); /* len must be multiple of 4 bytes */ assert ((len & 3) == 0); for (i = 0; i < len; i += 4) { k = BYTE2WORD(&buf[i]); ADDKEY(k); cycle(c->R); XORNL(nltap(c)); } /* also fold in the length of the key */ ADDKEY(len); /* now diffuse */ s128_diffuse(c); c->nbuf = 0; } return CRYPT_OK; }
/** Initialize an Sober128 context (only the key) @param c [out] The destination of the Sober128 state @param key The secret key @param keylen The length of the secret key (octets) @return CRYPT_OK if successful */ int sober128_stream_setup(sober128_state *c, const unsigned char *key, unsigned long keylen) { ulong32 i, k; LTC_ARGCHK(c != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(keylen > 0); /* keylen must be multiple of 4 bytes */ if ((keylen & 3) != 0) { return CRYPT_INVALID_KEYSIZE; } /* Register initialised to Fibonacci numbers */ c->R[0] = 1; c->R[1] = 1; for (i = 2; i < N; ++i) { c->R[i] = c->R[i-1] + c->R[i-2]; } c->konst = INITKONST; for (i = 0; i < keylen; i += 4) { k = BYTE2WORD((unsigned char *)&key[i]); ADDKEY(k); cycle(c->R); XORNL(nltap(c)); } /* also fold in the length of the key */ ADDKEY(keylen); /* now diffuse */ s128_diffuse(c); s128_genkonst(c); s128_savestate(c); c->nbuf = 0; return CRYPT_OK; }