/* setup needed for both encrypt & decrypt */ static void setup(u64 mlen, u64 adlen, const byte *npub, const byte *k) { assert( k != NULL) ; assert( npub != NULL) ; /* run ChaCha key schedule and then ChaCha */ chacha_keysetup(chacha_ctx, (byte *) k, 256, 64) ; chacha_ivsetup(chacha_ctx, npub) ; chacha_round() ; /* set up H, I & finalblock for authentication */ chacha_copy( H, 1 ) ; memcpy( I, H, AUTH_BYTES ) ; store64((byte *) finalblock,8 * adlen); store64(((byte *) finalblock) + 8,8 * mlen); /* random init for counter */ chacha_copy( counter, 1 ) ; iter_count = 0 ; /* use ChaCha to generate aes round keys */ chacha_copy( aes_rk, AES_RKEYS ) ; #ifdef TESTING printf( "setup: called for %lld text and %lld ad\n", mlen, adlen ) ; printf( "setup: round keys start with %08x %08x\n", aes_rk[0], aes_rk[1] ) ; #endif }
static inline void chacha_rounds(uint32_t x[16]) { chacha_round(x, 0, 4, 8,12); chacha_round(x, 1, 5, 9,13); chacha_round(x, 2, 6,10,14); chacha_round(x, 3, 7,11,15); chacha_round(x, 0, 5,10,15); chacha_round(x, 1, 6,11,12); chacha_round(x, 2, 7, 8,13); chacha_round(x, 3, 4, 9,14); }
/* use 128-bit chunks from ChaCha */ static void chacha_copy( u32 *dest, u32 blocks ) { u32 i ; assert( dest != NULL ) ; assert( chacha_got <= 4 ) ; for( i = blocks ; i > 0 ; i-- ) { if( chacha_got == 0 ) { chacha_round() ; } memcpy( dest, chacha_next, AES_BYTES ) ; dest += AES_WORDS ; chacha_next += AES_WORDS ; chacha_got-- ; } }