/* ecrypt-sync.h */ /* * Header file for synchronous stream ciphers without authentication * mechanism. * * *** Please only edit parts marked with "[edit]". *** */ #ifndef ECRYPT_SYNC #define ECRYPT_SYNC #include "ecrypt-portable.h" /* ------------------------------------------------------------------------- */ /* Cipher parameters */ /* * The name of your cipher. */ #define ECRYPT_NAME "POMARANCH" /* [edit] */ /* * Specify which key and IV sizes are supported by your cipher. A user * should be able to enumerate the supported sizes by running the * following code: * * for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i) * { * keysize = ECRYPT_KEYSIZE(i); * * ... * } * * All sizes are in bits. */ #define ECRYPT_MAXKEYSIZE 128 /* [edit] */ #define ECRYPT_KEYSIZE(i) (128 + i) /* [edit] */ #define ECRYPT_MAXIVSIZE 112 /* [edit] */ #define ECRYPT_IVSIZE(i) (8 + 8*i) /* [edit] */ /* ------------------------------------------------------------------------- */ /* Data structures */ /* * ECRYPT_ctx is the structure containing the representation of the * internal state of your cipher. */ typedef struct { u16 state[9]; /* states of the registers */ u16 Key[8]; /* 128-bit key in 2-byte words */ u8 IV_size; /* size of the IV in bits */ } ECRYPT_ctx; /* ------------------------------------------------------------------------- */ /* My functions */ void state_upd(u16 *state, const u16 F_mask); u16 KeyMap(const u16 state, const u16 Key); /* My constants */ const u16 pi[9] = {0x90F, 0x36A8, 0x2216, 0x2308, 0x34C4, 0x3198, 0x28B8, 0x370, 0x1CD1}; /* binary expansion of the decimal part of pi */ const u8 S[512] = { 0,0,0,127,64,85,127,54,96,18,42,57,63,83,91,51,112,17,73,38,21,103,92,49,95, 122,105,113,45,104,25,61,120,107,8,112,100,89,19,39,74,102,115,41,110,80,88, 119,47,62,61,15,52,29,56,88,22,16,52,26,12,125,94,93,124,75,53,14,4,77,120,84, 114,2,44,112,73,9,19,19,101,121,115,21,57,5,20,115,55,72,104,14,108,63,59, 116,87,121,31,89,94,80,7,91,90,98,14,33,92,84,44,72,75,82,72,82,90,85,13,48, 70,97,62,34,47,24,46,108,126,91,101,76,26,69,71,119,66,30,38,95,60,97,106,117, 57,82,65,78,86,78,56,82,100,111,4,34,73,65,9,51,50,94,124,87,57,72,10,77,92, 54,2,64,74,78,121,48,27,56,100,18,52,98,7,51,54,84,31,94,93,31,122,12,43,29, 60,70,79,5,108,110,111,76,40,121,3,39,45,68,45,14,113,13,71,117,16,120,46, 63,42,1,22,80,100,76,37,44,105,13,36,2,41,21,109,125,106,71,70,122,88,23,35, 84,48,87,95,12,81,7,87,81,12,30,23,105,54,3,127,1,109,42,114,36,102,39,77,34, 98,79,99,117,123,81,97,86,79,51,83,77,111,33,30,125,48,59,53,33,58,123,28,22, 41,27,96,4,39,19,43,115,103,10,28,16,105,126,50,114,55,32,66,69,17,41,36,37, 96,43,68,66,89,49,25,55,111,11,62,61,107,67,28,37,36,28,69,95,102,3,46,60, 27,17,1,109,96,29,37,112,103,68,60,40,24,62,13,59,92,11,114,24,9,79,26,29,113, 106,3,127,25,32,27,88,42,5,15,123,47,116,46,40,15,25,61,34,6,83,85,2,78,73, 30,68,35,107,103,45,66,26,118,122,119,67,55,44,38,9,20,102,124,32,65,101,83, 10,86,74,98,5,22,110,7,123,56,75,6,63,35,120,58,90,8,97,124,81,23,119,31,49, 85,58,64,126,11,49,104,118,50,80,38,69,18,4,86,8,52,90,6,117,18,89,65,76,20, 74,10,21,118,93,126,23,53,113,35,67,99,110,125,116,108,99,11,33,17,8,106,53, 24,50,43,20,47,59,6,99,104,93,67,71,107,16,40,101,70,118,15,58,75,32,116,109, 91,64,1,0}; // 9-to-7 S-box const u8 F[128] = {0,1,1,1,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0, 1,1,0,0,0,1,0,1,1,0,0,0,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,1,1,0, 1,0,1,0,1,1,0,0,0,0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,0,1,0,0,0,1,1,1, 0,1,1,0,0,0,0,1,1,0,0,1,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,1,0,0,0,0}; const u16 F_mask[2] = {0x15C5, 0x2A3A}; /* location of F-cells on the register and the complement */ const u16 tap_mask[2] = {0x7C0, 0x1E}; /* taps to the S-box */ const u16 fdk_mask = 0x2020, /* feedback from cells 14 and 6 */ out_mask = 0x1000, /* key stream contribution from cell 13 */ mask9 = 0x1; /* initialization feedback from section 9 is from cell 1 */ /* My globals */ u8 wt_mod2[256] = {0}; /* binary weight of all bytes */ /* ------------------------------------------------------------------------- */ /* Mandatory functions */ /* * Key and message independent initialization. This function will be * called once when the program starts (e.g., to build expanded S-box * tables). */ void ECRYPT_init(void); /* * Key setup. It is the user's responsibility to select the values of * keysize and ivsize from the set of supported values specified * above. */ void ECRYPT_keysetup( ECRYPT_ctx* ctx, const u8* key, u32 keysize, /* Key size in bits. */ u32 ivsize); /* IV size in bits. */ /* * IV setup. After having called ECRYPT_keysetup(), the user is * allowed to call ECRYPT_ivsetup() different times in order to * encrypt/decrypt different messages with the same key but different * IV's. */ void ECRYPT_ivsetup( ECRYPT_ctx* ctx, const u8* iv); /* * Encryption/decryption of arbitrary length messages. * * For efficiency reasons, the API provides two types of * encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function * (declared here) encrypts byte strings of arbitrary length, while * the ECRYPT_encrypt_blocks() function (defined later) only accepts * lengths which are multiples of ECRYPT_BLOCKLENGTH. * * The user is allowed to make multiple calls to * ECRYPT_encrypt_blocks() to incrementally encrypt a long message, * but he is NOT allowed to make additional encryption calls once he * has called ECRYPT_encrypt_bytes() (unless he starts a new message * of course). For example, this sequence of calls is acceptable: * * ECRYPT_keysetup(); * * ECRYPT_ivsetup(); * ECRYPT_encrypt_blocks(); * ECRYPT_encrypt_blocks(); * ECRYPT_encrypt_bytes(); * * ECRYPT_ivsetup(); * ECRYPT_encrypt_blocks(); * ECRYPT_encrypt_blocks(); * * ECRYPT_ivsetup(); * ECRYPT_encrypt_bytes(); * * The following sequence is not: * * ECRYPT_keysetup(); * ECRYPT_ivsetup(); * ECRYPT_encrypt_blocks(); * ECRYPT_encrypt_bytes(); * ECRYPT_encrypt_blocks(); */ /* * By default ECRYPT_encrypt_bytes() and ECRYPT_decrypt_bytes() are * defined as macros which redirect the call to a single function * ECRYPT_process_bytes(). If you want to provide separate encryption * and decryption functions, please undef * ECRYPT_HAS_SINGLE_BYTE_FUNCTION. */ #define ECRYPT_HAS_SINGLE_BYTE_FUNCTION /* [edit] */ #ifdef ECRYPT_HAS_SINGLE_BYTE_FUNCTION #define ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, msglen) \ ECRYPT_process_bytes(0, ctx, plaintext, ciphertext, msglen) #define ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, msglen) \ ECRYPT_process_bytes(1, ctx, ciphertext, plaintext, msglen) void ECRYPT_process_bytes( int action, /* 0 = encrypt; 1 = decrypt; */ ECRYPT_ctx* ctx, const u8* input, u8* output, u32 msglen); /* Message length in bytes. */ #else void ECRYPT_encrypt_bytes( ECRYPT_ctx* ctx, const u8* plaintext, u8* ciphertext, u32 msglen); /* Message length in bytes. */ void ECRYPT_decrypt_bytes( ECRYPT_ctx* ctx, const u8* ciphertext, u8* plaintext, u32 msglen); /* Message length in bytes. */ #endif /* ------------------------------------------------------------------------- */ /* Optional features */ /* * For testing purposes it can sometimes be useful to have a function * which immediately generates keystream without having to provide it * with a zero plaintext. If your cipher cannot provide this function * (e.g., because it is not strictly a synchronous cipher), please * reset the ECRYPT_GENERATES_KEYSTREAM flag. */ #define ECRYPT_GENERATES_KEYSTREAM #ifdef ECRYPT_GENERATES_KEYSTREAM void ECRYPT_keystream_bytes( ECRYPT_ctx* ctx, u8* keystream, u32 length); /* Length of keystream in bytes. */ #endif /* ------------------------------------------------------------------------- */ /* Optional optimizations */ /* * By default, the functions in this section are implemented using * calls to functions declared above. However, you might want to * implement them differently for performance reasons. */ /* * All-in-one encryption/decryption of (short) packets. * * The default definitions of these functions can be found in * "ecrypt-sync.c". If you want to implement them differently, please * undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag. */ #define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */ /* * Undef ECRYPT_HAS_SINGLE_PACKET_FUNCTION if you want to provide * separate packet encryption and decryption functions. */ #define ECRYPT_HAS_SINGLE_PACKET_FUNCTION /* [edit] */ #ifdef ECRYPT_HAS_SINGLE_PACKET_FUNCTION #define ECRYPT_encrypt_packet( \ ctx, iv, plaintext, ciphertext, mglen) \ ECRYPT_process_packet(0, \ ctx, iv, plaintext, ciphertext, mglen) #define ECRYPT_decrypt_packet( \ ctx, iv, ciphertext, plaintext, mglen) \ ECRYPT_process_packet(1, \ ctx, iv, ciphertext, plaintext, mglen) void ECRYPT_process_packet( int action, /* 0 = encrypt; 1 = decrypt; */ ECRYPT_ctx* ctx, const u8* iv, const u8* input, u8* output, u32 msglen); #else void ECRYPT_encrypt_packet( ECRYPT_ctx* ctx, const u8* iv, const u8* plaintext, u8* ciphertext, u32 msglen); void ECRYPT_decrypt_packet( ECRYPT_ctx* ctx, const u8* iv, const u8* ciphertext, u8* plaintext, u32 msglen); #endif /* * Encryption/decryption of blocks. * * By default, these functions are defined as macros. If you want to * provide a different implementation, please undef the * ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions * declared below. */ #define ECRYPT_BLOCKLENGTH 4 /* [edit] */ #define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */ #ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS #define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \ (blocks) * ECRYPT_BLOCKLENGTH) #define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \ (blocks) * ECRYPT_BLOCKLENGTH) #ifdef ECRYPT_GENERATES_KEYSTREAM #define ECRYPT_keystream_blocks(ctx, keystream, blocks) \ ECRYPT_keystream_bytes(ctx, keystream, \ (blocks) * ECRYPT_BLOCKLENGTH) #endif #else /* * Undef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION if you want to provide * separate block encryption and decryption functions. */ #define ECRYPT_HAS_SINGLE_BLOCK_FUNCTION /* [edit] */ #ifdef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION #define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ ECRYPT_process_blocks(0, ctx, plaintext, ciphertext, blocks) #define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ ECRYPT_process_blocks(1, ctx, ciphertext, plaintext, blocks) void ECRYPT_process_blocks( int action, /* 0 = encrypt; 1 = decrypt; */ ECRYPT_ctx* ctx, const u8* input, u8* output, u32 blocks); /* Message length in blocks. */ #else void ECRYPT_encrypt_blocks( ECRYPT_ctx* ctx, const u8* plaintext, u8* ciphertext, u32 blocks); /* Message length in blocks. */ void ECRYPT_decrypt_blocks( ECRYPT_ctx* ctx, const u8* ciphertext, u8* plaintext, u32 blocks); /* Message length in blocks. */ #endif #ifdef ECRYPT_GENERATES_KEYSTREAM void ECRYPT_keystream_blocks( ECRYPT_ctx* ctx, u8* keystream, u32 blocks); /* Keystream length in blocks. */ #endif #endif /* * If your cipher can be implemented in different ways, you can use * the ECRYPT_VARIANT parameter to allow the user to choose between * them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please * only use this possibility if you really think it could make a * significant difference and keep the number of variants * (ECRYPT_MAXVARIANT) as small as possible (definitely not more than * 10). Note also that all variants should have exactly the same * external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.). */ #define ECRYPT_MAXVARIANT 1 /* [edit] */ #ifndef ECRYPT_VARIANT #define ECRYPT_VARIANT 1 #endif #if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT) #error this variant does not exist #endif /* ------------------------------------------------------------------------- */ #endif