Skip to content

Commit

Permalink
Fix state update, modify key_init() args to u32*
Browse files Browse the repository at this point in the history
  • Loading branch information
vibhav950 committed Dec 21, 2024
1 parent 1f85090 commit 82e1c3e
Showing 1 changed file with 45 additions and 31 deletions.
76 changes: 45 additions & 31 deletions src/rand/trivium.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/

#include "trivium.h"
#include "common/endianness.h"
#include "rngw32.h"

/* 288-bit internal state */
Expand All @@ -36,60 +37,73 @@ static u8 z;
/* Global counter to handle periodic reseeding */
static s32 ctr = -1;

#if defined(__LITTLE_ENDIAN__)
#define BE_U32(_x) bswap32(_x)
#else
#define BE_U32(_x) (_x)
#endif

/*
* The constant key is the first 80 bits from the
* first 7 decimal digits of the square roots of
* the first 4 primes.
*/
static const u8 trivium_k[TRIVIUM_KEY_SIZE] = {0xfc, 0xd0, 0xdf, 0x7d, 0x9d,
0xe4, 0x80, 0xac, 0xf8, 0xa2};
static const u8 trivium_k[TRIVIUM_KEY_SIZE + 2] = {
0xfc, 0xd0, 0xdf, 0x7d, 0x9d, 0xe4, 0x80, 0xac, 0xf8, 0xa2, 0x00, 0x00
};

/*
* Update and rotate the internal state and generate
* one output bit per iteration.
* Update and rotate the internal state and generate one bit of keystream.
*/
#define TRIVIUM_UPDATE_ROTATE \
{ \
t1 = ((x3 >> 1) ^ (x3 >> 28)) & 0x1; \
t2 = ((x6 >> 1) ^ (x6 >> 16)) & 0x1; \
t3 = ((x8 >> 18) ^ (x9 >> 31)) & 0x1; \
z = t1 ^ t2 ^ t3; \
t1 = ((x3 >> 1) ^ (x3 >> 28)) & 0x1; /* t1 <- s66 + s93 */ \
t2 = ((x6 >> 1) ^ (x6 >> 16)) & 0x1; /* t2 <- s162 + s177 */ \
t3 = ((x8 >> 18) ^ (x9 >> 31)) & 0x1; /* t3 <- s243 + s288 */ \
z = t1 ^ t2 ^ t3; /* z <- t1 + t2 + t3 */ \
/* t1 <- t1 + s91.s92 + s171 */ \
t1 = (t1 ^ ((x3 >> 26) & (x3 >> 27)) ^ (x6 >> 10)) & 0x1; \
/* t2 <- t2 + s175.s176 + s264 */ \
t2 = (t2 ^ ((x6 >> 14) & (x6 >> 15)) ^ (x9 >> 7)) & 0x1; \
/* t3 <- t3 + s286.s287 + s69 */ \
t3 = (t3 ^ ((x9 >> 29) & (x9 >> 30)) ^ (x3 >> 4)) & 0x1; \
/* (s178, s179, ..., s288) <- (t2, s178, ..., s287) */ \
x9 = (x9 << 1) | (x8 >> 31); \
x8 = (x8 << 1) | (x7 >> 31); \
x7 = (x7 << 1) | (x6 >> 31); \
x6 = ((x6 << 1) & (((u32)t2 << 17) | 0xfffdffff)) | (x5 >> 31); \
/* (s94, s95, ..., s177) <- (t1, s94, ..., s176) */ \
x6 = ((x6 << 1) & 0xfffdffff) | ((u32)t2 << 17) | (x5 >> 31); \
x5 = (x5 << 1) | (x4 >> 31); \
x4 = (x4 << 1) | (x3 >> 31); \
x3 = ((x3 << 1) & (((u32)t1 << 29) | 0xdfffffff)) | (x2 >> 31); \
/* (s1, s2, ..., s93) <- (t3, s1, ..., s92) */ \
x3 = ((x3 << 1) & 0xdfffffff) | ((u32)t1 << 29) | (x2 >> 31); \
x2 = (x2 << 1) | (x1 >> 31); \
x1 = (x1 << 1) | t3; \
}

/*
* Initialize the internal state by inserting the key
* and IV (both 8-bit unsigned int arrays of size 10),
* and rotate the internal state over 4 full cycles
* without generating any key-stream bits.
* Initialize the internal state by inserting the key and IV and rotate the
* internal state over 4 full cycles (4 * 288 update rounds) without generating
* any key-stream bits.
*
* (s1, s2, ..., s93) <- (K3, ..., K80, 0, ..., 0)
* (s94, s95, ..., s177) <- (IV1, ..., IV80, 0, ..., 0)
* (s178, s179, ..., s288) <- (0, ..., 0, 1, 1, 1)
*/
static void trivium_init(const u8 *k, const u8 *iv) {
/* Insert 80-bit key */
x1 = ((u32)k[3] << 24) | ((u32)k[2] << 16) | ((u32)k[1] << 8) | k[0];
x2 = ((u32)k[7] << 24) | ((u32)k[6] << 16) | ((u32)k[5] << 8) | k[4];
x3 = (u32)0 | (((u32)iv[0] & 0x7) << 29) | ((u32)k[9] << 8) | k[8];
x4 = (((u32)iv[4] & 0x7) << 29) | ((u32)iv[3] << 21) | ((u32)iv[2] << 13) |
((u32)iv[1] << 5) | ((iv[0] & 0xf8) >> 3);
x5 = (((u32)iv[8] & 0x7) << 29) | ((u32)iv[7] << 21) | ((u32)iv[6] << 13) |
((u32)iv[5] << 5) | ((iv[4] & 0xf8) >> 3);
x6 = (u32)0 | (iv[8] & 0xf8) >> 3;
static void trivium_init(u32 *k, u32 *iv) {
x1 = (k[0] >> 2) | ((k[1] & 0x3) << 30);
x2 = (k[1] >> 2) | ((k[2] & 0x3) << 30);
x3 = (u32)0 | (k[2] & 0x3fff) | ((iv[0] & 0x7) << 29);
x4 = (iv[0] >> 3) | ((iv[1] & 0x7) << 29);
x5 = (iv[1] >> 3) | ((iv[2] & 0x7) << 29);
x6 = (u32)0 | ((iv[2] >> 3) & 0x1fff);
x7 = x8 = 0;
x9 = (u32)0xe0000000;
x9 = 0xe0000000; /* 0....111 */

/* Blank rounds */
for (int i = 0; i < 4 * 288; ++i)
/* Run blank rounds */
for (int i = 0; i < 4 * 288; ++i) {
TRIVIUM_UPDATE_ROTATE
}
}

/*
Expand All @@ -102,16 +116,16 @@ static void trivium_set_seed(void) {
* the IV. This IV combined with the constant
* key `trivium_k` forms the new seed.
*/
u8 iv[TRIVIUM_IV_SIZE];
u8 iv[TRIVIUM_IV_SIZE + 2];

/* TODO although any failures in the RNG should
be caught under the hood, this function CAN
still return FAILURE; handle this somehow. */
(void)RngFetchBytes(iv, TRIVIUM_IV_SIZE);

ctr = 0;
trivium_init(trivium_k, iv);
zeroize(iv, TRIVIUM_IV_SIZE);
trivium_init(Ptr32(&trivium_k[0]), Ptr32(&iv[0]));
zeroize(iv, sizeof(iv));
}

/* Return 8 bits of random keystream. */
Expand Down Expand Up @@ -210,4 +224,4 @@ void TriviumCsprngReset() {

/* Reset the reseed counter */
ctr = -1;
}
}

0 comments on commit 82e1c3e

Please sign in to comment.