void CCM_Mode::inc(secure_vector<uint8_t>& C) { for(size_t i = 0; i != C.size(); ++i) if(++C[C.size()-i-1]) break; }
std::unique_ptr<Comb4P> copy(new Comb4P); copy->m_hash1 = m_hash1->copy_state(); copy->m_hash2 = m_hash2->copy_state(); // work around GCC 4.8 bug return std::unique_ptr<HashFunction>(copy.release()); } void Comb4P::add_data(const uint8_t input[], size_t length) { m_hash1->update(input, length); m_hash2->update(input, length); } void Comb4P::final_result(uint8_t out[]) { secure_vector<uint8_t> h1 = m_hash1->final(); secure_vector<uint8_t> h2 = m_hash2->final(); // First round xor_buf(h1.data(), h2.data(), std::min(h1.size(), h2.size())); // Second round comb4p_round(h2, h1, 1, *m_hash1, *m_hash2); // Third round comb4p_round(h1, h2, 2, *m_hash1, *m_hash2); copy_mem(out , h1.data(), h1.size()); copy_mem(out + h1.size(), h2.data(), h2.size()); // Prep for processing next message, if any
/* * Decode a message */ secure_vector<byte> EME::decode(const secure_vector<byte>& msg, size_t key_bits) const { return unpad(msg.data(), msg.size(), key_bits); }
/* * Perform CMAC's multiplication in GF(2^n) */ secure_vector<uint8_t> CMAC::poly_double(const secure_vector<uint8_t>& in) { secure_vector<uint8_t> out(in.size()); poly_double_n(out.data(), in.data(), out.size()); return out; }
/* * Encode a message */ secure_vector<byte> EME::encode(const secure_vector<byte>& msg, size_t key_bits, RandomNumberGenerator& rng) const { return pad(msg.data(), msg.size(), key_bits, rng); }
void SHA_160::sha1_compress_x86(secure_vector<uint32_t>& digest, const uint8_t input[], size_t blocks) { const __m128i MASK = _mm_set_epi64x(0x0001020304050607ULL, 0x08090a0b0c0d0e0fULL); const __m128i* input_mm = reinterpret_cast<const __m128i*>(input); uint32_t* state = digest.data(); // Load initial values __m128i ABCD = _mm_loadu_si128(reinterpret_cast<__m128i*>(state)); __m128i E0 = _mm_set_epi32(state[4], 0, 0, 0); ABCD = _mm_shuffle_epi32(ABCD, 0x1B); while (blocks) { // Save current hash const __m128i ABCD_SAVE = ABCD; const __m128i E0_SAVE = E0; __m128i MSG0, MSG1, MSG2, MSG3; __m128i E1; // Rounds 0-3 MSG0 = _mm_loadu_si128(input_mm+0); MSG0 = _mm_shuffle_epi8(MSG0, MASK); E0 = _mm_add_epi32(E0, MSG0); E1 = ABCD; ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); // Rounds 4-7 MSG1 = _mm_loadu_si128(input_mm+1); MSG1 = _mm_shuffle_epi8(MSG1, MASK); E1 = _mm_sha1nexte_epu32(E1, MSG1); E0 = ABCD; ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0); MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); // Rounds 8-11 MSG2 = _mm_loadu_si128(input_mm+2); MSG2 = _mm_shuffle_epi8(MSG2, MASK); E0 = _mm_sha1nexte_epu32(E0, MSG2); E1 = ABCD; ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); MSG0 = _mm_xor_si128(MSG0, MSG2); // Rounds 12-15 MSG3 = _mm_loadu_si128(input_mm+3); MSG3 = _mm_shuffle_epi8(MSG3, MASK); E1 = _mm_sha1nexte_epu32(E1, MSG3); E0 = ABCD; MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0); MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); MSG1 = _mm_xor_si128(MSG1, MSG3); // Rounds 16-19 E0 = _mm_sha1nexte_epu32(E0, MSG0); E1 = ABCD; MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0); MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); MSG2 = _mm_xor_si128(MSG2, MSG0); // Rounds 20-23 E1 = _mm_sha1nexte_epu32(E1, MSG1); E0 = ABCD; MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); MSG3 = _mm_xor_si128(MSG3, MSG1); // Rounds 24-27 E0 = _mm_sha1nexte_epu32(E0, MSG2); E1 = ABCD; MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1); MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); MSG0 = _mm_xor_si128(MSG0, MSG2); // Rounds 28-31 E1 = _mm_sha1nexte_epu32(E1, MSG3); E0 = ABCD; MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); MSG1 = _mm_xor_si128(MSG1, MSG3); // Rounds 32-35 E0 = _mm_sha1nexte_epu32(E0, MSG0); E1 = ABCD; MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1); MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); MSG2 = _mm_xor_si128(MSG2, MSG0); // Rounds 36-39 E1 = _mm_sha1nexte_epu32(E1, MSG1); E0 = ABCD; MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1); MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); MSG3 = _mm_xor_si128(MSG3, MSG1); // Rounds 40-43 E0 = _mm_sha1nexte_epu32(E0, MSG2); E1 = ABCD; MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); MSG0 = _mm_xor_si128(MSG0, MSG2); // Rounds 44-47 E1 = _mm_sha1nexte_epu32(E1, MSG3); E0 = ABCD; MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2); MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); MSG1 = _mm_xor_si128(MSG1, MSG3); // Rounds 48-51 E0 = _mm_sha1nexte_epu32(E0, MSG0); E1 = ABCD; MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); MSG2 = _mm_xor_si128(MSG2, MSG0); // Rounds 52-55 E1 = _mm_sha1nexte_epu32(E1, MSG1); E0 = ABCD; MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2); MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1); MSG3 = _mm_xor_si128(MSG3, MSG1); // Rounds 56-59 E0 = _mm_sha1nexte_epu32(E0, MSG2); E1 = ABCD; MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2); MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2); MSG0 = _mm_xor_si128(MSG0, MSG2); // Rounds 60-63 E1 = _mm_sha1nexte_epu32(E1, MSG3); E0 = ABCD; MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3); ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3); MSG1 = _mm_xor_si128(MSG1, MSG3); // Rounds 64-67 E0 = _mm_sha1nexte_epu32(E0, MSG0); E1 = ABCD; MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0); ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3); MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0); MSG2 = _mm_xor_si128(MSG2, MSG0); // Rounds 68-71 E1 = _mm_sha1nexte_epu32(E1, MSG1); E0 = ABCD; MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1); ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); MSG3 = _mm_xor_si128(MSG3, MSG1); // Rounds 72-75 E0 = _mm_sha1nexte_epu32(E0, MSG2); E1 = ABCD; MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2); ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3); // Rounds 76-79 E1 = _mm_sha1nexte_epu32(E1, MSG3); E0 = ABCD; ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3); // Add values back to state E0 = _mm_sha1nexte_epu32(E0, E0_SAVE); ABCD = _mm_add_epi32(ABCD, ABCD_SAVE); input_mm += 4; blocks--; } // Save state ABCD = _mm_shuffle_epi32(ABCD, 0x1B); _mm_storeu_si128(reinterpret_cast<__m128i*>(state), ABCD); state[4] = _mm_extract_epi32(E0, 3); }
/* * Insert a single key and value */ void Data_Store::add(const std::string& key, const secure_vector<byte>& val) { add(key, hex_encode(val.data(), val.size())); }
/** * @p p_err_pos_len must point to the available length of @p error_pos on input, the * function will set it to the actual number of errors returned in the @p error_pos * array */ secure_vector<uint8_t> mceliece_decrypt( secure_vector<gf2m> & error_pos, const uint8_t *ciphertext, uint32_t ciphertext_len, const McEliece_PrivateKey & key) { uint32_t dimension = key.get_dimension(); uint32_t codimension = key.get_codimension(); uint32_t t = key.get_goppa_polyn().get_degree(); polyn_gf2m syndrome_polyn(key.get_goppa_polyn().get_sp_field()); // init as zero polyn const unsigned unused_pt_bits = dimension % 8; const uint8_t unused_pt_bits_mask = (1 << unused_pt_bits) - 1; if(ciphertext_len != (key.get_code_length()+7)/8) { throw Invalid_Argument("wrong size of McEliece ciphertext"); } uint32_t cleartext_len = (key.get_message_word_bit_length()+7)/8; if(cleartext_len != bit_size_to_byte_size(dimension)) { throw Invalid_Argument("mce-decryption: wrong length of cleartext buffer"); } secure_vector<uint32_t> syndrome_vec(bit_size_to_32bit_size(codimension)); matrix_arr_mul(key.get_H_coeffs(), key.get_code_length(), bit_size_to_32bit_size(codimension), ciphertext, syndrome_vec.data(), syndrome_vec.size()); secure_vector<uint8_t> syndrome_byte_vec(bit_size_to_byte_size(codimension)); uint32_t syndrome_byte_vec_size = syndrome_byte_vec.size(); for(uint32_t i = 0; i < syndrome_byte_vec_size; i++) { syndrome_byte_vec[i] = syndrome_vec[i/4] >> (8* (i % 4)); } syndrome_polyn = polyn_gf2m(t-1, syndrome_byte_vec.data(), bit_size_to_byte_size(codimension), key.get_goppa_polyn().get_sp_field()); syndrome_polyn.get_degree(); error_pos = goppa_decode(syndrome_polyn, key.get_goppa_polyn(), key.get_sqrtmod(), key.get_Linv()); uint32_t nb_err = error_pos.size(); secure_vector<uint8_t> cleartext(cleartext_len); copy_mem(cleartext.data(), ciphertext, cleartext_len); for(uint32_t i = 0; i < nb_err; i++) { gf2m current = error_pos[i]; if(current >= cleartext_len * 8) { // an invalid position, this shouldn't happen continue; } cleartext[current / 8] ^= (1 << (current % 8)); } if(unused_pt_bits) { cleartext[cleartext_len - 1] &= unused_pt_bits_mask; } return cleartext; }
/* * Process a full message at once */ void Pipe::process_msg(const secure_vector<uint8_t>& input) { process_msg(input.data(), input.size()); }