Add C++ implementation of Trivium.
This commit is contained in:
parent
a6721cae33
commit
c6c3ef396a
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
|
||||
.PHONY: all
|
||||
all: ref_xoroshiro ref_mt19937
|
||||
all: ref_xoroshiro ref_mt19937 ref_trivium
|
||||
|
||||
ref_xoroshiro: ref_xoroshiro.c
|
||||
$(CC) -std=c11 -Wall -O2 -o $@ $<
|
||||
|
@ -13,7 +13,10 @@ ref_xoroshiro: ref_xoroshiro.c
|
|||
ref_mt19937: ref_mt19937.cpp
|
||||
$(CXX) -std=c++11 -Wall -O2 -o $@ $<
|
||||
|
||||
ref_trivium: ref_trivium.cpp
|
||||
$(CXX) -std=c++11 -Wall -O2 -o $@ $<
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) ref_xoroshiro ref_mt19937
|
||||
$(RM) ref_xoroshiro ref_mt19937 ref_trivium
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Reference implementation of "Trivium" in C++11.
|
||||
*
|
||||
* Written in 2016 by Joris van Rantwijk <joris@jorisvr.nl>
|
||||
*
|
||||
* To the extent possible under law, the author has dedicated all copyright
|
||||
* and related and neighboring rights to this software to the public domain
|
||||
* worldwide. This software is distributed without any warranty.
|
||||
*
|
||||
* See <http://creativecommons.org/publicdomain/zero/1.0/>
|
||||
*
|
||||
* NOTE: This is a very naive and slow implementation of Trivium,
|
||||
* not suitable for practical use.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <bitset>
|
||||
|
||||
struct trivium_state {
|
||||
std::bitset<93> s1;
|
||||
std::bitset<84> s2;
|
||||
std::bitset<111> s3;
|
||||
};
|
||||
|
||||
/*
|
||||
* Generate one random bit and update state.
|
||||
*
|
||||
* Returns: one random bit, value 0 or 1.
|
||||
*/
|
||||
unsigned int trivium_step(struct trivium_state *state)
|
||||
{
|
||||
unsigned int t1 = state->s1[65] ^ state->s1[92];
|
||||
unsigned int t2 = state->s2[68] ^ state->s2[83];
|
||||
unsigned int t3 = state->s3[65] ^ state->s3[110];
|
||||
|
||||
unsigned int z = t1 ^ t2 ^ t3;
|
||||
|
||||
t1 ^= (state->s1[90] & state->s1[91]) ^ state->s2[77];
|
||||
t2 ^= (state->s2[81] & state->s2[82]) ^ state->s3[86];
|
||||
t3 ^= (state->s3[108] & state->s3[109]) ^ state->s1[68];
|
||||
|
||||
state->s1 <<= 1;
|
||||
state->s1[0] = t3;
|
||||
state->s2 <<= 1;
|
||||
state->s2[0] = t1;
|
||||
state->s3 <<= 1;
|
||||
state->s3[0] = t2;
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize stream state with given key and IV.
|
||||
*
|
||||
* key: pointer to 10 bytes of key data.
|
||||
* iv: pointer to 10 bytes of IV data.
|
||||
*/
|
||||
void trivium_init(struct trivium_state *state,
|
||||
const unsigned char *key,
|
||||
const unsigned char *iv)
|
||||
{
|
||||
state->s1.reset();
|
||||
state->s2.reset();
|
||||
state->s3.reset();
|
||||
|
||||
/*
|
||||
* NOTE: The least significant bit of the first byte of the key
|
||||
* is mapped to s_80. The most significant bit of the last
|
||||
* byte of the key is mapped to s_1.
|
||||
*
|
||||
* This is the same as the phase-3, API-compliant version
|
||||
* of Trivium as published on the ECRYPT website (but different
|
||||
* from the original submitted code.)
|
||||
*/
|
||||
for (unsigned int p = 0; p < 10; p++) {
|
||||
for (unsigned int k = 0; k < 8; k++) {
|
||||
state->s1[79-8*p-k] = ((key[p] >> k) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: The least significant bit of the first byte of the IV
|
||||
* is mapped to s_173. The most significant bit of the last
|
||||
* byte of the key is mapped to s_94.
|
||||
*/
|
||||
for (unsigned int p = 0; p < 10; p++) {
|
||||
for (unsigned int k = 0; k < 8; k++) {
|
||||
state->s2[79-8*p-k] = ((iv[p] >> k) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
state->s3[108] = true;
|
||||
state->s3[109] = true;
|
||||
state->s3[110] = true;
|
||||
|
||||
for (int i = 0; i < 4 * 288; i++) {
|
||||
trivium_step(state);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a small subset of the test vectors from
|
||||
* the ECRYPT stream cipher project.
|
||||
*/
|
||||
static const struct testvec {
|
||||
unsigned char key[10];
|
||||
unsigned char iv[10];
|
||||
} testvecs[5] = {
|
||||
{ { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ { 0x00, 0x53, 0xA6, 0xF9, 0x4C, 0x9F, 0xF2, 0x45, 0x98, 0xEB },
|
||||
{ 0x0D, 0x74, 0xDB, 0x42, 0xA9, 0x10, 0x77, 0xDE, 0x45, 0xAC } },
|
||||
{ { 0x05, 0x58, 0xAB, 0xFE, 0x51, 0xA4, 0xF7, 0x4A, 0x9D, 0xF0 },
|
||||
{ 0x16, 0x7D, 0xE4, 0x4B, 0xB2, 0x19, 0x80, 0xE7, 0x4E, 0xB5 } }
|
||||
};
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const unsigned int nvec = sizeof(testvecs) / sizeof(testvecs[0]);
|
||||
struct trivium_state state;
|
||||
|
||||
for (unsigned int i = 0; i < nvec; i++) {
|
||||
|
||||
printf("key =");
|
||||
for (unsigned int p = 0; p < 10; p++)
|
||||
printf(" %02x", testvecs[i].key[p]);
|
||||
printf("\n");
|
||||
|
||||
printf("iv =");
|
||||
for (unsigned int p = 0; p < 10; p++)
|
||||
printf(" %02x", testvecs[i].iv[p]);
|
||||
printf("\n");
|
||||
|
||||
trivium_init(&state, testvecs[i].key, testvecs[i].iv);
|
||||
|
||||
unsigned int np = 0;
|
||||
for (unsigned int p = 0; p < 131072; p++) {
|
||||
|
||||
// Generate 8 random bits.
|
||||
// Map first-generated bit to least significant bit within byte;
|
||||
// last-generated bit to most significant bit.
|
||||
unsigned int t = 0;
|
||||
for (unsigned int k = 0; k < 8; k++) {
|
||||
t = (t >> 1) | (trivium_step(&state) << 7);
|
||||
}
|
||||
|
||||
// Write parts of the output to screen.
|
||||
if (p == 0 || p == 448 || p == 131008) {
|
||||
np = 64;
|
||||
printf("data+%-6d =", p);
|
||||
} else if (np > 0 && np % 16 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
if (np > 0) {
|
||||
printf(" %02x", t);
|
||||
np--;
|
||||
if (np % 16 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue