/*
*   Zcipher. Test and Usage Sample
*   Written by Ilya O. Levin, http://www.literatecode.com
*/
#pragma warning(push, 1)
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#pragma warning(pop)

#define uint32_t unsigned long

#define TEST_LOOPS 13107200

void cvsched(uint32_t *);
void encr(uint32_t *);
void decr(uint32_t *);

uint32_t k[6] = {0};

/* ------------------------------------------------------------------------- */
int main (void)
{
    clock_t t;
    double dt;
    int i;

    printf("Zcipher Tests\n\n");

    printf("* Encrypting %3d Mb - ", (TEST_LOOPS * sizeof(k[0])*2)/1048576);
    t = clock();
    cvsched(k);
    for (i = 0, dt = 0; i < (TEST_LOOPS); i++ ) encr(k);
    dt = (double)(clock() - t) / CLOCKS_PER_SEC;
    printf("%2.3f sec [%08x]\r\n", dt, (k[0] ^ k[1]));

    printf("  + key streaming -   ");
    t = clock();
    for (i = 0, dt = 0; i < (TEST_LOOPS); i++ ) cvsched(k), encr(k);
    dt = (double)(clock() - t) / CLOCKS_PER_SEC;
    printf("%2.3f sec [%08x]\r\n", dt, (k[0] ^ k[1]));


    printf("\nKey Stream Generator:\n");

    k[2] = 0x11111111; k[3] = 0x22222222; k[4] = 0x33333333; k[5] = 0x44444444;

    printf("#0: %08x %08x %08x %08x\n", k[2], k[3], k[4], k[5]);
    cvsched(k);    
    printf("#1: %08x %08x %08x %08x - %s\n", k[2], k[3], k[4], k[5],
            ((k[2]==0x7a7db236) && (k[3]==0x8d69797c) && 
             (k[4]==0xea87711e) && (k[5]==0xe183da90)) ? "PASSED" : "FAILED"
            );
    cvsched(k);    
    printf("#2: %08x %08x %08x %08x - %s\n", k[2], k[3], k[4], k[5],
            ((k[2]==0xbd03c8dc) && (k[3]==0x98e5347f) && 
             (k[4]==0x8cfb9730) && (k[5]==0x45dc0cc9)) ? "PASSED" : "FAILED"
            );

    cvsched(k);    
    printf("#3: %08x %08x %08x %08x - %s\n", k[2], k[3], k[4], k[5],
            ((k[2]==0x96fbbf1d) && (k[3]==0x2f7d4382) && 
             (k[4]==0xc3fabc58) && (k[5]==0x42f34f4d)) ? "PASSED" : "FAILED"
            );


    printf("\nCodebook:\n");

    k[2] = 0x11111111; k[3] = 0x22222222; k[4] = 0x33333333; k[5] = 0x44444444;

    k[0] = 0x12345678; k[1] = 0x9abcdef0; 
    printf("* %08x %08x -> ", k[0], k[1]);
    encr(k); printf("%08x %08x -> ", k[0], k[1]);
    decr(k); printf("%08x %08x\n", k[0], k[1]);

    k[0] = k[1] = 0; 
    printf("* %08x %08x -> ", k[0], k[1]);
    encr(k); printf("%08x %08x -> ", k[0], k[1]);
    decr(k); printf("%08x %08x\n", k[0], k[1]);


    k[0] = k[1] = 0xFFFFFFFF; 
    printf("* %08x %08x -> ", k[0], k[1]);
    encr(k); printf("%08x %08x -> ", k[0], k[1]);
    decr(k); printf("%08x %08x\n", k[0], k[1]);


    return 0;
} /* main */
