Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1025e9b6 authored by Paul Crowley's avatar Paul Crowley Committed by Android (Google) Code Review
Browse files

Merge "Speed up encoding"

parents 47ff2dff 0080bde5
Loading
Loading
Loading
Loading
+21 −14
Original line number Diff line number Diff line
@@ -26,10 +26,6 @@ namespace hardware {
namespace rebootescrow {
namespace hadamard {

static inline void or_bit(std::vector<uint8_t>* input, size_t bit, uint8_t val) {
    (*input)[bit >> 3] |= (val & 1u) << (bit & 7);
}

static inline uint8_t read_bit(const std::vector<uint8_t>& input, size_t bit) {
    return (input[bit >> 3] >> (bit & 7)) & 1u;
}
@@ -60,17 +56,28 @@ std::vector<uint8_t> EncodeKey(const std::vector<uint8_t>& input) {
    CHECK_EQ(input.size(), KEY_SIZE_IN_BYTES);
    std::vector<uint8_t> result(OUTPUT_SIZE_BYTES, 0);
    static_assert(OUTPUT_SIZE_BYTES == 64 * 1024);
    for (size_t i = 0; i < KEY_CODEWORDS; i++) {
        uint16_t word = input[i * 2 + 1] << 8 | input[i * 2];
        for (size_t j = 0; j < ENCODE_LENGTH; j++) {
            uint16_t wi = word & (j + ENCODE_LENGTH);
            // Sum all the bits in the word and check its parity.
            wi ^= wi >> 8u;
            wi ^= wi >> 4u;
            wi ^= wi >> 2u;
            wi ^= wi >> 1u;
            or_bit(&result, (j * KEY_CODEWORDS) + i, wi & 1);
    // Transpose the key so that each row contains one bit from each codeword
    uint16_t wordmatrix[CODEWORD_BITS];
    for (size_t i = 0; i < CODEWORD_BITS; i++) {
        uint16_t word = 0;
        for (size_t j = 0; j < KEY_CODEWORDS; j++) {
            word |= read_bit(input, i + j * CODEWORD_BITS) << j;
        }
        wordmatrix[i] = word;
    }
    // Fill in the encodings in Gray code order for speed.
    uint16_t val = wordmatrix[CODEWORD_BITS - 1];
    size_t ix = 0;
    for (size_t i = 0; i < ENCODE_LENGTH; i++) {
        for (size_t b = 0; b < CODEWORD_BITS; b++) {
            if (i & (1 << b)) {
                ix ^= (1 << b);
                val ^= wordmatrix[b];
                break;
            }
        }
        result[ix * KEY_CODEWORD_BYTES] = val & 0xffu;
        result[ix * KEY_CODEWORD_BYTES + 1] = val >> 8u;
    }
    // Apply the inverse shuffle here; we apply the forward shuffle in decoding.
    uint64_t rng_state = RNG_INV_SEED;
+3 −2
Original line number Diff line number Diff line
@@ -31,9 +31,10 @@ constexpr auto CODEWORD_BYTES = 2u; // uint16_t
constexpr auto CODEWORD_BITS = CODEWORD_BYTES * BYTE_LENGTH;
constexpr uint32_t CODE_K = CODEWORD_BITS - 1;
constexpr uint32_t ENCODE_LENGTH = 1u << CODE_K;
constexpr auto KEY_CODEWORDS = 16u;
constexpr auto KEY_CODEWORD_BYTES = 2u;  // uint16_t (after transpose)
constexpr auto KEY_CODEWORDS = KEY_CODEWORD_BYTES * BYTE_LENGTH;
constexpr auto KEY_SIZE_IN_BYTES = KEY_CODEWORDS * CODEWORD_BYTES;
constexpr auto OUTPUT_SIZE_BYTES = KEY_CODEWORDS * ENCODE_LENGTH / BYTE_LENGTH;
constexpr auto OUTPUT_SIZE_BYTES = ENCODE_LENGTH * KEY_CODEWORD_BYTES;

// Encodes a key that has a size of KEY_SIZE_IN_BYTES. Returns a byte array representation of the
// encoded bitset. So a 32 bytes key will expand to 16*(2^15) bits = 64KiB.