av_cold int av_cast5_init(AVCAST5* cs, const uint8_t *key, int key_bits) { uint8_t newKey[16]; int i; uint32_t p[4],q[4]; if (key_bits%8||key_bits<40||key_bits>128) return -1; memset(newKey,0,sizeof(newKey)); memcpy(newKey,key,key_bits>>3); cs->rounds = key_bits<=80 ? 12:16; for (i=0;i<4;i++) q[i]=AV_RB32(newKey+(4*i)); generate_round_keys(cs->rounds,cs->Km,q,p); generate_round_keys(cs->rounds,cs->Kr,q,p); for (i=0;i<cs->rounds;i++) cs->Kr[i]=cs->Kr[i]&0x1f; return 0; }
// given plain text and key, return cipher text std::bitset<BLOCK_SIZE> encrypt(const std::bitset<BLOCK_SIZE>& input_text, const std::bitset<INPUT_KEY_SIZE>& input_key, bool encrypt) { std::bitset<BLOCK_SIZE> cipher_block; // generate initial key std::bitset<KEY_SIZE> initial_key = generate_initial_key(input_key); // generate round keys std::vector<std::bitset<ROUND_KEY_SIZE> > round_keys = generate_round_keys(initial_key); // split input text into two blocks of 32b std::bitset<BLOCK_SIZE/2> lower; // use lower to represent bits [0,BLOCK_SIZE/2), and std::bitset<BLOCK_SIZE/2> upper; // user upper to represent bits [BLOCK_SIZE/2,BLOCK_SIZE) int mid = input_text.size() / 2; for (int i = 0; i < input_text.size(); i++) if (i < mid) lower.set(i, input_text.test(i)); else upper.set(i % mid, input_text.test(i)); std::bitset<BLOCK_SIZE/2> temp; // temporarily hold lower, so that upper can be used in XOR // if encryption if (encrypt) { for (int i = 0; i < ROUND_NUM; ++i) { //std::cout << "ROUND " << i << "----------------------------------------" << std::endl; //std::cout << "Using key " << i << ":\t\t" << round_keys[i] << std::endl; temp = copy_bit_pattern(lower); // hold r_i-1 in temp lower = perform_round(lower, round_keys[i]); lower ^= upper; // r_i = f(r_i-1,key) xor l_i-1 upper = copy_bit_pattern(temp); // l_i = r_i-1 std::cout << "ROUND " << i << " ENDED" << "----------------------------------" << std::endl; } } else { // if decryption for (int i = ROUND_NUM -1; i >= 0; --i) { //std::cout << "ROUND " << i << "----------------------------------------" << std::endl; //std::cout << "Using key " << i << ":\t\t" << round_keys[i] << std::endl; temp = copy_bit_pattern(lower); // hold r_i-1 in temp lower = perform_round(lower, round_keys[i]); lower ^= upper; // r_i = f(r_i-1,key) xor l_i-1 upper = copy_bit_pattern(temp); // l_i = r_i-1 //std::cout << "ROUND " << i << " ENDED" << "----------------------------------" << std::endl; } } // perform final swap for (int i = 0; i < cipher_block.size(); ++i) { if (i < mid) cipher_block.set(i, upper.test(i)); else cipher_block.set(i, lower.test(i % mid)); } return cipher_block; }
void generate_round_keys_time() { //100000 runs of round_keys to generate mean for this function uint32_t key[80] = {0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff}; clock_t start, end, result = 0; mach_timebase_info_data_t info; mach_timebase_info(&info); for(int run = 0; run < 100000; run++) { uint32_t round_keys[32][64] = {{ 0 }}; start = mach_absolute_time(); generate_round_keys(key, round_keys); end = mach_absolute_time(); result += (end - start); for(int bit = 0; bit < 80; bit++) { key[bit] = 0xffffffff; } } printf("generate_round_keys time: %lu\n", (result / 100000) * info.numer / info.denom); }
int main(int argc, char *argv[]) { int nonce_flag = 0; int nonce; int i; int length = atoi(argv[1]); char* key_string = argv[3]; if (argc > 4) { nonce = atoi(argv[4]); nonce_flag = 1; } int num_blocks = ceil( (double)length / 8.0); int pad = length - (length/8)*8; byte key1 = convert_char_to_hex(key_string[0]); byte key2 = convert_char_to_hex(key_string[1]); byte key = (key1 << 4) + key2; byte* keys = generate_round_keys(key); printf("Pad:\t\t%d\n", pad); printf("#Blocks:\t%d\n", num_blocks); printf("Key:\t\t0x%02X\n", key); byte IV; if(nonce_flag) { IV = generate_IV_from_nonce(nonce, keys); printf("Nonce:\t\t%d\n", nonce); } else IV = 0xA5; printf("IV:\t\t0x%02X\n", IV); byte* CTR = (byte*)malloc(num_blocks*sizeof(byte)); for(i = 0; i < num_blocks; i++) { CTR[i] = generate_IV_from_nonce( IV++, keys); //printf("CTR%d:\t\t0x%02X\n", i,CTR[i]); } char** bitstream = (char**)malloc(num_blocks*sizeof(char*)); for(i = 0; i < num_blocks; i++) { byte out = encrypt_block(CTR[i], keys); bitstream[i] = byte_to_bit_string(out); } if(pad > 0) bitstream[num_blocks-1][8-pad] = '\0'; char * outfile = argv[2]; FILE * ofp = fopen(outfile, "w"); if(ofp == NULL) { printf("Cannot open output file. Exiting...\n"); exit(1); } else { for(i = 0; i < num_blocks; i++) fprintf(ofp, "%s\n", bitstream[i]); } fprintf(ofp,"\n"); fclose(ofp); }