fn compress_to_bytes(code: &[u8]) -> Result<Vec<u8>, FailedToCompressBytecodeError> {
    validate_bytecode(code)?;

    // Statistic is a hash map of values (number of occurrences, first occurrence position),
    // this is needed to ensure that the determinism during sorting of the statistic, i.e.
    // each element will have unique first occurrence position
    let mut statistic: HashMap<u64, (usize, usize)> = HashMap::new();
    let mut dictionary: HashMap<u64, u16> = HashMap::new();
    let mut encoded_data: Vec<u8> = Vec::new();

    // Split original bytecode into 8-byte chunks.
    for (position, chunk_bytes) in code.chunks(8).enumerate() {
        // It is safe to unwrap here, because each chunk is exactly 8 bytes, since
        // valid bytecodes are divisible by 8.
        let chunk = u64::from_be_bytes(chunk_bytes.try_into().unwrap());

        // Count the number of occurrences of each chunk.
        statistic.entry(chunk).or_insert((0, position)).0 += 1;
    }

    let mut statistic_sorted_by_value: Vec<_> = statistic.into_iter().collect::<Vec<_>>();
    statistic_sorted_by_value.sort_by_key(|x| x.1);

    // The dictionary size is limited by 2^16 - 1,
    if statistic_sorted_by_value.len() > (u16::MAX as usize) {
        return Err(FailedToCompressBytecodeError::DictionaryOverflow);
    }

    // Fill the dictionary with the most popular chunks.
    // The most popular chunks will be encoded with the smallest indexes, so that
    // the 255 most popular chunks will be encoded with one zero byte.
    // And the encoded data will be filled with more zeros, so
    // the calldata that will be sent to L1 will be cheaper.
    for (chunk, _) in statistic_sorted_by_value.iter().rev() {
        dictionary.insert(*chunk, dictionary.len() as u16);
    }

    for chunk_bytes in code.chunks(8) {
        // It is safe to unwrap here, because each chunk is exactly 8 bytes, since
        // valid bytecodes are divisible by 8.
        let chunk = u64::from_be_bytes(chunk_bytes.try_into().unwrap());

        // Add the index of the chunk to the encoded data.
        encoded_data.extend(dictionary.get(&chunk).unwrap().to_be_bytes());
    }

    // Prepare the raw compressed bytecode in the following format:
    // - 2 bytes: the length of the dictionary (N)
    // - N bytes: packed dictionary bytes
    // - remaining bytes: packed encoded data bytes

    let mut compressed: Vec<u8> = Vec::new();
    compressed.extend((dictionary.len() as u16).to_be_bytes());

    let mut entries: Vec<_> = dictionary.into_iter().map(|(k, v)| (v, k)).collect();
    entries.sort_unstable();
    for (_, chunk) in entries {
        compressed.extend(chunk.to_be_bytes());
    }
    compressed.extend(encoded_data);
    Ok(compressed)
}
Implements, a simple compression algorithm for the bytecode.
core/lib/multivm/src/utils/bytecode.rs