int decrypt(WORDSIZE* data, WORDSIZE* decryption_iv, WORDSIZE* keym, WORDSIZE* extra_data, WORDSIZE* tag, unsigned long data_size, unsigned long extra_data_size){ REGISTER a, b, c, d, t; unsigned long index; load_register(d, decryption_iv, 4); load_register(c, decryption_iv, 0); load_register(t, keym, 4); d ^= t; load_register(t, keym, 0); c ^= t; unsigned long block_number = data_size / 8; while (block_number-- > 0){ load_register(a, data, (block_number * 8)); load_register(b, data, (block_number * 8) + 4); inverse_permutation(a, b, c, d); store_register(a, data, (block_number * 8)); store_register(b, data, (block_number * 8) + 4);} WORDSIZE _tag[8], keyr[8]; store_register(c, keyr, 0); store_register(d, keyr, 4); keyed_hash_function(keyr, extra_data, extra_data_size, _tag); REGISTER tag_a, tag_b, _tag_a, _tag_b, valid; load_register(tag_a, tag, 0); load_register(tag_b, tag, 4); load_register(_tag_a, _tag, 0); load_register(_tag_b, tag, 4); valid[0] = 0xFFFFFFFF; valid[1] = 0xFFFFFFFF; valid[2] = 0xFFFFFFFF; valid[3] = 0xFFFFFFFF; valid = (_tag_a ^ tag_a ^ 0xFFFFFFFF) & valid; valid = (_tag_b ^ tag_b ^ 0xFFFFFFFF) & valid; return valid[0] & valid[1] & valid[2] & valid[3];}
uint64_t rank(uint32_t n, uint32_t k, uint32_t* p) { uint32_t* i = inverse_permutation(n, p); uint64_t r = rank_inner(n, k, p, i); free(i); return r; }
/*TODO: inline troubles*/ void perm_ident_rev(interval * inter, size_t * perm_buffer, size_t degree) { if (inter->orientation == 1) memcpy(perm_buffer, inter->lab->sigma, degree * sizeof(size_t)); else inverse_permutation(inter->lab->sigma, perm_buffer, degree); }
/*TODO: inline troubles*/ void perm_name(interval * inter, size_t * perm_buffer, size_t degree) { if (inter->orientation == 1) permutation(0, perm_buffer, degree); //return identity else inverse_permutation(inter->lab->sigma, perm_buffer, degree); }